diff --git a/uppsrc/Core/Color.cpp b/uppsrc/Core/Color.cpp index 16aaf91fd..2d0fc06cd 100644 --- a/uppsrc/Core/Color.cpp +++ b/uppsrc/Core/Color.cpp @@ -90,24 +90,42 @@ Color::Color(RGBA rgba) void Color::Jsonize(JsonIO& jio) { - int r = GetR(); - int g = GetG(); - int b = GetB(); + int r, g, b; + if(IsNullInstance()) { + r = g = b = Null; + } + else { + r = GetR(); + g = GetG(); + b = GetB(); + } jio("red", r)("green", g)("blue", b); - *this = Color(r, g, b); + if(IsNull(r)) + *this = Null; + else + *this = Color(r, g, b); } void Color::Xmlize(XmlIO& xio) { - int r = GetR(); - int g = GetG(); - int b = GetB(); + int r, g, b; + if(IsNullInstance()) { + r = g = b = Null; + } + else { + r = GetR(); + g = GetG(); + b = GetB(); + } xio .Attr("red", r) .Attr("green", g) .Attr("blue", b) ; - *this = Color(r, g, b); + if(IsNull(r)) + *this = Null; + else + *this = Color(r, g, b); } RGBA operator*(int alpha, Color c) diff --git a/uppsrc/Core/JSON.cpp b/uppsrc/Core/JSON.cpp index 6923113a2..79697ba93 100644 --- a/uppsrc/Core/JSON.cpp +++ b/uppsrc/Core/JSON.cpp @@ -1,307 +1,310 @@ -#include "Core.h" - -NAMESPACE_UPP - -Value ParseJSON(CParser& p) -{ - p.UnicodeEscape(); - if(p.IsNumber()) - return p.ReadDouble(); - if(p.IsString()) - return p.ReadString(); - if(p.Id("null")) - return Null; - if(p.Id("true")) - return true; - if(p.Id("false")) - return false; - if(p.Char('{')) { - ValueMap m; - if(!p.IsChar('}')) - do { - String key = p.ReadString(); - p.PassChar(':'); - m.Add(key, ParseJSON(p)); - } - while(p.Char(',')); - p.PassChar('}'); - return m; - } - if(p.Char('[')) { - ValueArray va; - if(!p.IsChar(']')) - do - va.Add(ParseJSON(p)); - while(p.Char(',')); - p.PassChar(']'); - return va; - } - p.ThrowError("Unrecognized JSON element"); - return Null; -} - -Value ParseJSON(const char *s) -{ - try { - CParser p(s); - return ParseJSON(p); - } - catch(CParser::Error) { - return ErrorValue(); - } -} - -String AsJSON(const Value& v, const String& sep, bool pretty) -{ - String r; - if(v.GetType() == VALUEMAP_V) { - r << "{"; - String sep1; - if(pretty) { - r << "\r\n"; - sep1 = sep + '\t'; - } - ValueMap m = v; - ValueArray va = m.GetValues(); - for(int i = 0; i < m.GetCount(); i++) { - if(i) { - r << ","; - if(pretty) - r << "\r\n"; - } - if(pretty) - r << sep1; - r << AsCString((String)m.GetKeys()[i]) << (pretty ? ": " : ":") - << AsJSON(va[i], sep1, pretty); - } - if(pretty) - r << "\r\n" << sep; - r << "}"; - return r; - } - if(v.GetType() == VALUEARRAY_V) { - r << "["; - String sep1; - if(pretty) { - r << "\r\n"; - sep1 = sep + '\t'; - } - ValueArray va = v; - for(int i = 0; i < va.GetCount(); i++) { - if(i) { - r << ","; - if(pretty) - r << "\r\n"; - } - if(pretty) - r << sep1; - r << AsJSON(va[i], sep1, pretty); - } - if(pretty) - r << "\r\n" << sep; - r << "]"; - return r; - } - if(IsNumber(v) && IsNull(v)) - return "null"; - if(v.GetType() == INT_V) - return Format("%d", (int)v); - if(v.GetType() == BOOL_V) - return (bool)v ? "true" : "false"; - if(IsNumber(v)) - return Format("%.16g", (double)v); - if(IsString(v)) - return AsCString((String)v); - if(IsNull(v)) - return "null"; - NEVER(); - return "null"; -} - -String AsJSON(const Value& v, bool pretty) -{ - return AsJSON(v, String(), pretty); -} - -template<> void Jsonize(JsonIO& io, double& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsNull(v)) { - var = Null; - return; - } - if(IsNumber(v)) { - var = io.Get(); - return; - } - if(IsString(v)) { - double h = ScanDouble((String)v); - if(!IsNull(h)) { - var = h; - return; - } - } - throw JsonizeError("number expected"); - } - else - io.Set(var); -} - -template<> void Jsonize(JsonIO& io, int& var) -{ - double v = IntDbl(var); - Jsonize(io, v); - if(io.IsLoading()) - if(IsNull(v)) - var = Null; - else - if(v >= INT_MIN && v <= INT_MAX) - var = (int)v; - else - throw JsonizeError("number is not integer"); -} - -template<> void Jsonize(JsonIO& io, bool& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsNumber(v) && !IsNull(v)) - var = (bool)v; - else - throw JsonizeError("boolean expected"); - } - else - io.Set(var); -} - -template<> void Jsonize(JsonIO& io, int64& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsNull(v)) { - var = Null; - return; - } - if(v.Is() || v.Is()) { - var = v; - return; - } - if(IsNumber(v)) { - double d = v; - if(d >= INT64_MIN && d <= INT64_MAX) { - var = (int64)d; - return; - } - } - else - if(IsString(v)) { - int64 h = ScanInt64((String)v); - if(!IsNull(h)) { - var = h; - return; - } - } - throw JsonizeError("invalid int64 value"); - } - else - if(IsNull(var)) - io.Set(Null); - else - if(var >= INT_MIN && var <= INT_MAX) - io.Set(var); - else - io.Set(AsString(var)); -} - -template<> void Jsonize(JsonIO& io, String& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsString(v)) - var = v; - else - throw JsonizeError("string expected"); - } - else - io.Set(var); -} - -template<> void Jsonize(JsonIO& io, WString& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsString(v)) - var = v; - else - throw JsonizeError("string expected"); - } - else - io.Set(var); -} - -template<> void Jsonize(JsonIO& io, Date& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsNull(v)) { - var = Null; - return; - } - if(IsString(v)) { - String text = v; - if(text.GetCount() > 6) { - Date d; - d.year = ScanInt(text.Left(4)); - d.month = ScanInt(text.Mid(4, 2)); - d.day = ScanInt(text.Mid(6)); - if(var.IsValid()) { - var = d; - return; - } - } - } - throw JsonizeError("string expected for Date value"); - } - else - if(IsNull(var)) - io.Set(Null); - else - io.Set(Format("%04d%02d%02d", var.year, var.month, var.day)); -} - -template<> void Jsonize(JsonIO& io, Time& var) -{ - if(io.IsLoading()) { - const Value& v = io.Get(); - if(IsNull(v)) { - var = Null; - return; - } - if(IsString(v)) { - String text = v; - if(text.GetCount() > 15) { - Time tm; - tm.year = ScanInt(text.Left(4)); - tm.month = ScanInt(text.Mid(4, 2)); - tm.day = ScanInt(text.Mid(6, 2)); - tm.hour = ScanInt(text.Mid(9, 2)); - tm.minute = ScanInt(text.Mid(12, 2)); - tm.second = ScanInt(text.Mid(15)); - if(var.IsValid()) { - var = tm; - return; - } - } - } - throw JsonizeError("string expected for Time value"); - } - else - if(IsNull(var)) - io.Set(Null); - else - io.Set(Format("%04d%02d%02d`T%02d:%02d:%02d", - var.year, var.month, var.day, var.hour, var.minute, var.second)); -} - -END_UPP_NAMESPACE +#include "Core.h" + +NAMESPACE_UPP + +Value ParseJSON(CParser& p) +{ + p.UnicodeEscape(); + if(p.IsNumber()) + return p.ReadDouble(); + if(p.IsString()) + return p.ReadString(); + if(p.Id("null")) + return Null; + if(p.Id("true")) + return true; + if(p.Id("false")) + return false; + if(p.Char('{')) { + ValueMap m; + if(!p.IsChar('}')) + do { + String key = p.ReadString(); + p.PassChar(':'); + m.Add(key, ParseJSON(p)); + } + while(p.Char(',')); + p.PassChar('}'); + return m; + } + if(p.Char('[')) { + ValueArray va; + if(!p.IsChar(']')) + do + va.Add(ParseJSON(p)); + while(p.Char(',')); + p.PassChar(']'); + return va; + } + p.ThrowError("Unrecognized JSON element"); + return Null; +} + +Value ParseJSON(const char *s) +{ + try { + CParser p(s); + return ParseJSON(p); + } + catch(CParser::Error) { + return ErrorValue(); + } +} + +String AsJSON(const Value& v, const String& sep, bool pretty) +{ + String r; + if(v.GetType() == VALUEMAP_V) { + r << "{"; + String sep1; + if(pretty) { + r << "\r\n"; + sep1 = sep + '\t'; + } + ValueMap m = v; + ValueArray va = m.GetValues(); + for(int i = 0; i < m.GetCount(); i++) { + if(i) { + r << ","; + if(pretty) + r << "\r\n"; + } + if(pretty) + r << sep1; + r << AsCString((String)m.GetKeys()[i]) << (pretty ? ": " : ":") + << AsJSON(va[i], sep1, pretty); + } + if(pretty) + r << "\r\n" << sep; + r << "}"; + return r; + } + if(v.GetType() == VALUEARRAY_V) { + r << "["; + String sep1; + if(pretty) { + r << "\r\n"; + sep1 = sep + '\t'; + } + ValueArray va = v; + for(int i = 0; i < va.GetCount(); i++) { + if(i) { + r << ","; + if(pretty) + r << "\r\n"; + } + if(pretty) + r << sep1; + r << AsJSON(va[i], sep1, pretty); + } + if(pretty) + r << "\r\n" << sep; + r << "]"; + return r; + } + if(IsNumber(v) && IsNull(v)) + return "null"; + if(v.GetType() == INT_V) + return Format("%d", (int)v); + if(v.GetType() == BOOL_V) + return (bool)v ? "true" : "false"; + if(IsNumber(v)) + return Format("%.16g", (double)v); + if(IsString(v)) + return AsCString((String)v); + if(IsNull(v)) + return "null"; + NEVER(); + return "null"; +} + +String AsJSON(const Value& v, bool pretty) +{ + return AsJSON(v, String(), pretty); +} + +template<> void Jsonize(JsonIO& io, double& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsNull(v)) { + var = Null; + return; + } + if(IsNumber(v)) { + var = io.Get(); + return; + } + if(IsString(v)) { + double h = ScanDouble((String)v); + if(!IsNull(h)) { + var = h; + return; + } + } + throw JsonizeError("number expected"); + } + else + io.Set(var); +} + +template<> void Jsonize(JsonIO& io, int& var) +{ + double v = IntDbl(var); + Jsonize(io, v); + if(io.IsLoading()) + if(IsNull(v)) + var = Null; + else + if(v >= INT_MIN && v <= INT_MAX) + var = (int)v; + else + throw JsonizeError("number is not integer"); +} + +template<> void Jsonize(JsonIO& io, bool& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsNumber(v) && !IsNull(v)) + var = (bool)v; + else + throw JsonizeError("boolean expected"); + } + else + io.Set(var); +} + +template<> void Jsonize(JsonIO& io, int64& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsNull(v)) { + var = Null; + return; + } + if(v.Is() || v.Is()) { + var = v; + return; + } + if(IsNumber(v)) { + double d = v; + if(d >= INT64_MIN && d <= INT64_MAX) { + var = (int64)d; + return; + } + } + else + if(IsString(v)) { + int64 h = ScanInt64((String)v); + if(!IsNull(h)) { + var = h; + return; + } + } + throw JsonizeError("invalid int64 value"); + } + else + if(IsNull(var)) + io.Set(Null); + else + if(var >= INT_MIN && var <= INT_MAX) + io.Set(var); + else + io.Set(AsString(var)); +} + +template<> void Jsonize(JsonIO& io, String& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsString(v)) + var = v; + else + throw JsonizeError("string expected"); + } + else + io.Set(var); +} + +template<> void Jsonize(JsonIO& io, WString& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsString(v)) + var = v; + else + throw JsonizeError("string expected"); + } + else + io.Set(var); +} + +template<> void Jsonize(JsonIO& io, Date& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsNull(v)) { + var = Null; + return; + } + if(IsString(v)) { + String text = v; + if(text.GetCount() > 6) { + DDUMP(text); + Date d; + d.year = ScanInt(text.Left(4)); + d.month = ScanInt(text.Mid(4, 2)); + d.day = ScanInt(text.Mid(6)); + DDUMP(d); + if(d.IsValid()) { + var = d; + DDUMP(var); + return; + } + } + } + throw JsonizeError("string expected for Date value"); + } + else + if(IsNull(var)) + io.Set(Null); + else + io.Set(Format("%04d%02d%02d", var.year, var.month, var.day)); +} + +template<> void Jsonize(JsonIO& io, Time& var) +{ + if(io.IsLoading()) { + const Value& v = io.Get(); + if(IsNull(v)) { + var = Null; + return; + } + if(IsString(v)) { + String text = v; + if(text.GetCount() > 15) { + Time tm; + tm.year = ScanInt(text.Left(4)); + tm.month = ScanInt(text.Mid(4, 2)); + tm.day = ScanInt(text.Mid(6, 2)); + tm.hour = ScanInt(text.Mid(9, 2)); + tm.minute = ScanInt(text.Mid(12, 2)); + tm.second = ScanInt(text.Mid(15)); + if(tm.IsValid()) { + var = tm; + return; + } + } + } + throw JsonizeError("string expected for Time value"); + } + else + if(IsNull(var)) + io.Set(Null); + else + io.Set(Format("%04d%02d%02d`T%02d:%02d:%02d", + var.year, var.month, var.day, var.hour, var.minute, var.second)); +} + +END_UPP_NAMESPACE diff --git a/uppsrc/Core/OldValue.cpp b/uppsrc/Core/OldValue.cpp index 5a22e9ec4..4aca2d16a 100644 --- a/uppsrc/Core/OldValue.cpp +++ b/uppsrc/Core/OldValue.cpp @@ -1,685 +1,685 @@ -#include "Core.h" - -#ifndef SVO_VALUE - -NAMESPACE_UPP - -#ifndef flagSO -const Nuller Null; -#endif - -#define LTIMING(x) // RTIMING(x) - -unsigned Value::GetHashValue() const { - return IsNull() ? 0 : ptr->GetHashValue(); -} - -Value& Value::operator=(const Value& v) { - if(this == &v) return *this; - ptr->Release(); - ptr = v.ptr; - ptr->Retain(); - return *this; -} - -Value::Value(const Value& v) { - ptr = v.ptr; - ptr->Retain(); -} - -void Value::SetVoidVal() -{ - ptr = &Single(); - ptr->Retain(); -} - -Value::Value() { - SetVoidVal(); -} - -Value::~Value() { - ptr->Release(); -} - -bool Value::operator==(const Value& v) const { - if(ptr == v.ptr) return true; - bool an = IsNull(); - bool bn = v.IsNull(); - if(an || bn) return an && bn; - if(GetType() == v.GetType()) - return ptr->IsEqual(v.ptr); - return ptr->IsPolyEqual(v) || v.ptr->IsPolyEqual(*this); -} - -Value::Value(const String& s) { ptr = new RichValueRep(s); } -Value::Value(const WString& s) { ptr = new RichValueRep(s); } -Value::Value(const char *s) { ptr = new RichValueRep(s); } -Value::Value(int i) { ptr = new RichValueRep(i); } -Value::Value(int64 i) { ptr = new RichValueRep(i); } -Value::Value(double d) { ptr = new RichValueRep(d); } -Value::Value(bool b) { ptr = new RichValueRep(b); } -Value::Value(Date d) { ptr = new RichValueRep(d); } -Value::Value(Time t) { ptr = new RichValueRep