diff --git a/uppsrc/Core/JSON.h b/uppsrc/Core/JSON.h index e59fb158b..e5fbc974d 100644 --- a/uppsrc/Core/JSON.h +++ b/uppsrc/Core/JSON.h @@ -1,383 +1,366 @@ -Value ParseJSON(CParser& p); -Value ParseJSON(const char *s); - -inline String AsJSON(int i) { return IsNull(i) ? "null" : AsString(i); } -inline String AsJSON(double n) { return IsNull(n) ? "null" : AsString(n); } -inline String AsJSON(bool b) { return b ? "true" : "false"; } -inline String AsJSON(const String& s) { return AsCString(s); } -inline String AsJSON(const WString& s) { return AsCString(s.ToString()); } -inline String AsJSON(const char *s) { return AsCString(s); } - -String AsJSON(const Value& v, const String& indent, bool pretty); -String AsJSON(const Value& v, bool pretty = false); - -class JsonArray; - -class Json { - String text; - - Json& CatRaw(const char *key, const String& val) { - if(text.GetCount()) - text << ','; - text << '\"' << key << "\":" << val; - return *this; - } - -public: - String ToString() const { return "{" + text + "}"; } - String operator~() const { return ToString(); } - operator String() const { return ToString(); } - - Json& operator()(const char *key, const Value& value) { return CatRaw(key, AsJSON(value)); } - Json& operator()(const char *key, int i) { return CatRaw(key, AsJSON(i)); } - Json& operator()(const char *key, double n) { return CatRaw(key, AsJSON(n)); } - Json& operator()(const char *key, bool b) { return CatRaw(key, AsJSON(b)); } - Json& operator()(const char *key, const String& s) { return CatRaw(key, AsJSON(s)); } - Json& operator()(const char *key, const WString& s) { return CatRaw(key, AsJSON(s)); } - Json& operator()(const char *key, const char *s) { return CatRaw(key, AsJSON(s)); } - Json& operator()(const char *key, const Json& object) { return CatRaw(key, ~object); } - Json& operator()(const char *key, const JsonArray& array); - - Json() {} - Json(const char *key, const Value& value) { CatRaw(key, AsJSON(value)); } - Json(const char *key, int i) { CatRaw(key, AsJSON(i)); } - Json(const char *key, double n) { CatRaw(key, AsJSON(n)); } - Json(const char *key, bool b) { CatRaw(key, AsJSON(b)); } - Json(const char *key, const String& s) { CatRaw(key, AsJSON(s)); } - Json(const char *key, const WString& s) { CatRaw(key, AsJSON(s)); } - Json(const char *key, const char *s) { CatRaw(key, AsJSON(s)); } - Json(const char *key, const Json& object) { CatRaw(key, ~object); } - Json(const char *key, const JsonArray& array) { operator()(key, array); } -}; - -class JsonArray { - String text; - - JsonArray& CatRaw(const String& val) { - if(text.GetCount()) - text << ','; - text << val; - return *this; - } - -public: - String ToString() const { return "[" + text + "]"; } - String operator~() const { return ToString(); } - operator String() const { return ToString(); } - - JsonArray& operator<<(const Value& value) { return CatRaw(AsJSON(value)); } - JsonArray& operator<<(int i) { return CatRaw(AsJSON(i)); } - JsonArray& operator<<(double n) { return CatRaw(AsJSON(n)); } - JsonArray& operator<<(bool b) { return CatRaw(AsJSON(b)); } - JsonArray& operator<<(const String& s) { return CatRaw(AsJSON(s)); } - JsonArray& operator<<(const WString& s) { return CatRaw(AsJSON(s)); } - JsonArray& operator<<(const char *s) { return CatRaw(AsJSON(s)); } - JsonArray& operator<<(const Json& object) { return CatRaw(~object); } - JsonArray& operator<<(const JsonArray& array) { return CatRaw(~array); } - - JsonArray() {} -}; - -inline Json& Json::operator()(const char *key, const JsonArray& array) -{ - return CatRaw(key, array); -} - -class JsonIO { - const Value *src; - One map; - Value tgt; - -public: - bool IsLoading() const { return src; } - bool IsStoring() const { return !src; } - - const Value& Get() const { ASSERT(IsLoading()); return *src; } - void Set(const Value& v) { ASSERT(IsStoring() && !map); tgt = v; } - void Put(Value& v) { ASSERT(IsStoring()); if(map) v = *map; else v = tgt; } - Value GetResult() const { ASSERT(IsStoring()); return map ? Value(*map) : tgt; } - - template - JsonIO& operator()(const char *key, T& value); - - JsonIO(const Value& src) : src(&src) {} - JsonIO() { src = NULL; } -}; - -struct JsonizeError : Exc { - JsonizeError(const String& s) : Exc(s) {} -}; - -template -void Jsonize(JsonIO& io, T& var) -{ - var.Jsonize(io); -} - -template -JsonIO& JsonIO::operator()(const char *key, T& value) -{ - if(IsLoading()) { - const Value& v = (*src)[key]; - if(!v.IsVoid()) { - JsonIO jio(v); - Jsonize(jio, value); - } - } - else { - ASSERT(tgt.IsVoid()); - if(!map) - map.Create(); - JsonIO jio; - Jsonize(jio, value); - if(jio.map) - map->Add(key, *jio.map); - else - map->Add(key, jio.tgt); - } - return *this; -} - -template -Value StoreAsJsonValue(const T& var) -{ - JsonIO io; - Jsonize(io, const_cast(var)); - return io.GetResult(); -} - -template -void LoadFromJsonValue(T& var, const Value& x) -{ - JsonIO io(x); - Jsonize(io, var); -} - -template -String StoreAsJson(const T& var, bool pretty = false) -{ - return AsJSON(StoreAsJsonValue(var), pretty); -} - -template -bool LoadFromJson(T& var, const char *json) -{ - try { - Value jv = ParseJSON(json); - if(jv.IsError()) - return false; - LoadFromJsonValue(var, jv); - } - catch(JsonizeError) { - return false; - } - return true; -} - -String sJsonFile(const char *file); - -template -bool StoreAsJsonFile(const T& var, const char *file, bool pretty = false) -{ - return SaveFile(sJsonFile(file), StoreAsJson(var, pretty));; -} - -template -bool LoadFromJsonFile(T& var, const char *file = NULL) -{ - return LoadFromJson(var, LoadFile(sJsonFile(file))); -} - -template<> void Jsonize(JsonIO& io, int& var); -template<> void Jsonize(JsonIO& io, int16& var); -template<> void Jsonize(JsonIO& io, int64& var); -template<> void Jsonize(JsonIO& io, double& var); -template<> void Jsonize(JsonIO& io, bool& var); -template<> void Jsonize(JsonIO& io, String& var); -template<> void Jsonize(JsonIO& io, WString& var); -template<> void Jsonize(JsonIO& io, Date& var); -template<> void Jsonize(JsonIO& io, Time& var); - -template -void JsonizeArray(JsonIO& io, T& array) -{ - if(io.IsLoading()) { - const Value& va = io.Get(); - array.SetCount(va.GetCount()); - for(int i = 0; i < va.GetCount(); i++) { - JsonIO jio(va[i]); - Jsonize(jio, array[i]); - } - } - else { - Vector va; - va.SetCount(array.GetCount()); - for(int i = 0; i < array.GetCount(); i++) { - JsonIO jio; - Jsonize(jio, array[i]); - jio.Put(va[i]); - } - io.Set(ValueArray(va)); - } -} - -template -void Jsonize(JsonIO& io, Vector& var) -{ - JsonizeArray, T>(io, var); -} - -template -void Jsonize(JsonIO& io, Array& var) -{ - JsonizeArray, T>(io, var); -} - -template -void JsonizeMap(JsonIO& io, T& map, const char *keyid, const char *valueid) -{ - if(io.IsLoading()) { - map.Clear(); - const Value& va = io.Get(); - map.Reserve(va.GetCount()); - for(int i = 0; i < va.GetCount(); i++) { - K key; - V value; - LoadFromJsonValue(key, va[i][keyid]); - LoadFromJsonValue(value, va[i][valueid]); - map.Add(key, value); - } - } - else { - Vector va; - va.SetCount(map.GetCount()); - for(int i = 0; i < map.GetCount(); i++) - if(!map.IsUnlinked(i)) { - ValueMap item; - item.Add(keyid, StoreAsJsonValue(map.GetKey(i))); - item.Add(valueid, StoreAsJsonValue(map[i])); - va[i] = item; - } - io.Set(ValueArray(va)); - } -} - -template -void Jsonize(JsonIO& io, VectorMap& map) -{ - JsonizeMap, K, V>(io, map, "key", "value"); -} - -template -void Jsonize(JsonIO& io, ArrayMap& map) -{ - JsonizeMap, K, V>(io, map, "key", "value"); -} - -template -void JsonizeStringMap(JsonIO& io, T& map) -{ - if(io.IsLoading()) { - map.Clear(); - const ValueMap& va = io.Get(); - map.Reserve(va.GetCount()); - for(int i = 0; i < va.GetCount(); i++) { - V value; - String key = va.GetKey(i); - LoadFromJsonValue(key, va.GetKey(i)); - LoadFromJsonValue(value, va.GetValue(i)); - map.Add(key, value); - } - } - else { - Index index; - Vector values; - index.Reserve(map.GetCount()); - values.Reserve(map.GetCount()); - for (int i=0; i -void StringMap(JsonIO& io, VectorMap& map) -{ - JsonizeStringMap, K, V>(io, map); -} - -template -void StringMap(JsonIO& io, ArrayMap& map) -{ - JsonizeStringMap, K, V>(io, map); -} - -template -void JsonizeIndex(JsonIO& io, T& index) -{ - if(io.IsLoading()) { - const Value& va = io.Get(); - index.Reserve(va.GetCount()); - for(int i = 0; i < va.GetCount(); i++) { - V v; - LoadFromJsonValue(v, va[i]); - index.Add(v); - } - } - else { - Vector va; - for(int i = 0; i < index.GetCount(); i++) - if(!index.IsUnlinked(i)) - va.Add(StoreAsJsonValue(index[i])); - io.Set(ValueArray(va)); - } -} - -template -void Jsonize(JsonIO& io, Index& var) -{ - JsonizeIndex, T>(io, var); -} - -template -void Jsonize(JsonIO& io, ArrayIndex& var) -{ - JsonizeIndex, T>(io, var); -} - - -template -void XmlizeBySerialize(XmlIO& xio, T& x) -{ - String h; - if(xio.IsStoring()) - h = HexString(StoreAsString(x)); - xio.Attr("data", h); - if(xio.IsLoading()) - try { - LoadFromString(x, ScanHexString(h)); - } - catch(LoadingError) { - throw XmlError("xmlize by serialize error"); - } -} - -template -void JsonizeBySerialize(JsonIO& jio, T& x) -{ - String h; - if(jio.IsStoring()) - h = HexString(StoreAsString(x)); - jio("data", h); - if(jio.IsLoading()) - try { - LoadFromString(x, ScanHexString(h)); - } - catch(LoadingError) { - throw JsonizeError("jsonize by serialize error"); - } -} +Value ParseJSON(CParser& p); +Value ParseJSON(const char *s); + +inline String AsJSON(int i) { return IsNull(i) ? "null" : AsString(i); } +inline String AsJSON(double n) { return IsNull(n) ? "null" : AsString(n); } +inline String AsJSON(bool b) { return b ? "true" : "false"; } +inline String AsJSON(const String& s) { return AsCString(s); } +inline String AsJSON(const WString& s) { return AsCString(s.ToString()); } +inline String AsJSON(const char *s) { return AsCString(s); } + +String AsJSON(const Value& v, const String& indent, bool pretty); +String AsJSON(const Value& v, bool pretty = false); + +class JsonArray; + +class Json { + String text; + + Json& CatRaw(const char *key, const String& val) { + if(text.GetCount()) + text << ','; + text << '\"' << key << "\":" << val; + return *this; + } + +public: + String ToString() const { return "{" + text + "}"; } + String operator~() const { return ToString(); } + operator String() const { return ToString(); } + + Json& operator()(const char *key, const Value& value) { return CatRaw(key, AsJSON(value)); } + Json& operator()(const char *key, int i) { return CatRaw(key, AsJSON(i)); } + Json& operator()(const char *key, double n) { return CatRaw(key, AsJSON(n)); } + Json& operator()(const char *key, bool b) { return CatRaw(key, AsJSON(b)); } + Json& operator()(const char *key, const String& s) { return CatRaw(key, AsJSON(s)); } + Json& operator()(const char *key, const WString& s) { return CatRaw(key, AsJSON(s)); } + Json& operator()(const char *key, const char *s) { return CatRaw(key, AsJSON(s)); } + Json& operator()(const char *key, const Json& object) { return CatRaw(key, ~object); } + Json& operator()(const char *key, const JsonArray& array); + + Json() {} + Json(const char *key, const Value& value) { CatRaw(key, AsJSON(value)); } + Json(const char *key, int i) { CatRaw(key, AsJSON(i)); } + Json(const char *key, double n) { CatRaw(key, AsJSON(n)); } + Json(const char *key, bool b) { CatRaw(key, AsJSON(b)); } + Json(const char *key, const String& s) { CatRaw(key, AsJSON(s)); } + Json(const char *key, const WString& s) { CatRaw(key, AsJSON(s)); } + Json(const char *key, const char *s) { CatRaw(key, AsJSON(s)); } + Json(const char *key, const Json& object) { CatRaw(key, ~object); } + Json(const char *key, const JsonArray& array) { operator()(key, array); } +}; + +class JsonArray { + String text; + + JsonArray& CatRaw(const String& val) { + if(text.GetCount()) + text << ','; + text << val; + return *this; + } + +public: + String ToString() const { return "[" + text + "]"; } + String operator~() const { return ToString(); } + operator String() const { return ToString(); } + + JsonArray& operator<<(const Value& value) { return CatRaw(AsJSON(value)); } + JsonArray& operator<<(int i) { return CatRaw(AsJSON(i)); } + JsonArray& operator<<(double n) { return CatRaw(AsJSON(n)); } + JsonArray& operator<<(bool b) { return CatRaw(AsJSON(b)); } + JsonArray& operator<<(const String& s) { return CatRaw(AsJSON(s)); } + JsonArray& operator<<(const WString& s) { return CatRaw(AsJSON(s)); } + JsonArray& operator<<(const char *s) { return CatRaw(AsJSON(s)); } + JsonArray& operator<<(const Json& object) { return CatRaw(~object); } + JsonArray& operator<<(const JsonArray& array) { return CatRaw(~array); } + + JsonArray() {} +}; + +inline Json& Json::operator()(const char *key, const JsonArray& array) +{ + return CatRaw(key, array); +} + +class JsonIO { + const Value *src; + One map; + Value tgt; + +public: + bool IsLoading() const { return src; } + bool IsStoring() const { return !src; } + + const Value& Get() const { ASSERT(IsLoading()); return *src; } + void Set(const Value& v) { ASSERT(IsStoring() && !map); tgt = v; } + void Put(Value& v) { ASSERT(IsStoring()); if(map) v = *map; else v = tgt; } + Value GetResult() const { ASSERT(IsStoring()); return map ? Value(*map) : tgt; } + + template + JsonIO& operator()(const char *key, T& value); + + JsonIO(const Value& src) : src(&src) {} + JsonIO() { src = NULL; } +}; + +struct JsonizeError : Exc { + JsonizeError(const String& s) : Exc(s) {} +}; + +template +void Jsonize(JsonIO& io, T& var) +{ + var.Jsonize(io); +} + +template +JsonIO& JsonIO::operator()(const char *key, T& value) +{ + if(IsLoading()) { + const Value& v = (*src)[key]; + if(!v.IsVoid()) { + JsonIO jio(v); + Jsonize(jio, value); + } + } + else { + ASSERT(tgt.IsVoid()); + if(!map) + map.Create(); + JsonIO jio; + Jsonize(jio, value); + if(jio.map) + map->Add(key, *jio.map); + else + map->Add(key, jio.tgt); + } + return *this; +} + +template +Value StoreAsJsonValue(const T& var) +{ + JsonIO io; + Jsonize(io, const_cast(var)); + return io.GetResult(); +} + +template +void LoadFromJsonValue(T& var, const Value& x) +{ + JsonIO io(x); + Jsonize(io, var); +} + +template +String StoreAsJson(const T& var, bool pretty = false) +{ + return AsJSON(StoreAsJsonValue(var), pretty); +} + +template +bool LoadFromJson(T& var, const char *json) +{ + try { + Value jv = ParseJSON(json); + if(jv.IsError()) + return false; + LoadFromJsonValue(var, jv); + } + catch(JsonizeError) { + return false; + } + return true; +} + +String sJsonFile(const char *file); + +template +bool StoreAsJsonFile(const T& var, const char *file, bool pretty = false) +{ + return SaveFile(sJsonFile(file), StoreAsJson(var, pretty));; +} + +template +bool LoadFromJsonFile(T& var, const char *file = NULL) +{ + return LoadFromJson(var, LoadFile(sJsonFile(file))); +} + +template<> void Jsonize(JsonIO& io, int& var); +template<> void Jsonize(JsonIO& io, int16& var); +template<> void Jsonize(JsonIO& io, int64& var); +template<> void Jsonize(JsonIO& io, double& var); +template<> void Jsonize(JsonIO& io, bool& var); +template<> void Jsonize(JsonIO& io, String& var); +template<> void Jsonize(JsonIO& io, WString& var); +template<> void Jsonize(JsonIO& io, Date& var); +template<> void Jsonize(JsonIO& io, Time& var); + +template +void JsonizeArray(JsonIO& io, T& array) +{ + if(io.IsLoading()) { + const Value& va = io.Get(); + array.SetCount(va.GetCount()); + for(int i = 0; i < va.GetCount(); i++) { + JsonIO jio(va[i]); + Jsonize(jio, array[i]); + } + } + else { + Vector va; + va.SetCount(array.GetCount()); + for(int i = 0; i < array.GetCount(); i++) { + JsonIO jio; + Jsonize(jio, array[i]); + jio.Put(va[i]); + } + io.Set(ValueArray(va)); + } +} + +template +void Jsonize(JsonIO& io, Vector& var) +{ + JsonizeArray, T>(io, var); +} + +template +void Jsonize(JsonIO& io, Array& var) +{ + JsonizeArray, T>(io, var); +} + +template +void JsonizeMap(JsonIO& io, T& map, const char *keyid, const char *valueid) +{ + if(io.IsLoading()) { + map.Clear(); + const Value& va = io.Get(); + map.Reserve(va.GetCount()); + for(int i = 0; i < va.GetCount(); i++) { + K key; + V value; + LoadFromJsonValue(key, va[i][keyid]); + LoadFromJsonValue(value, va[i][valueid]); + map.Add(key, value); + } + } + else { + Vector va; + va.SetCount(map.GetCount()); + for(int i = 0; i < map.GetCount(); i++) + if(!map.IsUnlinked(i)) { + ValueMap item; + item.Add(keyid, StoreAsJsonValue(map.GetKey(i))); + item.Add(valueid, StoreAsJsonValue(map[i])); + va[i] = item; + } + io.Set(ValueArray(va)); + } +} + +template +void Jsonize(JsonIO& io, VectorMap& map) +{ + JsonizeMap, K, V>(io, map, "key", "value"); +} + +template +void Jsonize(JsonIO& io, ArrayMap& map) +{ + JsonizeMap, K, V>(io, map, "key", "value"); +} + +template +void JsonizeStringMap(JsonIO& io, T& map) +{ + if(io.IsLoading()) { + map.Clear(); + const ValueMap& va = io.Get(); + map.Reserve(va.GetCount()); + for(int i = 0; i < va.GetCount(); i++) { + V value; + String key = va.GetKey(i); + LoadFromJsonValue(key, va.GetKey(i)); + LoadFromJsonValue(value, va.GetValue(i)); + map.Add(key, value); + } + } + else { + Index index; + Vector values; + index.Reserve(map.GetCount()); + values.Reserve(map.GetCount()); + for (int i=0; i +void StringMap(JsonIO& io, VectorMap& map) +{ + JsonizeStringMap, K, V>(io, map); +} + +template +void StringMap(JsonIO& io, ArrayMap& map) +{ + JsonizeStringMap, K, V>(io, map); +} + +template +void JsonizeIndex(JsonIO& io, T& index) +{ + if(io.IsLoading()) { + const Value& va = io.Get(); + index.Reserve(va.GetCount()); + for(int i = 0; i < va.GetCount(); i++) { + V v; + LoadFromJsonValue(v, va[i]); + index.Add(v); + } + } + else { + Vector va; + for(int i = 0; i < index.GetCount(); i++) + if(!index.IsUnlinked(i)) + va.Add(StoreAsJsonValue(index[i])); + io.Set(ValueArray(va)); + } +} + +template +void Jsonize(JsonIO& io, Index& var) +{ + JsonizeIndex, T>(io, var); +} + +template +void Jsonize(JsonIO& io, ArrayIndex& var) +{ + JsonizeIndex, T>(io, var); +} + +template +void JsonizeBySerialize(JsonIO& jio, T& x) +{ + String h; + if(jio.IsStoring()) + h = HexString(StoreAsString(x)); + jio("data", h); + if(jio.IsLoading()) + try { + LoadFromString(x, ScanHexString(h)); + } + catch(LoadingError) { + throw JsonizeError("jsonize by serialize error"); + } +} diff --git a/uppsrc/Core/Value.hpp b/uppsrc/Core/Value.hpp index 0f6479e08..fe06399d3 100644 --- a/uppsrc/Core/Value.hpp +++ b/uppsrc/Core/Value.hpp @@ -138,8 +138,10 @@ void Value::InitSmall(const T& init) template T& Value::GetSmall() const { +#ifdef _DEBUG dword t = GetValueTypeNo(); ASSERT(t < 255 && (t == STRING_V ? IsString() : Is((byte)t))); +#endif return *(T*)&data; } diff --git a/uppsrc/Core/Xmlize.h b/uppsrc/Core/Xmlize.h index aff43cf73..8869e4492 100644 --- a/uppsrc/Core/Xmlize.h +++ b/uppsrc/Core/Xmlize.h @@ -319,3 +319,19 @@ bool LoadFromXMLFile(T& data, const char *file = NULL) ParamHelper__ p(data); return LoadFromXMLFile(callback(&p, &ParamHelper__::Invoke), file); } + +template +void XmlizeBySerialize(XmlIO& xio, T& x) +{ + String h; + if(xio.IsStoring()) + h = HexString(StoreAsString(x)); + xio.Attr("data", h); + if(xio.IsLoading()) + try { + LoadFromString(x, ScanHexString(h)); + } + catch(LoadingError) { + throw XmlError("xmlize by serialize error"); + } +}