162 lines
5.8 KiB
C++
162 lines
5.8 KiB
C++
#include "pip.h"
|
|
|
|
using namespace PICoutManipulators;
|
|
|
|
|
|
template<typename P>
|
|
class BinaryStream {
|
|
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> {
|
|
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;}
|
|
int i;
|
|
float f;
|
|
};
|
|
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;}
|
|
|
|
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());
|
|
vi.clear();
|
|
f.file.seekToBegin();
|
|
f >> vi;
|
|
piCout << "data" << vi;
|
|
//piCout << "r" << ba.data;
|
|
return 0;
|
|
}
|