before error detection
This commit is contained in:
415
libs/main/core/pibinarystream.h
Normal file
415
libs/main/core/pibinarystream.h
Normal file
@@ -0,0 +1,415 @@
|
||||
/*! \file pibinarystream.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english Binary serialization interface
|
||||
* \~russian Интерфейс бинарной сериализации
|
||||
*/
|
||||
/*
|
||||
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 distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIBINARYSTREAM_H
|
||||
#define PIBINARYSTREAM_H
|
||||
|
||||
#include "pibitarray.h"
|
||||
#include "pimap.h"
|
||||
#include "pivector2d.h"
|
||||
|
||||
|
||||
//! \ingroup Core
|
||||
//! \~\brief
|
||||
//! \~english Binary serialization interface.
|
||||
//! \~russian Интерфейс бинарной сериализации.
|
||||
template<typename P>
|
||||
class PIBinaryStream {
|
||||
public:
|
||||
// one should implements next methods:
|
||||
//
|
||||
// void appendImp(const void * d, size_t s);
|
||||
// void takeImp(void * d, size_t s);
|
||||
|
||||
void append(const void * d, size_t s) {static_cast<P*>(this)->appendImp(d, s);}
|
||||
void take(void * d, size_t s) {static_cast<P*>(this)->takeImp(d, s);}
|
||||
template<typename T>
|
||||
void append(T v) {append(&v, sizeof(v));}
|
||||
uchar takeByte() {uchar r = 0; take(&r, sizeof(r)); return r;}
|
||||
int takeInt() {int r = 0; take(&r, sizeof(r)); return r;}
|
||||
};
|
||||
|
||||
|
||||
// helper class to detect default operators
|
||||
template<typename P>
|
||||
class PIBinaryStreamRef {
|
||||
public:
|
||||
PIBinaryStreamRef(PIBinaryStream<P> & s): p(s) {}
|
||||
PIBinaryStream<P> & p;
|
||||
};
|
||||
|
||||
|
||||
template<typename P, typename T> inline PIBinaryStream<P> & operator <<(PIBinaryStreamRef<P> s, const T & v) {s.p << v; return s.p;}
|
||||
template<typename P, typename T> inline PIBinaryStream<P> & operator >>(PIBinaryStreamRef<P> s, T & v) {s.p >> v; return s.p;}
|
||||
|
||||
|
||||
// small types
|
||||
template<typename P> inline PIBinaryStreamRef<P> operator <<(PIBinaryStream<P> & s, const bool v) {s.append((uchar)v); return s;}
|
||||
template<typename P> inline PIBinaryStreamRef<P> operator <<(PIBinaryStream<P> & s, const char v) {s.append((uchar)v); return s;}
|
||||
template<typename P> inline PIBinaryStreamRef<P> operator <<(PIBinaryStream<P> & s, const uchar v) {s.append((uchar)v); return s;}
|
||||
template<typename P> inline PIBinaryStreamRef<P> operator >>(PIBinaryStream<P> & s, bool & v) {v = s.takeByte(); return s;}
|
||||
template<typename P> inline PIBinaryStreamRef<P> operator >>(PIBinaryStream<P> & s, char & v) {v = s.takeByte(); return s;}
|
||||
template<typename P> inline PIBinaryStreamRef<P> operator >>(PIBinaryStream<P> & s, uchar & v) {v = s.takeByte(); return s;}
|
||||
|
||||
|
||||
|
||||
|
||||
// store simple types
|
||||
|
||||
|
||||
template<typename P, typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStreamRef<P> operator <<(PIBinaryStream<P> & s, const T & v) {
|
||||
s.append(&v, sizeof(v));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
||||
piCout << "<< vector trivial default";
|
||||
s.append((int)v.size());
|
||||
s.append(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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector<T> & v) {
|
||||
piCout << "<< vector trivial custom";
|
||||
s.append((int)v.size());
|
||||
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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
||||
piCout << "<< deque trivial default";
|
||||
s.append((int)v.size());
|
||||
s.append(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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<T> & v) {
|
||||
piCout << "<< deque trivial custom";
|
||||
s.append((int)v.size());
|
||||
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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
||||
piCout << "<< vector2d trivial default";
|
||||
s.append((int)v.rows());
|
||||
s.append((int)v.cols());
|
||||
s.append(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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIVector2D<T> & v) {
|
||||
piCout << "<< vector2d trivial custom";
|
||||
s.append((int)v.rows());
|
||||
s.append((int)v.cols());
|
||||
s << v.toPlainVector();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Store operator
|
||||
//! \~russian Оператор сохранения
|
||||
template<typename P>
|
||||
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;}
|
||||
|
||||
|
||||
|
||||
|
||||
// restore simple types
|
||||
|
||||
|
||||
template<typename P, typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline PIBinaryStreamRef<P> operator >>(PIBinaryStream<P> & s, T & v) {
|
||||
s.take(&v, sizeof(v));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
||||
piCout << ">> vector trivial default";
|
||||
int sz = s.takeInt();
|
||||
v._resizeRaw(sz);
|
||||
s.take(v.data(), sz*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<T &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector<T> & v) {
|
||||
piCout << ">> vector trivial custom";
|
||||
int sz = s.takeInt();
|
||||
v._resizeRaw(sz);
|
||||
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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
||||
piCout << ">> deque trivial default";
|
||||
int sz = s.takeInt();
|
||||
v._resizeRaw(sz);
|
||||
s.take(v.data(), sz*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<T &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<T> & v) {
|
||||
piCout << ">> deque trivial custom";
|
||||
int sz = s.takeInt();
|
||||
v._resizeRaw(sz);
|
||||
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 &>()), PIBinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIVector2D<T> & v) {
|
||||
piCout << ">> vector2d trivial default";
|
||||
int r, c;
|
||||
r = s.takeInt();
|
||||
c = s.takeInt();
|
||||
v._resizeRaw(r, c);
|
||||
s.take(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<T &>()), PIBinaryStreamRef<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.takeInt();
|
||||
c = s.takeInt();
|
||||
s >> tmp;
|
||||
v = PIVector2D<T>(r, c, tmp);
|
||||
return s;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
// store complex types
|
||||
|
||||
|
||||
//! \~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";
|
||||
s.append(int(v.size_s()));
|
||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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";
|
||||
s.append(int(v.size_s()));
|
||||
for (size_t i = 0; i < v.size(); ++i) s << v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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";
|
||||
s.append(int(v.rows()));
|
||||
s.append(int(v.cols()));
|
||||
s << v.toPlainVector();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 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";
|
||||
/*if (s.size_s() < 4) {
|
||||
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 4);
|
||||
}*/
|
||||
v.resize(s.takeInt());
|
||||
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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";
|
||||
/*if (s.size_s() < 4) {
|
||||
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 4);
|
||||
}*/
|
||||
v.resize(s.takeInt());
|
||||
for (size_t i = 0; i < v.size(); ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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";
|
||||
/*if (s.size_s() < 8) {
|
||||
printf("error with PIVecto2Dr<%s>\n", __PIP_TYPENAME__(T));
|
||||
assert(s.size_s() >= 8);
|
||||
}*/
|
||||
int r, c;
|
||||
PIVector<T> tmp;
|
||||
r = s.takeInt();
|
||||
c = s.takeInt();
|
||||
s >> tmp;
|
||||
v = PIVector2D<T>(r, c, tmp);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 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) {
|
||||
s.append((int)v.pim_index.size_s());
|
||||
for (uint i = 0; i < v.size(); ++i) {
|
||||
s.append((int)v.pim_index[i].index);
|
||||
s << v.pim_index[i].key;
|
||||
}
|
||||
s << v.pim_content;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Restore operator
|
||||
//! \~russian Оператор извлечения
|
||||
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);
|
||||
}*/
|
||||
int sz = s.takeInt(); v.pim_index.resize(sz);
|
||||
int ind = 0;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
ind = s.takeInt();
|
||||
s >> v.pim_index[i].key;
|
||||
v.pim_index[i].index = ind;
|
||||
}
|
||||
s >> v.pim_content;
|
||||
if (v.pim_content.size_s() != v.pim_index.size_s()) {
|
||||
piCout << "Warning: loaded invalid PIMap, clear";
|
||||
v.clear();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 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 & ) {
|
||||
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 & ) {
|
||||
static_assert(std::is_trivially_copyable<T>::value, "[PIBinaryStream] Error: using undeclared operator >> for complex type!");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
151
main.cpp
151
main.cpp
@@ -1,161 +1,64 @@
|
||||
#include "pip.h"
|
||||
#include "pibinarystream.h"
|
||||
//#include "stream.h"
|
||||
//#include "ccm.h"
|
||||
//#include "pisystemmonitor_.h"
|
||||
|
||||
using namespace PICoutManipulators;
|
||||
|
||||
|
||||
template<typename P>
|
||||
class BinaryStream {
|
||||
class ByteArray: public PIBinaryStream<ByteArray> {
|
||||
public:
|
||||
BinaryStream(P & parent): p(parent) {}
|
||||
void append(const void * d, size_t s) {p.appendImp(d, s);}
|
||||
void append(int i) {append(&i, sizeof(i));}
|
||||
void append(uchar byte) {p.appendImp(byte);}
|
||||
void take(void * d, size_t s) {p.takeImp(d, s);}
|
||||
uchar takeByte() {return p.takeByteImp();}
|
||||
int takeInt() {int r = 0; take(&r, sizeof(r)); return r;}
|
||||
private:
|
||||
P & p;
|
||||
};
|
||||
|
||||
template<typename P>
|
||||
class BinaryStreamRef {
|
||||
public:
|
||||
BinaryStreamRef(BinaryStream<P> & s): p(s) {}
|
||||
BinaryStream<P> & ref() {return p;}
|
||||
BinaryStream<P> & p;
|
||||
};
|
||||
|
||||
|
||||
template<typename P, typename T> inline BinaryStream<P> & operator <<(BinaryStreamRef<P> s, const T & v) {s.ref() << v; return s.p;}
|
||||
template<typename P, typename T> inline BinaryStream<P> & operator >>(BinaryStreamRef<P> s, T & v) {s.ref() >> v; return s.p;}
|
||||
|
||||
template<typename P> inline BinaryStream<P> & operator <<(BinaryStream<P> & s, const bool v) {s.append((uchar)v); return s;}
|
||||
template<typename P> inline BinaryStream<P> & operator <<(BinaryStream<P> & s, const char v) {s.append((uchar)v); return s;}
|
||||
template<typename P> inline BinaryStream<P> & operator <<(BinaryStream<P> & s, const uchar v) {s.append((uchar)v); return s;}
|
||||
template<typename P, typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline BinaryStreamRef<P> operator <<(BinaryStream<P> & s, const T & v) {
|
||||
s.append(&v, sizeof(v));
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename P> inline BinaryStream<P> & operator >>(BinaryStream<P> & s, bool & v) {v = s.takeByte(); return s;}
|
||||
template<typename P> inline BinaryStream<P> & operator >>(BinaryStream<P> & s, char & v) {v = s.takeByte(); return s;}
|
||||
template<typename P> inline BinaryStream<P> & operator >>(BinaryStream<P> & s, uchar & v) {v = s.takeByte(); return s;}
|
||||
template<typename P, typename T, typename std::enable_if< std::is_trivially_copyable<T>::value, int>::type = 0>
|
||||
inline BinaryStreamRef<P> operator >>(BinaryStream<P> & s, T & v) {
|
||||
s.take(&v, sizeof(v));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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<BinaryStream<P>&>() << std::declval<const T &>()), BinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline BinaryStream<P> & operator <<(BinaryStream<P> & s, const PIVector<T> & v) {
|
||||
piCout << "<< vector trivial default";
|
||||
s.append((int)v.size());
|
||||
s.append(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<BinaryStream<P>&>() << std::declval<const T &>()), BinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline BinaryStream<P> & operator <<(BinaryStream<P> & s, const PIVector<T> & v) {
|
||||
piCout << "<< vector trivial custom";
|
||||
s.append((int)v.size());
|
||||
for (const auto & i: v) s << i;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~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<BinaryStream<P>&>() >> std::declval<T &>()), BinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline BinaryStream<P> & operator >>(BinaryStream<P> & s, PIVector<T> & v) {
|
||||
piCout << ">> vector trivial default";
|
||||
int sz = s.takeInt();
|
||||
v._resizeRaw(sz);
|
||||
if (sz > 0)
|
||||
s.take(v.data(), sz*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<BinaryStream<P>&>() >> std::declval<T &>()), BinaryStreamRef<P>>::value, int>::type = 0>
|
||||
inline BinaryStream<P> & operator >>(BinaryStream<P> & s, PIVector<T> & v) {
|
||||
piCout << ">> vector trivial custom";
|
||||
int sz = s.takeInt();
|
||||
v._resizeRaw(sz);
|
||||
for (int i = 0; i < sz; ++i) s >> v[i];
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
class ByteArray: public BinaryStream<ByteArray> {
|
||||
public:
|
||||
ByteArray(): BinaryStream<ByteArray>(*this) {}
|
||||
PIByteArray data;
|
||||
void appendImp(const void * d, size_t s) {
|
||||
data.append(d, s);
|
||||
}
|
||||
void appendImp(uchar byte) {
|
||||
data.append(byte);
|
||||
}
|
||||
void takeImp(void * d, size_t s) {
|
||||
memcpy(d, data.data(), s);
|
||||
data.remove(0, s);
|
||||
}
|
||||
uchar takeByteImp() {
|
||||
return data.take_front();
|
||||
}
|
||||
};
|
||||
|
||||
class File: public BinaryStream<File> {
|
||||
class File: public PIBinaryStream<File> {
|
||||
public:
|
||||
File(): BinaryStream<File>(*this) {}
|
||||
PIFile file;
|
||||
void appendImp(const void * d, size_t s) {
|
||||
file.write(d, s);
|
||||
}
|
||||
void appendImp(uchar byte) {
|
||||
file.writeBinary(byte);
|
||||
}
|
||||
void takeImp(void * d, size_t s) {
|
||||
file.read(d, s);
|
||||
}
|
||||
uchar takeByteImp() {
|
||||
return (uchar)file.readChar();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct TS {
|
||||
TS(int v0 = -1, float v1 = -1){i = v0; f = v1;}
|
||||
TS(int v0 = -1, float v1 = -1, PIString v2 = "") {i = v0; f = v1; s = v2;}
|
||||
int i;
|
||||
float f;
|
||||
PIString s;
|
||||
};
|
||||
PICout operator << (PICout c, const TS & v) {c << '{' << v.i << ", " << v.f << '}'; return c;}
|
||||
|
||||
template<typename P> inline BinaryStream<P> & operator <<(BinaryStream<P> & s, const TS & v) {s << v.i; return s;}
|
||||
template<typename P> inline BinaryStream<P> & operator >>(BinaryStream<P> & s, TS & v) {s >> v.i; return s;}
|
||||
template<typename P> inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const TS & v) {s << v.i; return s;}
|
||||
template<typename P> inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, TS & v) {s >> v.i; return s;}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
//ByteArray ba;
|
||||
File f;
|
||||
f.file.open("_", PIIODevice::ReadWrite);
|
||||
f.file.clear();
|
||||
PIVector<TS> vi({TS(1,20), TS(3,40)});
|
||||
f << vi;
|
||||
//piCout << "s" << ba.data;
|
||||
vi.fill(TS());
|
||||
ByteArray ba;
|
||||
/*ProcessStatsFixed_ ps;
|
||||
ba << ps;
|
||||
piCout << "s" << ba.data;*/
|
||||
//File f;
|
||||
//f.file.open("_", PIIODevice::ReadWrite);
|
||||
//f.file.clear();
|
||||
//PIVector<TS> vi({TS(1,20), TS(3,40)});
|
||||
PIVector<PIChar> vi({'a', 'b', 'c'});
|
||||
ba << vi;
|
||||
piCout << "src" << vi;
|
||||
piCout << "s" << ba.data;
|
||||
vi.fill(' ');
|
||||
vi.clear();
|
||||
f.file.seekToBegin();
|
||||
f >> vi;
|
||||
piCout << "data" << vi;
|
||||
//piCout << "r" << ba.data;
|
||||
//f.file.seekToBegin();
|
||||
ba >> vi;
|
||||
piCout << "res" << vi;
|
||||
piCout << "r" << ba.data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user