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, INT_MAX, NULL, ASCSTRING_JSON); } inline String AsJSON(const WString& s) { return AsCString(s.ToString(), INT_MAX, NULL, ASCSTRING_JSON); } inline String AsJSON(const char *s) { return AsCString(s, INT_MAX, NULL, ASCSTRING_JSON); } String AsJSON(Time tm); String AsJSON(Date dt); String AsJSON(const Value& v, const String& indent, bool pretty); String AsJSON(const Value& v, bool pretty = false); class JsonArray; class Json { String text; public: Json& CatRaw(const char *key, const String& val); String ToString() const { return "{" + text + "}"; } String operator~() const { return ToString(); } operator String() const { return ToString(); } operator bool() const { return text.GetCount(); } 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, Date d) { return CatRaw(key, AsJSON(d)); } Json& operator()(const char *key, Time t) { return CatRaw(key, AsJSON(t)); } 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, Date d) { CatRaw(key, AsJSON(d)); } Json(const char *key, Time t) { CatRaw(key, AsJSON(t)); } 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; public: JsonArray& CatRaw(const String& val); String ToString() const { return "[" + text + "]"; } String operator~() const { return ToString(); } operator String() const { return ToString(); } operator bool() const { return text.GetCount(); } 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<<(Date d) { return CatRaw(AsJSON(d)); } JsonArray& operator<<(Time t) { return CatRaw(AsJSON(t)); } 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; } Value Get(const char *key) { ASSERT(IsLoading()); return (*src)[key]; } void Set(const char *key, const Value& 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); template JsonIO& operator()(const char *key, T& value, const T& defvalue); template JsonIO& List(const char *key, const char *, T& var) { return operator()(key, var); } template JsonIO& Var(const char *key, T& value, X item_jsonize); template JsonIO& Array(const char *key, T& value, X item_jsonize, const char * = NULL); 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 JsonIO& JsonIO::Var(const char *key, T& value, X jsonize) { 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 void JsonizeArray(JsonIO& io, T& array, X item_jsonize) { if(io.IsLoading()) { const Value& va = io.Get(); array.SetCount(va.GetCount()); for(int i = 0; i < va.GetCount(); i++) { JsonIO jio(va[i]); item_jsonize(jio, array[i]); } } else { Vector va; va.SetCount(array.GetCount()); for(int i = 0; i < array.GetCount(); i++) { JsonIO jio; item_jsonize(jio, array[i]); jio.Put(va[i]); } io.Set(ValueArray(pick(va))); } } template JsonIO& JsonIO::Array(const char *key, T& value, X item_jsonize, const char *) { if(IsLoading()) { const Value& v = (*src)[key]; if(!v.IsVoid()) { JsonIO jio(v); JsonizeArray(jio, value, item_jsonize); } } else { ASSERT(tgt.IsVoid()); if(!map) map.Create(); JsonIO jio; JsonizeArray(jio, value, item_jsonize); if(jio.map) map->Add(key, *jio.map); else map->Add(key, jio.tgt); } return *this; } template JsonIO& JsonIO::operator()(const char *key, T& value, const T& defvalue) { if(IsLoading()) { const Value& v = (*src)[key]; if(v.IsVoid()) value = defvalue; else { 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(ValueTypeError) { return false; } catch(JsonizeError) { return false; } return true; } String sJsonFile(const char *file); template bool StoreAsJsonFile(const T& var, const char *file = NULL, 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, byte& 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) { JsonizeArray(io, array, [](JsonIO& io, ValueTypeOf& item) { Jsonize(io, item); }); } 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, pick(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(pick(va))); } } template void JsonizeSortedMap(JsonIO& io, T& map, const char *keyid, const char *valueid) { if(io.IsLoading()) { map.Clear(); const Value& va = io.Get(); 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, pick(value)); } } else { Vector va; va.SetCount(map.GetCount()); for(int i = 0; i < map.GetCount(); i++) { ValueMap item; item.Add(keyid, StoreAsJsonValue(map.GetKey(i))); item.Add(valueid, StoreAsJsonValue(map[i])); va[i] = item; } io.Set(ValueArray(pick(va))); } } 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, pick(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(pick(v)); } } else { Vector va; for(int i = 0; i < index.GetCount(); i++) if(!index.IsUnlinked(i)) va.Add(StoreAsJsonValue(index[i])); io.Set(ValueArray(pick(va))); } } 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"); } } template struct LambdaIzeVar { IZE& ize; void Jsonize(JsonIO& io) { ize(io); } void Xmlize(XmlIO& io) { ize(io); } LambdaIzeVar(IZE& ize) : ize(ize) {} }; template void LambdaIze(IO& io, const char *id, IZE ize) { LambdaIzeVar var(ize); io(id, var); }