/*! \file pijson.h * \ingroup Serialization * \brief * \~english JSON serialization * \~russian Сериализация JSON */ /* PIP - Platform Independent Primitives JSON serialization Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef pijsonserialization_H #define pijsonserialization_H #include "pijson.h" // --- // serialize, PIJSON = piSerializeJSON(T) // --- // enum & arithmetic template::value, int>::type = 0> inline PIJSON piSerializeJSON(const T & v) { return PIJSON() = (int)v; } template::value, int>::type = 0, typename std::enable_if::value, int>::type = 0> inline PIJSON piSerializeJSON(const T & v) { return PIJSON() = v; } template::value, int>::type = 0, typename std::enable_if::value, int>::type = 0> inline PIJSON piSerializeJSON(const T & v) { static_assert(std::is_enum::value || std::is_arithmetic::value, "[piSerializeJSON] Error: using undeclared piSerializeJSON() for complex type!"); return {}; } // known types template<> inline PIJSON piSerializeJSON(const PIVariant & v) { return PIJSON() = v; } template inline PIJSON piSerializeJSON(const complex & v) { PIJSON ret; ret << v.real() << v.imag(); return ret; } template inline PIJSON piSerializeJSON(const PIFlags & v) { return PIJSON() = (int)v; } template<> inline PIJSON piSerializeJSON(const PIString & v) { return PIJSON() = v; } template<> inline PIJSON piSerializeJSON(const PIConstChars & v) { return PIJSON() = v.toString(); } template<> inline PIJSON piSerializeJSON(const PIByteArray & v) { return PIJSON() = PIStringAscii(v.toBase64()); } template<> inline PIJSON piSerializeJSON(const PISystemTime & v) { PIJSON ret; ret["s"] = v.seconds; ret["ns"] = v.nanoseconds; return ret; } template<> inline PIJSON piSerializeJSON(const PITime & v) { PIJSON ret; ret["h"] = v.hours; ret["m"] = v.minutes; ret["s"] = v.seconds; ret["z"] = v.milliseconds; return ret; } template<> inline PIJSON piSerializeJSON(const PIDate & v) { PIJSON ret; ret["y"] = v.year; ret["M"] = v.month; ret["d"] = v.day; return ret; } template<> inline PIJSON piSerializeJSON(const PIDateTime & v) { PIJSON ret; ret["y"] = v.year; ret["M"] = v.month; ret["d"] = v.day; ret["h"] = v.hours; ret["m"] = v.minutes; ret["s"] = v.seconds; ret["z"] = v.milliseconds; return ret; } template<> inline PIJSON piSerializeJSON(const PINetworkAddress & v) { return PIJSON() = v.toString(); } template inline PIJSON piSerializeJSON(const PIPoint & v) { PIJSON ret; ret["x"] = piSerializeJSON(v.x); ret["y"] = piSerializeJSON(v.y); return ret; } template inline PIJSON piSerializeJSON(const PILine & v) { PIJSON ret; ret["p0"] = piSerializeJSON(v.p0); ret["p1"] = piSerializeJSON(v.p1); return ret; } template inline PIJSON piSerializeJSON(const PIRect & v) { PIJSON ret; ret["bl"] = piSerializeJSON(v.bottomLeft()); ret["tr"] = piSerializeJSON(v.topRigth()); return ret; } // containers template inline PIJSON piSerializeJSON(const PIPair & v) { PIJSON ret; ret << piSerializeJSON(v.first) << piSerializeJSON(v.second); return ret; } template inline PIJSON piSerializeJSON(const PIVector & v) { if (v.isEmpty()) return PIJSON::newArray(); PIJSON ret; for (const auto & i: v) ret << piSerializeJSON(i); return ret; } template inline PIJSON piSerializeJSON(const PIDeque & v) { if (v.isEmpty()) return PIJSON::newArray(); PIJSON ret; for (const auto & i: v) ret << piSerializeJSON(i); return ret; } template inline PIJSON piSerializeJSON(const PIVector2D & v) { PIJSON ret; ret["cols"] = v.cols(); ret["rows"] = v.rows(); ret["mat"] = piSerializeJSON(v.plainVector()); return ret; } template inline PIJSON piSerializeJSON(const PISet & v) { if (v.isEmpty()) return PIJSON::newArray(); PIJSON ret; for (const auto & i: v) ret << piSerializeJSON(i); return ret; } template inline PIJSON piSerializeJSON(const PIMap & v) { if (v.isEmpty()) return PIJSON::newObject(); PIJSON ret; auto it = v.makeIterator(); while (it.next()) ret[PIVariant(it.key()).toString()] = piSerializeJSON(it.value()); return ret; } // --- // deserialize, piDeserializeJSON(T, PIJSON) // --- // enum & arithmetic template::value, int>::type = 0> inline void piDeserializeJSON(T & v, const PIJSON & js) { v = (T)js.toInt(); } template::value, int>::type = 0, typename std::enable_if::value, int>::type = 0> inline void piDeserializeJSON(T & v, const PIJSON & js) { v = js.value().value(); } template::value, int>::type = 0, typename std::enable_if::value, int>::type = 0> inline void piDeserializeJSON(T & v, const PIJSON & js) { static_assert(std::is_enum::value || std::is_arithmetic::value, "[piDeserializeJSON] Error: using undeclared piDeserializeJSON() for complex type!"); v = {}; } // known types template<> inline void piDeserializeJSON(PIVariant & v, const PIJSON & js) { v = js.value(); } template inline void piDeserializeJSON(complex & v, const PIJSON & js) { T c[2]; piDeserializeJSON(c[0], js[0]); piDeserializeJSON(c[1], js[1]); v = complex(c[0], c[1]); } template inline void piDeserializeJSON(PIFlags & v, const PIJSON & js) { v = js.toInt(); } template<> inline void piDeserializeJSON(PIString & v, const PIJSON & js) { v = js.toString(); } template<> inline void piDeserializeJSON(PIByteArray & v, const PIJSON & js) { v = PIByteArray::fromBase64(js.toString()); } template<> inline void piDeserializeJSON(PISystemTime & v, const PIJSON & js) { piDeserializeJSON(v.seconds, js["s"]); piDeserializeJSON(v.nanoseconds, js["ns"]); } template<> inline void piDeserializeJSON(PITime & v, const PIJSON & js) { v.hours = js["h"].toInt(); v.minutes = js["m"].toInt(); v.seconds = js["s"].toInt(); v.milliseconds = js["z"].toInt(); } template<> inline void piDeserializeJSON(PIDate & v, const PIJSON & js) { v.year = js["y"].toInt(); v.month = js["M"].toInt(); v.day = js["d"].toInt(); } template<> inline void piDeserializeJSON(PIDateTime & v, const PIJSON & js) { v.year = js["y"].toInt(); v.month = js["M"].toInt(); v.day = js["d"].toInt(); v.hours = js["h"].toInt(); v.minutes = js["m"].toInt(); v.seconds = js["s"].toInt(); v.milliseconds = js["z"].toInt(); } template<> inline void piDeserializeJSON(PINetworkAddress & v, const PIJSON & js) { v = PINetworkAddress(js.toString()); } template inline void piDeserializeJSON(PIPoint & v, const PIJSON & js) { piDeserializeJSON(v.x, js["x"]); piDeserializeJSON(v.y, js["y"]); } template inline void piDeserializeJSON(PILine & v, const PIJSON & js) { piDeserializeJSON(v.p0, js["p0"]); piDeserializeJSON(v.p1, js["p1"]); } template inline void piDeserializeJSON(PIRect & v, const PIJSON & js) { PIPoint bl, tr; piDeserializeJSON(bl, js["bl"]); piDeserializeJSON(tr, js["tr"]); v = PIRect(bl, tr); } // containers template inline void piDeserializeJSON(PIPair & v, const PIJSON & js) { v = {}; if (!js.isArray()) return; piDeserializeJSON(v.first, js[0]); piDeserializeJSON(v.second, js[1]); } template inline void piDeserializeJSON(PIVector & v, const PIJSON & js) { v.clear(); if (!js.isArray()) return; v.resize(js.size()); for (int i = 0; i < js.size(); ++i) piDeserializeJSON(v[i], js[i]); } template inline void piDeserializeJSON(PIDeque & v, const PIJSON & js) { v.clear(); if (!js.isArray()) return; v.resize(js.size()); for (int i = 0; i < js.size(); ++i) piDeserializeJSON(v[i], js[i]); } template inline void piDeserializeJSON(PIVector2D & v, const PIJSON & js) { v.clear(); if (!js.isObject()) return; v.resize(js["rows"].toInt(), js["cols"].toInt()); const auto & mat(js["mat"]); if (!mat.isArray()) return; piDeserializeJSON(v.plainVector(), mat); } template inline void piDeserializeJSON(PISet & v, const PIJSON & js) { v.clear(); if (!js.isArray()) return; T _t; for (int i = 0; i < js.size(); ++i) { piDeserializeJSON(_t, js[i]); v << _t; } } template inline void piDeserializeJSON(PIMap & v, const PIJSON & js) { v.clear(); if (!js.isObject()) return; const auto & obj(js.object()); auto it = obj.makeIterator(); while (it.next()) piDeserializeJSON(v[PIVariant(it.key()).value()], it.value()); } // --- // PIJSON static wrapper // --- template PIJSON PIJSON::serialize(const T & v) { return piSerializeJSON(v); } template T PIJSON::deserialize(const PIJSON & json) { T ret; piDeserializeJSON(ret, json); return ret; } #endif // pijsonserialization_h