#include "Core.h" namespace Upp { const Nuller Null; #define LTIMING(x) // RTIMING(x) ValueTypeError::ValueTypeError(const String& text, const Value& src, int target) : Exc(text), src(src), target(target) {} hash_t Value::GetOtherHashValue() const { if(IsNull()) return 0; byte st = data.GetSt(); if(st == REF) return ptr()->GetHashValue(); return svo[st]->GetHashValue(&data); } void Value::RefRelease() { ASSERT(IsRef()); // Check that svo type is not registered as Ref ptr()->Release(); } void Value::RefRetain() { ptr()->Retain(); } Value& Value::operator=(const Value& v) { if(this == &v) return *this; Value h = v; // Make copy a 'v' can be reference to ValueMap/Array contained element FreeRef(); // e.g. json = json["foo"] data = h.data; if(IsRef()) ptr()->Retain(); return *this; } void Value::SetLarge(const Value& v) { if(v.IsRef()) { data.SetSmall(v.data); RefRetain(); } else data.LSet(v.data); } dword Value::GetType() const { if(IsString()) return STRING_V; byte st = data.GetSt(); return st == REF ? GetRefType() : st == VOIDV ? VOID_V : st; } bool Value::IsNull() const { if(IsString()) return data.GetCount() == 0; int st = data.GetSt(); if(st == VOIDV) return true; if(st == REF) return ptr()->IsNull(); return svo[st]->IsNull(&data); } bool Value::IsPolyEqual(const Value& v) const { int st = data.GetSpecial(); if(st == REF) return ptr()->IsPolyEqual(v); if(svo[st] && svo[st]->IsPolyEqual(&data, v)) return true; return IsNull() && v.IsNull(); } bool Value::operator==(const Value& v) const { if(IsString() && v.IsString()) return data == v.data; if(GetType() != v.GetType()) { if(IsPolyEqual(v) || v.IsPolyEqual(*this)) return true; } else { int st = data.GetSpecial(); if(st == REF) { if(ptr()->IsEqual(v.ptr())) return true; } else if(st != VOIDV) { if(svo[st]->IsEqual(&data, &v.data)) return true; } } return IsNull() && v.IsNull(); } int Value::PolyCompare(const Value& v) const { int st = data.GetSpecial(); if(st == REF) return ptr()->PolyCompare(v); if(st != VOIDV) return svo[st]->PolyCompare(&data, v); return 0; } int Value::Compare2(const Value& v) const { if(IsString() && v.IsString()) return SgnCompare(data, v.data); dword stw = data.GetStW(); if(stw == v.data.GetStW()) { if(stw == String::StW(INT64_V)) return SgnCompare(GetSmallRaw(), v.GetSmallRaw()); if(stw == String::StW(DATE_V)) return SgnCompare(GetSmallRaw(), v.GetSmallRaw()); if(stw == String::StW(TIME_V)) return SgnCompare(GetSmallRaw