decompose pip_cmg

add serialization/pijsonserialization.h for JSON de/serialization
add -J flag for pip_cmg to make JSON serialization methods
not finished yet, but basically workable now
This commit is contained in:
2025-08-02 18:48:38 +03:00
parent 19daab173c
commit cf25cacc17
19 changed files with 1348 additions and 475 deletions

View File

@@ -127,7 +127,21 @@ public:
//! \~russian
//! Прибавить координаты второй точки и сохранить.
//! \details Является копией метода \a translate().
void operator+=(const PIPoint<Type> & p) { translate(p); }
PIPoint<Type> & operator+=(const PIPoint<Type> & p) {
translate(p);
return *this;
}
PIPoint<Type> & operator*=(Type v) {
x *= v;
y *= v;
return *this;
}
PIPoint<Type> & operator/=(Type v) {
x /= v;
y /= v;
return *this;
}
//! \~russian Сложить координаты двух точек.
PIPoint<Type> operator+(const PIPoint<Type> & p) { return PIPoint<Type>(x + p.x, y + p.y); }
@@ -144,6 +158,12 @@ public:
//! \~russian Инвертировать координаты точки.
PIPoint<Type> operator-() { return PIPoint<Type>(-x, -y); }
//! \~russian Умножить координаты точки.
PIPoint<Type> operator*(Type v) { return PIPoint<Type>(x * v, y * v); }
//! \~russian Делить координаты точки.
PIPoint<Type> operator/(Type v) { return PIPoint<Type>(x / v, y / v); }
//! \~russian Проверить равенство координат двух точек.
bool operator==(const PIPoint<Type> & p) const { return (x == p.x && y == p.y); }

View File

@@ -33,6 +33,7 @@
#include "piioutilsmodule.h"
#include "piliterals.h"
#include "pimathmodule.h"
#include "piserializationmodule.h"
#include "pistatemachinemodule.h"
#include "pisystemmodule.h"
#include "pithreadmodule.h"

View File

