code format
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user