+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(this)->appendImp(d, s);}
+ void take(void * d, size_t s) {static_cast
(this)->takeImp(d, s);}
+ template
+ 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
+class PIBinaryStreamRef {
+public:
+ PIBinaryStreamRef(PIBinaryStream & s): p(s) {}
+ PIBinaryStream
& p;
+};
+
+
+template inline PIBinaryStream & operator <<(PIBinaryStreamRef
s, const T & v) {s.p << v; return s.p;}
+template inline PIBinaryStream & operator >>(PIBinaryStreamRef
s, T & v) {s.p >> v; return s.p;}
+
+
+// small types
+template inline PIBinaryStreamRef operator <<(PIBinaryStream
& s, const bool v) {s.append((uchar)v); return s;}
+template inline PIBinaryStreamRef operator <<(PIBinaryStream
& s, const char v) {s.append((uchar)v); return s;}
+template inline PIBinaryStreamRef operator <<(PIBinaryStream
& s, const uchar v) {s.append((uchar)v); return s;}
+template inline PIBinaryStreamRef operator >>(PIBinaryStream
& s, bool & v) {v = s.takeByte(); return s;}
+template inline PIBinaryStreamRef operator >>(PIBinaryStream
& s, char & v) {v = s.takeByte(); return s;}
+template inline PIBinaryStreamRef operator >>(PIBinaryStream
& s, uchar & v) {v = s.takeByte(); return s;}
+
+
+
+
+// store simple types
+
+
+template::value, int>::type = 0>
+inline PIBinaryStreamRef operator <<(PIBinaryStream
& s, const T & v) {
+ s.append(&v, sizeof(v));
+ return s;
+}
+
+
+//! \~english Store operator for PIVector of any trivial copyable type
+//! \~russian Оператор сохранения для PIVector тривиальных типов
+template::value, int>::type = 0,
+typename std::enable_if< std::is_same&>() << std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator <<(PIBinaryStream
& s, const PIVector & v) {
+ piCout << "<< vector trivial default";
+ s.append((int)v.size());
+ s.append(v.data(), v.size() * sizeof(T));
+ return s;
+}
+template::value, int>::type = 0,
+typename std::enable_if&>() << std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator <<(PIBinaryStream
& s, const PIVector & 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::value, int>::type = 0,
+typename std::enable_if< std::is_same&>() << std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator <<(PIBinaryStream
& s, const PIDeque & v) {
+ piCout << "<< deque trivial default";
+ s.append((int)v.size());
+ s.append(v.data(), v.size() * sizeof(T));
+ return s;
+}
+template::value, int>::type = 0,
+typename std::enable_if&>() << std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator <<(PIBinaryStream
& s, const PIDeque & 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::value, int>::type = 0,
+typename std::enable_if< std::is_same&>() << std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator <<(PIBinaryStream
& s, const PIVector2D & 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::value, int>::type = 0,
+typename std::enable_if&>() << std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator <<(PIBinaryStream
& s, const PIVector2D & 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
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const PIBitArray & v) {s << v.size_ << v.data_; return s;}
+
+
+//! \~english Store operator
+//! \~russian Оператор сохранения
+template
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const PIPair & v) {s << v.first << v.second; return s;}
+
+
+
+
+// restore simple types
+
+
+template::value, int>::type = 0>
+inline PIBinaryStreamRef operator >>(PIBinaryStream
& s, T & v) {
+ s.take(&v, sizeof(v));
+ return s;
+}
+
+
+//! \~english Restore operator for PIVector of any trivial copyable type
+//! \~russian Оператор извлечения для PIVector тривиальных типов
+template::value, int>::type = 0,
+typename std::enable_if< std::is_same&>() >> std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator >>(PIBinaryStream
& s, PIVector & v) {
+ piCout << ">> vector trivial default";
+ int sz = s.takeInt();
+ v._resizeRaw(sz);
+ s.take(v.data(), sz*sizeof(T));
+ return s;
+}
+template::value, int>::type = 0,
+typename std::enable_if&>() >> std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator >>(PIBinaryStream
& s, PIVector & 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::value, int>::type = 0,
+typename std::enable_if< std::is_same&>() >> std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator >>(PIBinaryStream
& s, PIDeque & v) {
+ piCout << ">> deque trivial default";
+ int sz = s.takeInt();
+ v._resizeRaw(sz);
+ s.take(v.data(), sz*sizeof(T));
+ return s;
+}
+template::value, int>::type = 0,
+typename std::enable_if&>() >> std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator >>(PIBinaryStream
& s, PIDeque & 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::value, int>::type = 0,
+typename std::enable_if< std::is_same&>() >> std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator >>(PIBinaryStream
& s, PIVector2D & 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::value, int>::type = 0,
+typename std::enable_if&>() >> std::declval()), PIBinaryStreamRef>::value, int>::type = 0>
+inline PIBinaryStream
& operator >>(PIBinaryStream
& s, PIVector2D & v) {
+ piCout << ">> vector2d trivial custom";
+ int r, c;
+ PIVector tmp;
+ r = s.takeInt();
+ c = s.takeInt();
+ s >> tmp;
+ v = PIVector2D(r, c, tmp);
+ return s;
+}
+;
+
+
+
+
+// store complex types
+
+
+//! \~english Store operator for PIVector of any compound type
+//! \~russian Оператор сохранения для PIVector сложных типов
+template::value, int>::type = 0>
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const PIVector & 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::value, int>::type = 0>
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const PIDeque & 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::value, int>::type = 0>
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const PIVector2D & 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::value, int>::type = 0>
+inline PIBinaryStream & operator >>(PIBinaryStream
& s, PIVector & 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::value, int>::type = 0>
+inline PIBinaryStream & operator >>(PIBinaryStream
& s, PIDeque & 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::value, int>::type = 0>
+inline PIBinaryStream & operator >>(PIBinaryStream
& s, PIVector2D & 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 tmp;
+ r = s.takeInt();
+ c = s.takeInt();
+ s >> tmp;
+ v = PIVector2D(r, c, tmp);
+ return s;
+}
+
+
+
+
+// other types
+
+
+//! \~english Store operator
+//! \~russian Оператор сохранения
+template
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const PIMap & 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
+inline PIBinaryStream & operator >>(PIBinaryStream
& s, PIMap & 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::value, int>::type = 0>
+inline PIBinaryStream & operator <<(PIBinaryStream
& s, const T & ) {
+ static_assert(std::is_trivially_copyable::value, "[PIBinaryStream] Error: using undeclared operator << for complex type!");
+ return s;
+}
+
+template::value, int>::type = 0>
+inline PIBinaryStream & operator >>(PIBinaryStream
& s, T & ) {
+ static_assert(std::is_trivially_copyable::value, "[PIBinaryStream] Error: using undeclared operator >> for complex type!");
+ return s;
+}
+
+
+
+
+#endif
diff --git a/main.cpp b/main.cpp
index 83784703..52ca5804 100644
--- a/main.cpp
+++ b/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
-class BinaryStream {
+class ByteArray: public PIBinaryStream {
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
-class BinaryStreamRef {
-public:
- BinaryStreamRef(BinaryStream & s): p(s) {}
- BinaryStream
& ref() {return p;}
- BinaryStream
& p;
-};
-
-
-template inline BinaryStream & operator <<(BinaryStreamRef
s, const T & v) {s.ref() << v; return s.p;}
-template inline BinaryStream & operator >>(BinaryStreamRef
s, T & v) {s.ref() >> v; return s.p;}
-
-template inline BinaryStream & operator <<(BinaryStream
& s, const bool v) {s.append((uchar)v); return s;}
-template inline BinaryStream & operator <<(BinaryStream
& s, const char v) {s.append((uchar)v); return s;}
-template inline BinaryStream & operator <<(BinaryStream
& s, const uchar v) {s.append((uchar)v); return s;}
-template::value, int>::type = 0>
-inline BinaryStreamRef operator <<(BinaryStream
& s, const T & v) {
- s.append(&v, sizeof(v));
- return s;
-}
-
-template inline BinaryStream & operator >>(BinaryStream
& s, bool & v) {v = s.takeByte(); return s;}
-template inline BinaryStream & operator >>(BinaryStream
& s, char & v) {v = s.takeByte(); return s;}
-template inline BinaryStream & operator >>(BinaryStream
& s, uchar & v) {v = s.takeByte(); return s;}
-template::value, int>::type = 0>
-inline BinaryStreamRef operator >>(BinaryStream
& s, T & v) {
- s.take(&v, sizeof(v));
- return s;
-}
-
-
-//! \~english Store operator for PIVector of any trivial copyable type
-//! \~russian Оператор сохранения для PIVector тривиальных типов
-template::value, int>::type = 0,
- typename std::enable_if< std::is_same&>() << std::declval()), BinaryStreamRef>::value, int>::type = 0>
-inline BinaryStream
& operator <<(BinaryStream
& s, const PIVector & v) {
- piCout << "<< vector trivial default";
- s.append((int)v.size());
- s.append(v.data(), v.size() * sizeof(T));
- return s;
-}
-template::value, int>::type = 0,
- typename std::enable_if&>() << std::declval()), BinaryStreamRef>::value, int>::type = 0>
-inline BinaryStream
& operator <<(BinaryStream
& s, const PIVector & 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::value, int>::type = 0,
- typename std::enable_if< std::is_same&>() >> std::declval()), BinaryStreamRef>::value, int>::type = 0>
-inline BinaryStream
& operator >>(BinaryStream
& s, PIVector & 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::value, int>::type = 0,
- typename std::enable_if&>() >> std::declval()), BinaryStreamRef>::value, int>::type = 0>
-inline BinaryStream
& operator >>(BinaryStream
& s, PIVector & 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 {
-public:
- ByteArray(): BinaryStream(*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 {
+class File: public PIBinaryStream {
public:
- File(): BinaryStream(*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 inline BinaryStream & operator <<(BinaryStream
& s, const TS & v) {s << v.i; return s;}
-template inline BinaryStream & operator >>(BinaryStream
& s, TS & v) {s >> v.i; return s;}
+template inline PIBinaryStream & operator <<(PIBinaryStream
& s, const TS & v) {s << v.i; return s;}
+template inline PIBinaryStream & operator >>(PIBinaryStream
& 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 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 vi({TS(1,20), TS(3,40)});
+ PIVector 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;
}