@@ -0,0 +1,395 @@
/*! \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 <http://www.gnu.org/licenses/>.
*/
#ifndef pijsonserialization_H
#define pijsonserialization_H
#include "pijson.h"
// ---
// serialize, PIJSON = piSerializeJSON(T)
// ---
// enum & arithmetic
template<typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
inline PIJSON piSerializeJSON(const T & v) {
return PIJSON() = (int)v;
}
template<typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
inline PIJSON piSerializeJSON(const T & v) {
return PIJSON() = v;
}
template<typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if<!std::is_arithmetic<T>::value, int>::type = 0>
inline PIJSON piSerializeJSON(const T & v) {
static_assert(false, "[piSerializeJSON] Error: using undeclared piSerializeJSON() for complex type!");
return {};
}
// known types
template<>
inline PIJSON piSerializeJSON(const PIVariant & v) {
return PIJSON() = v;
}
template<typename T>
inline PIJSON piSerializeJSON(const complex<T> & v) {
PIJSON ret;
ret << v.real() << v.imag();
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PIFlags<T> & 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<typename T>
inline PIJSON piSerializeJSON(const PIPoint<T> & v) {
PIJSON ret;
ret["x"] = piSerializeJSON(v.x);
ret["y"] = piSerializeJSON(v.y);
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PILine<T> & v) {
PIJSON ret;
ret["p0"] = piSerializeJSON(v.p0);
ret["p1"] = piSerializeJSON(v.p1);
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PIRect<T> & v) {
PIJSON ret;
ret["bl"] = piSerializeJSON(v.bottomLeft());
ret["tr"] = piSerializeJSON(v.topRigth());
return ret;
}
// containers
template<typename T1, typename T2>
inline PIJSON piSerializeJSON(const PIPair<T1, T2> & v) {
PIJSON ret;
ret << piSerializeJSON(v.first) << piSerializeJSON(v.second);
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PIVector<T> & v) {
if (v.isEmpty()) return PIJSON::newArray();
PIJSON ret;
for (const auto & i: v)
ret << piSerializeJSON(i);
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PIDeque<T> & v) {
if (v.isEmpty()) return PIJSON::newArray();
PIJSON ret;
for (const auto & i: v)
ret << piSerializeJSON(i);
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PIVector2D<T> & v) {
PIJSON ret;
ret["cols"] = v.cols();
ret["rows"] = v.rows();
ret["mat"] = piSerializeJSON(v.plainVector());
return ret;
}
template<typename T>
inline PIJSON piSerializeJSON(const PISet<T> & v) {
if (v.isEmpty()) return PIJSON::newArray();
PIJSON ret;
for (const auto & i: v)
ret << piSerializeJSON(i);
return ret;
}
template<typename K, typename T>
inline PIJSON piSerializeJSON(const PIMap<K, T> & 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<typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
inline void piDeserializeJSON(T & v, const PIJSON & js) {
v = (T)js.toInt();
}
template<typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
inline void piDeserializeJSON(T & v, const PIJSON & js) {
v = js.value().value<T>();
}
template<typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if<!std::is_arithmetic<T>::value, int>::type = 0>
inline void piDeserializeJSON(T & v, const PIJSON & js) {
static_assert(false, "[piDeserializeJSON] Error: using undeclared piDeserializeJSON() for complex type!");
v = {};
}
// known types
template<>
inline void piDeserializeJSON(PIVariant & v, const PIJSON & js) {
v = js.value();
}
template<typename T>
inline void piDeserializeJSON(complex<T> & v, const PIJSON & js) {
T c[2];
piDeserializeJSON(c[0], js[0]);
piDeserializeJSON(c[1], js[1]);
v = complex<T>(c[0], c[1]);
}
template<typename T>
inline void piDeserializeJSON(PIFlags<T> & 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<typename T>
inline void piDeserializeJSON(PIPoint<T> & v, const PIJSON & js) {
piDeserializeJSON(v.x, js["x"]);
piDeserializeJSON(v.y, js["y"]);
}
template<typename T>
inline void piDeserializeJSON(PILine<T> & v, const PIJSON & js) {
piDeserializeJSON(v.p0, js["p0"]);
piDeserializeJSON(v.p1, js["p1"]);
}
template<typename T>
inline void piDeserializeJSON(PIRect<T> & v, const PIJSON & js) {
PIPoint<T> bl, tr;
piDeserializeJSON(bl, js["bl"]);
piDeserializeJSON(tr, js["tr"]);
v = PIRect<T>(bl, tr);
}
// containers
template<typename T1, typename T2>
inline void piDeserializeJSON(PIPair<T1, T2> & v, const PIJSON & js) {
v = {};
if (!js.isArray()) return;
piDeserializeJSON(v.first, js[0]);
piDeserializeJSON(v.second, js[1]);
}
template<typename T>
inline void piDeserializeJSON(PIVector<T> & 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<typename T>
inline void piDeserializeJSON(PIDeque<T> & 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<typename T>
inline void piDeserializeJSON(PIVector2D<T> & 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<typename T>
inline void piDeserializeJSON(PISet<T> & 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<typename K, typename T>
inline void piDeserializeJSON(PIMap<K, T> & 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<K>()], it.value());
}
#endif // pijsonserialization_h

View File

@@ -54,6 +54,7 @@
#include "pibinarystream.h"
#include "pichunkstream.h"
#include "pijson.h"
#include "pijsonserialization.h"
#include "pivaluetree_conversions.h"
#endif // PISERIALIZATIONMODULE_H

View File

@@ -793,7 +793,7 @@ public:
//! \~english Add to the end data "data" with size "size"
//! \~russian Добавляет в конец массива данные по указателю "data" размером "size"
PIByteArray & push_back(const void * data_, int size_) {
const uint ps = size();
const size_t ps = size();
enlarge(size_);
memcpy(data(ps), data_, size_);
return *this;
@@ -1092,7 +1092,7 @@ public:
//! \~english Add to the end data "data" with size "size"
//! \~russian Добавляет в конец массива данные по указателю "data" размером "size"
PIByteArray & append(const void * data_, int size_) {
const uint ps = size();
const size_t ps = size();
enlarge(size_);
memcpy(data(ps), data_, size_);
return *this;
@@ -1101,7 +1101,7 @@ public:
//! \~english Add to the end byte array "data"
//! \~russian Добавляет в конец массива содержимое массива "data"
PIByteArray & append(const PIByteArray & data_) {
const uint ps = size();
const size_t ps = size();
enlarge(data_.size_s());
memcpy(data(ps), data_.data(), data_.size());
return *this;