code format

This commit is contained in:
2022-12-14 14:13:52 +03:00
parent 430a41fefc
commit c2b8a8d6da
297 changed files with 27331 additions and 24162 deletions

View File

@@ -3,43 +3,47 @@
* \~\brief
* \~english Binary serialization interface
* \~russian Интерфейс бинарной сериализации
*/
*/
/*
PIP - Platform Independent Primitives
Binary serialization interface
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
Binary serialization interface
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 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.
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/>.
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 PIBINARYSTREAM_H
#define PIBINARYSTREAM_H
#include "pimemoryblock.h"
#include "pibitarray.h"
#include "pimap.h"
#include "pimemoryblock.h"
#include "pivector2d.h"
#define PIP_BINARY_STREAM
#define BINARY_STREAM_FRIEND(T) \
template<typename P> friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v); \
template<typename P> friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v);
#define BINARY_STREAM_FRIEND(T) \
template<typename P> \
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v); \
template<typename P> \
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v);
#define BINARY_STREAM_WRITE(T) \
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v)
template<typename P> \
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v)
#define BINARY_STREAM_READ(T) \
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v)
template<typename P> \
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v)
//! \ingroup Serialization
@@ -63,7 +67,7 @@ class PIBinaryStream {
public:
//! \~russian Записать данные
bool binaryStreamAppend(const void * d, size_t s) {
if (!static_cast<P*>(this)->binaryStreamAppendImp(d, s)) {
if (!static_cast<P *>(this)->binaryStreamAppendImp(d, s)) {
return false;
printf("[PIBinaryStream] binaryStreamAppend() error\n");
}
@@ -71,7 +75,7 @@ public:
}
//! \~russian Прочитать данные
bool binaryStreamTake(void * d, size_t s) {
if (!static_cast<P*>(this)->binaryStreamTakeImp(d, s)) {
if (!static_cast<P *>(this)->binaryStreamTakeImp(d, s)) {
return false;
printf("[PIBinaryStream] binaryStreamTake() error\n");
}
@@ -81,13 +85,13 @@ public:
//! \~russian Узнать оставшийся размер
//!\~\details
//!\~russian Возвращает -1 если нет информации о размере
ssize_t binaryStreamSize() const {
return static_cast<const P*>(this)->binaryStreamSizeImp();
}
ssize_t binaryStreamSize() const { return static_cast<const P *>(this)->binaryStreamSizeImp(); }
//! \~russian Записать данные
template<typename T>
void binaryStreamAppend(T v) {binaryStreamAppend(&v, sizeof(v));}
void binaryStreamAppend(T v) {
binaryStreamAppend(&v, sizeof(v));
}
//! \~russian Прочитать int
int binaryStreamTakeInt() {
@@ -107,65 +111,71 @@ public:
};
template<typename P, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStreamTrivialRef<P> s, const T & v) {
template<typename P, typename T>
inline PIBinaryStream<P> & operator<<(PIBinaryStreamTrivialRef<P> s, const T & v) {
s.p << v;
return s.p;
}
template<typename P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStreamTrivialRef<P> s, T & v) {
template<typename P, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStreamTrivialRef<P> s, T & v) {
s.p >> v;
return s.p;
}
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStreamTrivialRef<P> s, const PIMemoryBlock v) {
template<typename P>
inline PIBinaryStream<P> & operator<<(PIBinaryStreamTrivialRef<P> s, const PIMemoryBlock v) {
s.p << v;
return s.p;
}
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStreamTrivialRef<P> s, PIMemoryBlock v) {
template<typename P>
inline PIBinaryStream<P> & operator>>(PIBinaryStreamTrivialRef<P> s, PIMemoryBlock v) {
s.p >> v;
return s.p;
}
// specify types
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const bool v) {
template<typename P>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const bool v) {
s.binaryStreamAppend((uchar)v);
return s;
}
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, bool & v) {
template<typename P>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, bool & v) {
uchar c;
s.binaryStreamTake(&c, sizeof(c));
v = c;
return s;
}
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMemoryBlock v) {
template<typename P>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMemoryBlock v) {
s.binaryStreamAppend(v.data(), v.size());
return s;
}
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMemoryBlock v) {
template<typename P>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMemoryBlock v) {
s.binaryStreamTake(v.data(), v.size());
return s;
}
// store simple types
template<typename P, typename T,
typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & v) {
//piCout << "<< enum";
template<typename P, typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v) {
// piCout << "<< enum";
s.binaryStreamAppend((int)v);
return s;
}
template<typename P, typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStreamTrivialRef<P> operator <<(PIBinaryStream<P> & s, const T & v) {
template<typename P,
typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStreamTrivialRef<P> operator<<(PIBinaryStream<P> & s, const T & v) {
s.binaryStreamAppend(&v, sizeof(v));
return s;
}
@@ -173,65 +183,85 @@ inline PIBinaryStreamTrivialRef<P> operator <<(PIBinaryStream<P> & s, const T &
//! \~english Store operator for PIVector of any trivial copyable type
//! \~russian Оператор сохранения для PIVector тривиальных типов
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
//piCout << "<< vector trivial default";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector<T> & v) {
// piCout << "<< vector trivial default";
s.binaryStreamAppend((int)v.size());
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
return s;
}
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
//piCout << "<< vector trivial custom";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector<T> & v) {
// piCout << "<< vector trivial custom";
s.binaryStreamAppend((int)v.size());
for (size_t i = 0; i < v.size(); ++i) s << v[i];
for (size_t i = 0; i < v.size(); ++i)
s << v[i];
return s;
}
//! \~english Store operator for PIDeque of any trivial copyable type
//! \~russian Оператор сохранения для PIDeque тривиальных типов
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
//piCout << "<< deque trivial default";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
// piCout << "<< deque trivial default";
s.binaryStreamAppend((int)v.size());
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
return s;
}
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
//piCout << "<< deque trivial custom";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
// piCout << "<< deque trivial custom";
s.binaryStreamAppend((int)v.size());
for (size_t i = 0; i < v.size(); ++i) s << v[i];
for (size_t i = 0; i < v.size(); ++i)
s << v[i];
return s;
}
//! \~english Store operator for PIVector2D of any trivial copyable type
//! \~russian Оператор сохранения для PIVector2D тривиальных типов
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
//piCout << "<< vector2d trivial default";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
// piCout << "<< vector2d trivial default";
s.binaryStreamAppend((int)v.rows());
s.binaryStreamAppend((int)v.cols());
s.binaryStreamAppend(v.data(), v.size() * sizeof(T));
return s;
}
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
//piCout << "<< vector2d trivial custom";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() << std::declval<const T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
// piCout << "<< vector2d trivial custom";
s.binaryStreamAppend((int)v.rows());
s.binaryStreamAppend((int)v.cols());
s << v.toPlainVector();
@@ -242,33 +272,37 @@ inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T
//! \~english Store operator
//! \~russian Оператор сохранения
template<typename P>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;}
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIBitArray & v) {
s << v.size_ << v.data_;
return s;
}
//! \~english Store operator
//! \~russian Оператор сохранения
template<typename P, typename Type0, typename Type1>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIPair<Type0, Type1> & v) {s << v.first << v.second; return s;}
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIPair<Type0, Type1> & v) {
s << v.first << v.second;
return s;
}
// restore simple types
template<typename P, typename T,
typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & v) {
//piCout << ">> enum";
template<typename P, typename T, typename std::enable_if<std::is_enum<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v) {
// piCout << ">> enum";
v = (T)s.binaryStreamTakeInt();
return s;
}
template<typename P, typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStreamTrivialRef<P> operator >>(PIBinaryStream<P> & s, T & v) {
template<typename P,
typename T,
typename std::enable_if<!std::is_enum<T>::value, int>::type = 0,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStreamTrivialRef<P> operator>>(PIBinaryStream<P> & s, T & v) {
if (!s.binaryStreamTake(&v, sizeof(v))) {
printf("error with %s\n", __PIP_TYPENAME__(T));
assert(false);
@@ -279,11 +313,14 @@ inline PIBinaryStreamTrivialRef<P> operator >>(PIBinaryStream<P> & s, T & v) {
//! \~english Restore operator for PIVector of any trivial copyable type
//! \~russian Оператор извлечения для PIVector тривиальных типов
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
//piCout << ">> vector trivial default";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial default";
int sz = s.binaryStreamTakeInt();
v._resizeRaw(sz);
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
@@ -292,25 +329,32 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
}
return s;
}
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
//piCout << ">> vector trivial custom";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial custom";
int sz = s.binaryStreamTakeInt();
v._resizeRaw(sz);
for (int i = 0; i < sz; ++i) s >> v[i];
for (int i = 0; i < sz; ++i)
s >> v[i];
return s;
}
//! \~english Restore operator for PIDeque of any trivial copyable type
//! \~russian Оператор извлечения для PIDeque тривиальных типов
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
//piCout << ">> deque trivial default";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial default";
int sz = s.binaryStreamTakeInt();
v._resizeRaw(sz);
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
@@ -319,25 +363,32 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
}
return s;
}
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
//piCout << ">> deque trivial custom";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial custom";
int sz = s.binaryStreamTakeInt();
v._resizeRaw(sz);
for (int i = 0; i < sz; ++i) s >> v[i];
for (int i = 0; i < sz; ++i)
s >> v[i];
return s;
}
//! \~english Restore operator for PIVector2D of any trivial copyable type
//! \~russian Оператор извлечения для PIVector2D тривиальных типов
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if< std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
//piCout << ">> vector2d trivial default";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
// piCout << ">> vector2d trivial default";
int r, c;
r = s.binaryStreamTakeInt();
c = s.binaryStreamTakeInt();
@@ -348,11 +399,14 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v)
}
return s;
}
template<typename P, typename T,
typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<!std::is_same<decltype(std::declval<PIBinaryStream<P>&>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
//piCout << ">> vector2d trivial custom";
template<typename P,
typename T,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0,
typename std::enable_if<
!std::is_same<decltype(std::declval<PIBinaryStream<P> &>() >> std::declval<T &>()), PIBinaryStreamTrivialRef<P>>::value,
int>::type = 0>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
// piCout << ">> vector2d trivial custom";
int r, c;
PIVector<T> tmp;
r = s.binaryStreamTakeInt();
@@ -366,15 +420,19 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v)
//! \~english Restore operator
//! \~russian Оператор извлечения
template<typename P>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIBitArray & v) {s >> v.size_ >> v.data_; return s;}
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIBitArray & v) {
s >> v.size_ >> v.data_;
return s;
}
//! \~english Restore operator
//! \~russian Оператор извлечения
template<typename P, typename Type0, typename Type1>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIPair<Type0, Type1> & v) {s >> v.first >> v.second; return s;}
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIPair<Type0, Type1> & v) {
s >> v.first >> v.second;
return s;
}
// store complex types
@@ -383,10 +441,11 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIPair<Type0, Type
//! \~english Store operator for PIVector of any compound type
//! \~russian Оператор сохранения для PIVector сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
//piCout << "<< vector complex";
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector<T> & v) {
// piCout << "<< vector complex";
s.binaryStreamAppend(int(v.size_s()));
for (size_t i = 0; i < v.size(); ++i) s << v[i];
for (size_t i = 0; i < v.size(); ++i)
s << v[i];
return s;
}
@@ -394,10 +453,11 @@ inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T>
//! \~english Store operator for PIDeque of any compound type
//! \~russian Оператор сохранения для PIDeque сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
//piCout << "<< deque complex";
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
// piCout << "<< deque complex";
s.binaryStreamAppend(int(v.size_s()));
for (size_t i = 0; i < v.size(); ++i) s << v[i];
for (size_t i = 0; i < v.size(); ++i)
s << v[i];
return s;
}
@@ -405,8 +465,8 @@ inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> &
//! \~english Store operator for PIVector2D of any compound type
//! \~russian Оператор сохранения для PIVector2D сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
//piCout << "<< vector2d complex";
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
// piCout << "<< vector2d complex";
s.binaryStreamAppend(int(v.rows()));
s.binaryStreamAppend(int(v.cols()));
s << v.toPlainVector();
@@ -414,22 +474,21 @@ inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T
}
// restore complex types
//! \~english Restore operator for PIVector of any compound type
//! \~russian Оператор извлечения для PIVector сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
//piCout << ">> vector complex";
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector complex";
/*if (s.size_s() < 4) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}*/
v.resize(s.binaryStreamTakeInt());
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
for (size_t i = 0; i < v.size(); ++i)
s >> v[i];
return s;
}
@@ -437,14 +496,15 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
//! \~english Restore operator for PIDeque of any compound type
//! \~russian Оператор извлечения для PIDeque сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
//piCout << ">> deque complex";
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque complex";
/*if (s.size_s() < 4) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}*/
v.resize(s.binaryStreamTakeInt());
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
for (size_t i = 0; i < v.size(); ++i)
s >> v[i];
return s;
}
@@ -452,11 +512,11 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
//! \~english Restore operator for PIVector2D of any compound type
//! \~russian Оператор извлечения для PIVector2D сложных типов
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
//piCout << ">> vector2d complex";
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
// piCout << ">> vector2d complex";
/*if (s.size_s() < 8) {
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 8);
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
assert(s.size_s() >= 8);
}*/
int r, c;
PIVector<T> tmp;
@@ -468,15 +528,13 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v)
}
// other types
//! \~english Store operator
//! \~russian Оператор сохранения
template <typename P, typename Key, typename T>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMap<Key, T> & v) {
template<typename P, typename Key, typename T>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMap<Key, T> & v) {
s.binaryStreamAppend((int)v.pim_index.size_s());
for (uint i = 0; i < v.size(); ++i) {
s.binaryStreamAppend((int)v.pim_index[i].index);
@@ -489,13 +547,14 @@ inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMap<Key, T
//! \~english Restore operator
//! \~russian Оператор извлечения
template <typename P, typename Key, typename T>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
template<typename P, typename Key, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
/*if (s.size_s() < 4) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
assert(s.size_s() >= 4);
}*/
int sz = s.binaryStreamTakeInt(); v.pim_index.resize(sz);
int sz = s.binaryStreamTakeInt();
v.pim_index.resize(sz);
int ind = 0;
for (int i = 0; i < sz; ++i) {
ind = s.binaryStreamTakeInt();
@@ -511,24 +570,20 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMap<Key, T> & v)
}
// non-defined complex types
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const T & ) {
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T &) {
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator << for complex type!");
return s;
}
template<typename P, typename T, typename std::enable_if<!std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, T & ) {
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T &) {
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator >> for complex type!");
return s;
}
#endif

View File

@@ -1,20 +1,20 @@
/*
PIP - Platform Independent Primitives
Binary markup serializator
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
Binary markup serializator
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 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.
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/>.
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/>.
*/
#include "pichunkstream.h"
@@ -87,7 +87,7 @@
void PIChunkStream::setSource(const PIByteArray & data) {
data_ = const_cast<PIByteArray*>(&data);
data_ = const_cast<PIByteArray *>(&data);
_init();
}
@@ -110,13 +110,11 @@ PIByteArray PIChunkStream::data() const {
int PIChunkStream::read() {
switch (version_) {
case Version_1:
(*data_) >> last_id >> last_data;
break;
case Version_1: (*data_) >> last_id >> last_data; break;
case Version_2:
last_id = readVInt(*data_);
last_data.resize(readVInt(*data_));
//piCout << last_id << last_data.size();
// piCout << last_id << last_data.size();
(*data_) >> PIMemoryBlock(last_data.data(), last_data.size_s());
break;
default: break;
@@ -127,16 +125,14 @@ int PIChunkStream::read() {
int PIChunkStream::peekVInt(Version version_, uchar * data_, int sz, uint & ret) {
switch (version_) {
case Version_1:
memcpy(&ret, data_, 4);
return 4;
case Version_1: memcpy(&ret, data_, 4); return 4;
case Version_2: {
PIByteArray hdr(data_, piMini(4, sz));
hdr.resize(4);
uchar hsz = 0;
ret = readVInt(hdr, &hsz);
ret = readVInt(hdr, &hsz);
return hsz;
}
}
default: break;
}
return 0;
@@ -149,7 +145,7 @@ void PIChunkStream::replaceChunk(int id, const PIByteArray & v) {
PIByteArray nsba;
writeVInt(nsba, v.size());
int size_mod = (v.size_s() + nsba.size_s()) - (pos.length + pos.size_bytes);
pos.length = v.size_s();
pos.length = v.size_s();
if (size_mod != 0) {
auto it = data_map.makeIterator();
while (it.next()) {
@@ -176,7 +172,7 @@ void PIChunkStream::readAll() {
uint csz = 0, cid = 0;
while (pos < sz) {
pos += peekVInt((Version)version_, data_->data(pos), data_->size_s() - pos, cid);
hsz = peekVInt((Version)version_, data_->data(pos), data_->size_s() - pos, csz);
hsz = peekVInt((Version)version_, data_->data(pos), data_->size_s() - pos, csz);
pos += hsz;
data_map[cid] = CacheEntry(pos, csz, hsz);
pos += csz;
@@ -184,8 +180,7 @@ void PIChunkStream::readAll() {
}
PIChunkStream::~PIChunkStream() {
}
PIChunkStream::~PIChunkStream() {}
bool PIChunkStream::extract(PIByteArray & data, bool read_all) {
@@ -201,7 +196,7 @@ bool PIChunkStream::extract(PIByteArray & data, bool read_all) {
void PIChunkStream::_init() {
first_byte_taken = false;
last_id = -1;
last_id = -1;
last_data.clear();
if (!data_->isEmpty()) {
uchar v = data_->at(0);
@@ -212,10 +207,8 @@ void PIChunkStream::_init() {
version_ = (uchar)Version_2;
data_->pop_front();
first_byte_taken = true;
break;
default:
version_ = Version_1;
break;
break;
default: version_ = Version_1; break;
}
} else {
version_ = Version_1;
@@ -234,7 +227,8 @@ uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) {
if ((bytes[0] & mask) == mask) {
bytes[0] &= (mask - 1);
s >> bytes[abc + 1];
} else break;
} else
break;
}
if (bytes_cnt) *bytes_cnt = (abc + 1);
uint ret = 0;

View File

@@ -3,24 +3,24 @@
* \~\brief
* \~english Binary markup de/serializator stream
* \~russian Бинарный поток для де/сериализации с разметкой
*/
*/
/*
PIP - Platform Independent Primitives
Binary markup serializator
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
Binary markup serializator
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 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.
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/>.
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 PICHUNKSTREAM_H
@@ -33,10 +33,8 @@
//! \~\brief
//! \~english Class for binary de/serialization.
//! \~russian Класс для бинарной де/сериализации.
class PIP_EXPORT PIChunkStream
{
class PIP_EXPORT PIChunkStream {
public:
//! \~english
//! Version of data packing. Read-access %PIChunkStream automatic detect version, but write-access
//! %PIChunkStream by default write in new version, be careful!
@@ -50,38 +48,45 @@ public:
//! \~english Contructs stream for read from "data"
//! \~russian Создает поток на чтение из "data"
PIChunkStream(const PIByteArray & data): version_(Version_2) {setSource(data);}
PIChunkStream(const PIByteArray & data): version_(Version_2) { setSource(data); }
//! \~english Contructs stream for read or write to/from "data", or empty stream for write if "data" = 0
//! \~russian Создает поток на чтение или запись из/в "data", или пустой поток на запись если "data" = 0
PIChunkStream(PIByteArray * data = 0, Version v = Version_2): version_(v) {setSource(data);}
PIChunkStream(PIByteArray * data = 0, Version v = Version_2): version_(v) { setSource(data); }
//! \~english Contructs empty stream for write with version \"v\"
//! \~russian Создает пустой поток на запись с версией \"v\"
PIChunkStream(Version v): version_(v) {setSource(0);}
PIChunkStream(Version v): version_(v) { setSource(0); }
~PIChunkStream();
template <typename T>
template<typename T>
struct Chunk {
Chunk(int i, const T & d): id(i), data(d) {}
int id;
T data;
};
template <typename T>
template<typename T>
struct ChunkConst {
ChunkConst(int i, const T & d): id(i), data(d) {}
int id;
const T & data;
};
//! \~english Returns chunk with ID "id" and value "data" for write to stream
//! \~russian Возвращает чанк с ID "id" и значением "data" для записи в поток
template <typename T> static ChunkConst<T> chunk(int id, const T & data) {return ChunkConst<T>(id, data);}
template<typename T>
static ChunkConst<T> chunk(int id, const T & data) {
return ChunkConst<T>(id, data);
}
//! \~english Add to this stream chunk with ID "id" and value "data"
//! \~russian Добавляет в этот поток чанк с ID "id" и значением "data"
template <typename T> PIChunkStream & add(int id, const T & data) {*this << ChunkConst<T>(id, data); return *this;}
template<typename T>
PIChunkStream & add(int id, const T & data) {
*this << ChunkConst<T>(id, data);
return *this;
}
//! \~english
//! Extract %PIByteArray from "data" and set it current stream.
@@ -95,19 +100,19 @@ public:
void setSource(const PIByteArray & data);
void setSource(PIByteArray * data);
//! \~english Returns internal buffer with written data
//! \~russian Возвращает внутренний буфер с записанными данными
PIByteArray data() const;
//! \~english Returns if there is end of stream
//! \~russian Возвращает достигнут ли конец потока
bool atEnd() const {return data_->size_s() <= 1;}
bool atEnd() const { return data_->size_s() <= 1; }
//! \~english Returns stream version
//! \~russian Возвращает версию потока
Version version() const {return (Version)version_;}
Version version() const { return (Version)version_; }
//! \~english Read one chunk from stream and returns its ID
//! \~russian Читает один чанк из потока и возвращает его ID
@@ -116,36 +121,42 @@ public:
//! \~english Read all chunks from stream. This function just index input data
//! \~russian Читает все чанки из потока. Данный метод лишь индексирует данные
void readAll();
//! \~english Returns last readed chunk ID
//! \~russian Возвращает ID последнего прочитанного чанка
int getID() {return last_id;}
int getID() { return last_id; }
//! \~english Returns value of last readed chunk
//! \~russian Возвращает значение последнего прочитанного чанка
template <typename T>
T getData() const {T ret{}; PIByteArray s(last_data); s >> ret; return ret;}
template<typename T>
T getData() const {
T ret{};
PIByteArray s(last_data);
s >> ret;
return ret;
}
//! \~english Place value of last readed chunk into \"v\"
//! \~russian Записывает значение последнего прочитанного чанка в \"v\"
template <typename T>
void get(T & v) const {v = getData<T>();}
template<typename T>
void get(T & v) const {
v = getData<T>();
}
//! \~english Place value of chunk with ID \"id\" into \"v\". You should call \a readAll() before using this function!
//! \~russian Записывает значение чанка с ID \"id\" в \"v\". Необходимо вызвать \a readAll() перед использованием этого метода!
template <typename T>
template<typename T>
const PIChunkStream & get(int id, T & v) const {
CacheEntry pos = data_map.value(id);
if (pos.start < 0 || pos.length == 0) return *this;
PIByteArray ba(data_->data(pos.start), pos.length);
if (!ba.isEmpty())
ba >> v;
if (!ba.isEmpty()) ba >> v;
return *this;
}
//! \~english Replace value of chunk with ID \"id\" to \"v\". You should call \a readAll() before using this function!
//! \~russian Заменяет значение чанка с ID \"id\" на \"v\". Необходимо вызвать \a readAll() перед использованием этого метода!
template <typename T>
template<typename T>
PIChunkStream & set(int id, const T & v) {
PIByteArray ba;
ba << v;
@@ -162,7 +173,7 @@ private:
int length;
int size_bytes;
};
static uint readVInt(PIByteArray & s, uchar * bytes = 0);
static void writeVInt(PIByteArray & s, uint val);
static int peekVInt(Version version_, uchar * data_, int sz, uint & ret);
@@ -170,25 +181,24 @@ private:
int last_id;
uchar version_;
mutable PIByteArray * data_, last_data, tmp_data;
mutable PIByteArray *data_, last_data, tmp_data;
PIMap<int, CacheEntry> data_map;
bool first_byte_taken;
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);
template<typename T>
friend PIChunkStream & operator<<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
template<typename T>
friend PIChunkStream & operator<<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);
};
template <typename T>
PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c) {
template<typename T>
PIChunkStream & operator<<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c) {
PIByteArray ba;
ba << c.data;
switch (s.version_) {
case PIChunkStream::Version_1:
(*(s.data_)) << c.id << ba;
break;
case PIChunkStream::Version_1: (*(s.data_)) << c.id << ba; break;
case PIChunkStream::Version_2:
if (s.data_->isEmpty())
(*(s.data_)) << uchar(uchar(s.version_) | 0x80);
if (s.data_->isEmpty()) (*(s.data_)) << uchar(uchar(s.version_) | 0x80);
PIChunkStream::writeVInt(*(s.data_), c.id);
PIChunkStream::writeVInt(*(s.data_), ba.size());
s.data_->append(ba);
@@ -197,17 +207,14 @@ PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c
}
return s;
}
template <typename T>
PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c) {
template<typename T>
PIChunkStream & operator<<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c) {
PIByteArray ba;
ba << c.data;
switch (s.version_) {
case PIChunkStream::Version_1:
(*(s.data_)) << c.id << ba;
break;
case PIChunkStream::Version_1: (*(s.data_)) << c.id << ba; break;
case PIChunkStream::Version_2:
if (s.data_->isEmpty())
(*(s.data_)) << uchar(uchar(s.version_) | 0x80);
if (s.data_->isEmpty()) (*(s.data_)) << uchar(uchar(s.version_) | 0x80);
PIChunkStream::writeVInt(*(s.data_), c.id);
PIChunkStream::writeVInt(*(s.data_), ba.size());
s.data_->append(ba);

View File

@@ -1,20 +1,20 @@
/*
PIP - Platform Independent Primitives
JSON class
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
JSON class
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 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.
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/>.
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/>.
*/
#include "pijson.h"
@@ -275,7 +275,7 @@ void PIJSON::setValue(const PIVariant & v) {
void PIJSON::clear() {
c_type = Invalid;
c_type = Invalid;
c_value = PIVariant();
c_name.clear();
c_object.clear();
@@ -326,10 +326,10 @@ PIJSON & PIJSON::operator<<(const PIJSON & element) {
PIJSON & PIJSON::operator=(const PIJSON & v) {
c_type = v.c_type;
c_value = v.c_value;
c_type = v.c_type;
c_value = v.c_value;
c_object = v.c_object;
c_array = v.c_array;
c_array = v.c_array;
return *this;
}
@@ -369,7 +369,7 @@ PIJSON & PIJSON::nullEntry() {
PIString PIJSON::parseName(PIString & s) {
//piCout << "\n\n\n parseName" << s;
// piCout << "\n\n\n parseName" << s;
PIString ret;
ret = s.takeRange('"', '"');
s.trim();
@@ -382,7 +382,7 @@ PIString PIJSON::parseName(PIString & s) {
PIJSON PIJSON::parseValue(PIString & s) {
PIJSON ret;
//piCout << "\n\n\n parseValue" << s;
// piCout << "\n\n\n parseValue" << s;
s.trim();
if (s.isEmpty()) return ret;
if (s[0] == '{') {
@@ -392,7 +392,7 @@ PIJSON PIJSON::parseValue(PIString & s) {
} else {
s.trim();
if (s.startsWith('"')) {
ret.c_type = PIJSON::String;
ret.c_type = PIJSON::String;
ret.c_value = PIJSON::stringUnmask(s.takeRange('"', '"'));
} else {
PIString value;
@@ -403,17 +403,17 @@ PIJSON PIJSON::parseValue(PIString & s) {
value = s;
s.clear();
}
//piCout << "\n\n\n parseValue value = \"" << value << "\"";
// piCout << "\n\n\n parseValue value = \"" << value << "\"";
if (value == "null") {
ret.c_type = PIJSON::Null;
} else if (value == "true") {
ret.c_type = PIJSON::Boolean;
ret.c_type = PIJSON::Boolean;
ret.c_value = true;
} else if (value == "false") {
ret.c_type = PIJSON::Boolean;
ret.c_type = PIJSON::Boolean;
ret.c_value = false;
} else {
ret.c_type = PIJSON::Number;
ret.c_type = PIJSON::Number;
ret.c_value = value;
}
}
@@ -423,14 +423,14 @@ PIJSON PIJSON::parseValue(PIString & s) {
PIJSON PIJSON::parseObject(PIString s) {
//piCout << "\n\n\n parseObject" << s;
// piCout << "\n\n\n parseObject" << s;
PIJSON ret;
ret.c_type = PIJSON::Object;
while (s.isNotEmpty()) {
PIString name = PIJSON::stringUnmask(parseName(s));
PIJSON value = parseValue(s);
PIJSON value = parseValue(s);
auto & child(ret.c_object[name]);
child = value;
child = value;
child.c_name = name;
s.trim();
if (s.isEmpty()) break;
@@ -442,7 +442,7 @@ PIJSON PIJSON::parseObject(PIString s) {
PIJSON PIJSON::parseArray(PIString s) {
//piCout << "\n\n\n parseArray" << s;
// piCout << "\n\n\n parseArray" << s;
PIJSON ret;
ret.c_type = PIJSON::Array;
while (s.isNotEmpty()) {
@@ -468,14 +468,14 @@ PIString PIJSON::stringMask(const PIString & s, bool mask_unicode) {
} else {
char ca = c.toAscii();
switch (ca) {
case '"' : ret += "\\\""; break;
case '"': ret += "\\\""; break;
case '\\': ret += "\\\\"; break;
case '/' : ret += "\\/" ; break;
case '\b': ret += "\\b" ; break;
case '\f': ret += "\\f" ; break;
case '\n': ret += "\\n" ; break;
case '\r': ret += "\\r" ; break;
case '\t': ret += "\\t" ; break;
case '/': ret += "\\/"; break;
case '\b': ret += "\\b"; break;
case '\f': ret += "\\f"; break;
case '\n': ret += "\\n"; break;
case '\r': ret += "\\r"; break;
case '\t': ret += "\\t"; break;
default: ret += ca;
}
}
@@ -493,15 +493,15 @@ PIString PIJSON::stringUnmask(const PIString & s) {
++i;
char na = s[i].toAscii();
switch (na) {
case '"' : ret += '\"'; break;
case '"': ret += '\"'; break;
case '\\': ret += '\\'; break;
case '/' : ret += '/' ; break;
case 'b' : ret += '\b'; break;
case 'f' : ret += '\f'; break;
case 'n' : ret += '\n'; break;
case 'r' : ret += '\r'; break;
case 't' : ret += '\t'; break;
case 'u' :
case '/': ret += '/'; break;
case 'b': ret += '\b'; break;
case 'f': ret += '\f'; break;
case 'n': ret += '\n'; break;
case 'r': ret += '\r'; break;
case 't': ret += '\t'; break;
case 'u':
ret += PIChar(s.mid(i + 1, 4).toUShort(16));
i += 4;
break;
@@ -517,17 +517,17 @@ PIString PIJSON::stringUnmask(const PIString & s) {
void PIJSON::print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bool transform, bool comma, bool mask_unicode) {
if (spaces) s += tab;
/*
switch (v.c_type) {
case JSONEntry::Invalid: s << "(Invalid)"; break;
case JSONEntry::Null: s << "(Null)"; break;
case JSONEntry::Boolean: s << "(Boolean)"; break;
case JSONEntry::Number: s << "(Number)"; break;
case JSONEntry::String: s << "(String)"; break;
case JSONEntry::Object: s << "(Object)"; break;
case JSONEntry::Array: s << "(Array)"; break;
}
*/
/*
switch (v.c_type) {
case JSONEntry::Invalid: s << "(Invalid)"; break;
case JSONEntry::Null: s << "(Null)"; break;
case JSONEntry::Boolean: s << "(Boolean)"; break;
case JSONEntry::Number: s << "(Number)"; break;
case JSONEntry::String: s << "(String)"; break;
case JSONEntry::Object: s << "(Object)"; break;
case JSONEntry::Array: s << "(Array)"; break;
}
*/
if (v.name().isNotEmpty()) {
s += '"' + (transform ? stringMask(v.name(), mask_unicode) : v.name()) + "\":";
if (spaces) s += ' ';
@@ -543,8 +543,8 @@ void PIJSON::print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bo
if (spaces) s += '\n';
{
PIString ntab = tab + " ";
auto it = v.c_object.makeIterator();
int cnt = 0;
auto it = v.c_object.makeIterator();
int cnt = 0;
while (it.next()) {
print(s, it.value(), ntab, spaces, transform, ++cnt < v.c_object.size_s(), mask_unicode);
}

View File

@@ -3,24 +3,24 @@
* \brief
* \~english JSON class
* \~russian Класс JSON
*/
*/
/*
PIP - Platform Independent Primitives
JSON class
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
JSON class
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 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.
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/>.
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 PIJSON_H
@@ -34,21 +34,21 @@
//! \~english JSON class.
//! \~russian Класс JSON.
class PIP_EXPORT PIJSON {
friend PICout operator <<(PICout s, const PIJSON & v);
public:
friend PICout operator<<(PICout s, const PIJSON & v);
public:
//! \~english
//! Type of JSON tree element
//! \~russian
//! Тип элемента дерева JSON
enum Type {
Invalid /*! \~english Invalid type \~russian Недействительный тип */,
Null /*! \~english Without value, null \~russian Без значения, null */,
Null /*! \~english Without value, null \~russian Без значения, null */,
Boolean /*! \~english Boolean, /b true or /b false \~russian Логическое, /b true или /b false */,
Number /*! \~english Integer or floating-point number \~russian Целое либо число с плавающей точкой */,
String /*! \~english Text \~russian Текст */,
Object /*! \~english Object, {} \~russian Объект, {} */,
Array /*! \~english Array, [] \~russian Массив, [] */
Number /*! \~english Integer or floating-point number \~russian Целое либо число с плавающей точкой */,
String /*! \~english Text \~russian Текст */,
Object /*! \~english Object, {} \~russian Объект, {} */,
Array /*! \~english Array, [] \~russian Массив, [] */
};
//! \~english
@@ -57,7 +57,7 @@ public:
//! Вариант генерации JSON
enum PrintType {
Compact /*! \~english Without spaces, minimum size \~russian Без пробелов, минимальный размер */,
Tree /*! \~english With spaces and new-lines, human-readable \~russian С пробелами и новыми строками, читаемый человеком */
Tree /*! \~english With spaces and new-lines, human-readable \~russian С пробелами и новыми строками, читаемый человеком */
};
//! \~english Contructs invalid %PIJSON.
@@ -67,7 +67,7 @@ public:
//! \~english Returns name of element, or empty string if it doesn`t have name.
//! \~russian Возвращает имя элемента, либо пустую строку, если имени нет.
const PIString & name() const {return c_name;}
const PIString & name() const { return c_name; }
//! \~english Returns elements array of this element, or empty array if element is not \a PIJSON::Array.
//! \~russian Возвращает массив элементов этого элемента, либо пустой массив, если тип элемента не \a PIJSON::Array.
@@ -79,40 +79,40 @@ public:
//! \~english Returns element value.
//! \~russian Возвращает значение элемента.
const PIVariant & value() const {return c_value;}
const PIVariant & value() const { return c_value; }
//! \~english Returns element value as bool.
//! \~russian Возвращает значение элемента как логическое.
bool toBool() const {return c_value.toBool();}
bool toBool() const { return c_value.toBool(); }
//! \~english Returns element value as integer number.
//! \~russian Возвращает значение элемента как целое число.
int toInt() const {return c_value.toInt();}
int toInt() const { return c_value.toInt(); }
//! \~english Returns element value as floating-point number.
//! \~russian Возвращает значение элемента как число с плавающей точкой.
double toDouble() const {return c_value.toDouble();}
double toDouble() const { return c_value.toDouble(); }
//! \~english Returns element value as string, valid for all types.
//! \~russian Возвращает значение элемента как строка, действительно для всех типов.
PIString toString() const {return c_value.toString();}
PIString toString() const { return c_value.toString(); }
//! \~english Returns element type.
//! \~russian Возвращает тип элемента.
Type type() const {return c_type;}
Type type() const { return c_type; }
//! \~english Returns if element is valid.
//! \~russian Возвращает действителен ли элемент.
bool isValid() const {return c_type != Invalid;}
bool isValid() const { return c_type != Invalid; }
//! \~english Returns if element is \a PIJSON::Object.
//! \~russian Возвращает является ли элемент \a PIJSON::Object.
bool isObject() const {return c_type == Object;}
bool isObject() const { return c_type == Object; }
//! \~english Returns if element is \a PIJSON::Array.
//! \~russian Возвращает является ли элемент \a PIJSON::Array.
bool isArray() const {return c_type == Array;}
bool isArray() const { return c_type == Array; }
//! \~english Set value and type of element from "v".
//! \~russian Устанавливает значение и тип элемента из "v".
@@ -122,8 +122,10 @@ public:
//! \~russian Очищает элемент и устанавливает его в \a PIJSON::Invalid.
void clear();
//! \~english Returns size of elements array if type is \a PIJSON::Array, size of elements map if type is \a PIJSON::Object, otherwise returns 0.
//! \~russian Возвращает размер массива элементов если тип \a PIJSON::Array, размер словаря элементов если тип \a PIJSON::Object, иначе возвращает 0.
//! \~english Returns size of elements array if type is \a PIJSON::Array, size of elements map if type is \a PIJSON::Object, otherwise
//! returns 0.
//! \~russian Возвращает размер массива элементов если тип \a PIJSON::Array, размер словаря элементов если тип \a PIJSON::Object, иначе
//! возвращает 0.
int size() const;
//! \~english Returns if elements map contains key "key" if type is \a PIJSON::Object, otherwise returns \b false.
@@ -137,7 +139,10 @@ public:
//! \~english Synonim of \a setValue().
//! \~russian Аналог \a setValue().
PIJSON & operator=(const PIVariant & v) {setValue(v); return *this;}
PIJSON & operator=(const PIVariant & v) {
setValue(v);
return *this;
}
PIJSON & operator=(const PIJSON & v);
@@ -147,24 +152,27 @@ public:
const PIJSON & operator[](int index) const;
//! \~english Set element type to \a PIJSON::Array, resize if necessary and returns element from array with index "index".
//! \~russian Устанавливает тип элемента в \a PIJSON::Array, изменяет размер массива при неоходимости и возвращает элемент из массива по индексу "index".
//! \~russian Устанавливает тип элемента в \a PIJSON::Array, изменяет размер массива при неоходимости и возвращает элемент из массива по
//! индексу "index".
PIJSON & operator[](int index);
//! \~english Set element type to \a PIJSON::Array and add element to the end of array.
//! \~russian Устанавливает тип элемента в \a PIJSON::Array и добавляет элемент в массив.
PIJSON & operator <<(const PIJSON & element);
PIJSON & operator<<(const PIJSON & element);
//! \~english Returns element from map with key "key" if type is \a PIJSON::Object, otherwise returns invalid %PIJSON.
//! \~russian Возвращает элемент из словаря по ключу "key" если тип \a PIJSON::Object, иначе возвращает недействительный %PIJSON.
PIJSON operator[](const PIString & key) const;
//! \~english Set element type to \a PIJSON::Object and returns element from map with key "key". If element with this key doesn`t exists, it will be created.
//! \~russian Устанавливает тип элемента в \a PIJSON::Object и возвращает элемент из словаря по ключу "key". Если элемента с таким ключом не существует, он будет создан.
//! \~english Set element type to \a PIJSON::Object and returns element from map with key "key". If element with this key doesn`t
//! exists, it will be created.
//! \~russian Устанавливает тип элемента в \a PIJSON::Object и возвращает элемент из словаря по ключу "key". Если элемента с таким
//! ключом не существует, он будет создан.
PIJSON & operator[](const PIString & key);
PIJSON operator[](const char * key) const {return (*this)[PIString::fromUTF8(key)];}
PIJSON & operator[](const char * key) {return (*this)[PIString::fromUTF8(key)];}
PIJSON operator[](const char * key) const { return (*this)[PIString::fromUTF8(key)]; }
PIJSON & operator[](const char * key) { return (*this)[PIString::fromUTF8(key)]; }
//! \~english Returns text representation of JSON tree.
@@ -187,7 +195,8 @@ private:
static PIJSON parseArray(PIString s);
static PIString stringMask(const PIString & s, bool mask_unicode);
static PIString stringUnmask(const PIString & s);
static void print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bool transform = false, bool comma = false, bool mask_unicode = true);
static void
print(PIString & s, const PIJSON & v, PIString tab, bool spaces, bool transform = false, bool comma = false, bool mask_unicode = true);
PIString c_name;
PIVariant c_value;
@@ -197,11 +206,10 @@ private:
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout.
//! \~russian Оператор вывода в \a PICout.
inline PICout operator <<(PICout s, const PIJSON & v) {
inline PICout operator<<(PICout s, const PIJSON & v) {
s.space();
s.saveAndSetControls(0);
PIString str;

View File

@@ -1,20 +1,20 @@
/*
PIP - Platform Independent Primitives
Module includes
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
PIP - Platform Independent Primitives
Module includes
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 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.
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/>.
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/>.
*/
//! \defgroup Serialization Serialization
//! \~\brief

View File

@@ -1,27 +1,28 @@
/*
PIP - Platform Independent Primitives
PIValueTree conversions
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
PIValueTree conversions
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 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.
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/>.
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/>.
*/
#include "pivaluetree_conversions.h"
#include "pipropertystorage.h"
#include "pijson.h"
#include "pifile.h"
#include "piiostring.h"
#include "piiostream.h"
#include "piiostring.h"
#include "pijson.h"
#include "pipropertystorage.h"
const char _attribute_[] = "_attribute_";
@@ -29,8 +30,7 @@ PIString unmask(const PIString & str) {
PIString ret(str);
ret.unmask("#\\");
if (ret.isNotEmpty())
if (ret[0] == '\\')
ret.remove(0);
if (ret[0] == '\\') ret.remove(0);
return ret;
}
@@ -38,8 +38,7 @@ PIString mask(const PIString & str) {
PIString ret = str;
if (ret.isEmpty()) return ret;
ret.mask("#\\");
if (ret[0].isSpace())
ret.insert(0, '\\');
if (ret[0].isSpace()) ret.insert(0, '\\');
return ret;
}
@@ -74,7 +73,7 @@ PIValueTree fromJSONTree(const PIJSON & json) {
ret.setName(json["name"].toString());
ret.setComment(json["comment"].toString());
PIString value_str = json["value"].toString();
PIVariant value = PIVariant::fromType(json["type"].toString());
PIVariant value = PIVariant::fromType(json["type"].toString());
if (value_str.isNotEmpty()) {
if (value.isValid())
value.setValueFromString(value_str);
@@ -86,7 +85,7 @@ PIValueTree fromJSONTree(const PIJSON & json) {
for (const auto & i: attr.object())
ret.attributes()[i.first] = i.second.value();
bool is_array = ret.isArray();
int chindex = 0;
int chindex = 0;
const PIJSON & chl(json["children"]);
for (const auto & i: chl.array()) {
PIValueTree c = fromJSONTree(i);
@@ -120,8 +119,7 @@ PIValueTree prepareFromText(const PIValueTree & root) {
value.setValueFromString(root.value().toString());
ret.setValue(value);
for (const auto & c: root.children()) {
if (c.name() != _attribute_)
ret[c.name()] = prepareFromText(c);
if (c.name() != _attribute_) ret[c.name()] = prepareFromText(c);
}
return ret;
}
@@ -144,7 +142,7 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
continue;
}
line += l;
//piCout << "L" << line.replacedAll("\n", "\\n");
// piCout << "L" << line.replacedAll("\n", "\\n");
if (line.size() < 2) {
line.clear();
continue;
@@ -169,11 +167,13 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
cind = ind;
}
if (cind >= 0) {
comm = line.takeMid(cind + 1);
comm = line.takeMid(cind + 1);
bool typed = false;
if (comm.isNotEmpty()) {
if (comm.size() == 1) typed = true;
else if (comm[0].isAlpha() && comm[1].isSpace()) typed = true;
if (comm.size() == 1)
typed = true;
else if (comm[0].isAlpha() && comm[1].isSpace())
typed = true;
}
if (typed) {
switch (comm.takeLeft(1)[0].toAscii()) {
@@ -202,11 +202,11 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
PIConfig * iconf = new PIConfig(name, incdirs);
//piCout << "include" << name << iconf->dev;
if (!iconf->dev) {
delete iconf;
delete iconf;
} else {
inc_devs << iconf;
includes << iconf << iconf->includes;
updateIncludes();
inc_devs << iconf;
includes << iconf << iconf->includes;
updateIncludes();
}
other.back() = src;*/
}
@@ -214,29 +214,25 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
line.clear();
continue;
}
//piCout << path << line << comm;
// piCout << path << line << comm;
PIValueTree & leaf(ret[path]);
leaf.setComment(comm);
leaf.setValue(unmask(line));
if (!path.contains(_attribute_))
if (!leaf.contains({_attribute_, "type"}))
leaf[_attribute_].addChild({"type", type});
if (!leaf.contains({_attribute_, "type"})) leaf[_attribute_].addChild({"type", type});
line.clear();
}
return prepareFromText(ret);
//return ret;
// return ret;
}
PIJSON toJSONTree(const PIValueTree & root, PIValueTreeConversions::Options options) {
PIJSON ret = PIJSON::newObject();
if (root.name().isNotEmpty())
ret["name"] = root.name();
if (root.comment().isNotEmpty() && options[PIValueTreeConversions::WithComment])
ret["comment"] = root.comment();
if (root.name().isNotEmpty()) ret["name"] = root.name();
if (root.comment().isNotEmpty() && options[PIValueTreeConversions::WithComment]) ret["comment"] = root.comment();
if (root.value().isValid()) {
if (options[PIValueTreeConversions::WithType])
ret["type"] = root.value().typeName();
if (options[PIValueTreeConversions::WithType]) ret["type"] = root.value().typeName();
ret["value"] = root.value().toString();
}
if (root.attributes().isNotEmpty() && options[PIValueTreeConversions::WithAttributes]) {
@@ -286,8 +282,7 @@ PIString toTextTree(const PIValueTree & root, PIString prefix, PIValueTreeConver
prefix += root.name();
if (root.hasChildren()) {
ret += "\n[" + prefix + "]\n";
if (root.isArray() && options[PIValueTreeConversions::WithAttributes])
ret += toTextTreeAttributes(root, "", options);
if (root.isArray() && options[PIValueTreeConversions::WithAttributes]) ret += toTextTreeAttributes(root, "", options);
for (const auto & c: root.children()) {
PIString cp = prefix;
ret += toTextTree(c, prefix, options);
@@ -302,8 +297,7 @@ PIString toTextTree(const PIValueTree & root, PIString prefix, PIValueTreeConver
ret += root.comment();
}
ret += "\n";
if (options[PIValueTreeConversions::WithAttributes])
ret += toTextTreeAttributes(root, root.name() + ".", options);
if (options[PIValueTreeConversions::WithAttributes]) ret += toTextTreeAttributes(root, root.name() + ".", options);
}
return ret;

View File

@@ -5,22 +5,22 @@
* \~russian Преобразования PIValueTree
*/
/*
PIP - Platform Independent Primitives
PIValueTree conversions
Ivan Pelipenko peri4ko@yandex.ru
PIP - Platform Independent Primitives
PIValueTree conversions
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 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.
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/>.
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 pivaluetree_conversions_H