15 #include "classdesc.h" 31 #pragma warning(disable:4512) 42 pack_error(
const char *s): msg(
"pack:") {msg+=s;}
44 virtual const char* what()
const throw() {
return msg.c_str();}
48 typedef bool (*xdr_filter)(XDR*,...);
61 template <
class T> xdr_filter XDR_filter(
const T&);
68 val=(
void*)&x; size=
sizeof(x);
92 virtual void *data()=0;
103 void* data() {
return &d;}
114 void* data() {
return d->data();}
126 #if __cplusplus < 201103L 132 void swap_base (
pack_t& other){
133 std::swap(f,other.f);
134 std::swap(mode,other.mode);
135 std::swap(m_data,other.
m_data);
136 std::swap(m_size,other.
m_size);
137 std::swap(m_pos,other.
m_pos);
138 std::swap(ptr_flag,other.ptr_flag);
139 std::swap(alloced,other.alloced);
141 enum mode_t {buf, readf, writef};
151 std::vector<PtrStoreRef> alloced;
152 const char*
data()
const {
return m_data;}
154 size_t size()
const {
return m_size;}
155 size_t pos()
const {
return m_pos;}
156 char* realloc(
char* d,
size_t s) {
158 return (
char*)Realloc(d,s);
160 return (
char*)classdesc::realloc(d,s);
163 void realloc(
size_t s) {m_data=realloc(m_data,s);}
169 realloc(m_size+x.size);
171 throw std::bad_alloc();
172 memcpy(m_data+m_size,x.val,x.size);
175 if (fwrite(x.val,x.size,1,f) != 1)
182 if (m_pos+x.size>m_size)
185 memcpy(x.val,m_data+m_pos,x.size);
187 if (fread(x.val,x.size,1,f) != 1)
192 pack_t(
size_t sz=0): f(0), mode(buf), m_data(NULL), m_size(sz), m_pos(0), ptr_flag(DEFAULT), recur_max(500) {
197 pack_t(
const char *fname,
const char *rw):
198 f(fopen(fname,rw)), mode( (rw&&rw[0]==
'w')? writef: readf),
199 m_data(0), m_size(0), m_pos(0), ptr_flag(DEFAULT), recur_max(500) {
206 virtual ~
pack_t() {realloc(0);
if (f) fclose(f);}
208 #if __cplusplus >= 201103L 209 pack_t(
pack_t&& x): f(
nullptr), m_data(
nullptr) {swap(x);}
213 virtual operator bool() {
return m_pos<m_size;}
214 virtual pack_t& reseti() {m_size=0;
if (f) fseek(f,0,SEEK_SET);
return *
this;}
215 virtual pack_t& reseto() {m_pos=0;
if (f) fseek(f,0,SEEK_SET);
return *
this;}
216 virtual pack_t& seeki(
long offs) {
217 assert(offs<=0); m_size+=offs;
218 if (f) fseek(f,offs,SEEK_CUR);
221 virtual pack_t& seeko(
long offs) {
223 if (f) fseek(f,offs,SEEK_CUR);
226 void clear() {realloc(0); m_data=0; m_size=m_pos=0;}
227 virtual void packraw(
const char *x,
size_t s)
232 memcpy(m_data+m_size,x,s); m_size+=s;
235 if (fwrite(x,s,1,f)!=1)
236 throw pack_error(
"filed to write data to stream");
239 virtual void unpackraw(
char *x,
size_t s)
242 memcpy(x,m_data+m_pos,s);
244 if (fread(x,s,1,f)!=1)
248 virtual void swap(
pack_t& other) {
249 if (
typeid(*
this)!=
typeid(other))
250 throw pack_error(
"cannot swap differing types");
257 return memcmp(m_data,x.
m_data,m_size);
259 return m_size<x.
m_size? -1: 1;
262 bool operator<(
const pack_t& x)
const {
return cmp(x)==-1;}
263 bool operator>(
const pack_t& x)
const {
return cmp(x)==1;}
264 bool operator==(
const pack_t& x)
const {
return cmp(x)==0;}
265 bool operator!=(
const pack_t& x)
const {
return cmp(x)!=0;}
272 return (xb<<x).
cmp(yb<<y);
278 return (xb<<x).
cmp(yb<<y)==0;
284 const int BUFCHUNK=1024;
295 xdr_pack(
const char *,
const char* rw);
297 #if __cplusplus >= 201103L 308 virtual void packraw(
const char *x,
size_t sz);
309 virtual void unpackraw(
char *x,
size_t sz);
310 virtual void swap(
pack_t& other) {
312 if (!xdr_other)
throw pack_error(
"cannot swap differing types");
314 std::swap(asize,xdr_other->asize);
315 std::swap(input,xdr_other->input);
316 std::swap(input,xdr_other->output);
337 operator<<(
const T& o)
339 packer.packraw(reinterpret_cast<const char*>(&o),
sizeof(T));
346 packer.unpackraw(reinterpret_cast<char*>(&o),
sizeof(T));
352 operator<<(
const T& o)
355 for (
typename T::const_iterator i=o.begin(); i!=o.end(); ++i)
366 typename T::value_type v;
367 for (
size_t i=0; i<s; ++i)
381 typename T::value_type v;
382 for (
size_t i=0; i<s; ++i)
391 template <
class T,
class A>
392 inline BinStream& operator<<(const std::vector<T,A>& o);
394 template <
class T,
class A>
395 inline BinStream& operator>>(std::vector<T,A>& o);
410 template <
class A1,
class A2>
BinStreamT(A1 a1, A2 a2):
429 unserialisable operator=(
const T& x) {T::operator=(x);
return *
this;}
433 template <
class T>
pack_t& operator<<(
pack_t& y,
const T&x);
439 public is_fundamental<T> {};
441 #ifndef THROW_PTR_EXCEPTION 446 inline void unpack(unpack_t& targ,
const string& desc,
450 inline void pack(
pack_t& targ,
const string& desc,
462 void pack_onbase(
pack_t& x,
const string& d,T& a)
466 void unpack_onbase(unpack_t& x,
const string& d,T& a)
470 using classdesc::pack_onbase;
471 using classdesc::unpack_onbase;
481 template <
class T>
struct access_pack;
483 template <
class T>
struct access_unpack;
492 switch (targ.ptr_flag)
495 #ifndef THROW_PTR_EXCEPTION 496 case classdesc::GRAPH:
499 case classdesc::TREE:
515 switch (targ.ptr_flag)
518 #ifndef THROW_PTR_EXCEPTION 519 case classdesc::GRAPH:
522 case classdesc::TREE:
553 template <
class T>
typename 554 enable_if<Not<pack_supported<T> >,
void>::T
555 pack(pack_t& buf,
const string& desc, T& arg)
559 template <
class T>
typename 560 enable_if<Not<pack_supported<T> >,
void>::T
561 unpack(unpack_t& buf,
const string& desc, T& arg)
565 typename enable_if<is_fundamental<T>,
void>::T
566 pack(pack_t& targ,
const string&, T& arg)
568 Basic_Type<T> b(arg);
573 typename enable_if<is_fundamental<T>,
void>::T
574 pack(pack_t& targ,
const string&,
const T& arg)
576 Basic_Type<T> b(arg);
581 typename enable_if<is_fundamental<T>,
void>::T
582 unpack(unpack_t& targ,
const string&, T& arg)
584 Basic_Type<T> b(arg);
589 typename enable_if<is_fundamental<T>,
void>::T
590 unpack(unpack_t& targ,
const string&,
const T&)
592 T dum; Basic_Type<T> b(dum);
608 void pack(pack_t& targ,
const string& desc, is_array,
609 T &arg,
int dims,
size_t ncopies,...)
612 va_start(ap,ncopies);
613 for (
int i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
615 for (
size_t i=0; i<ncopies; i++)
pack(targ,desc,(&arg)[i]);
619 void unpack(unpack_t& targ,
const string& desc, is_array, T &arg,
620 int dims,
size_t ncopies,...)
623 va_start(ap,ncopies);
624 for (
int i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
626 for (
size_t i=0; i<ncopies; i++)
unpack(targ,desc,(&arg)[i]);
630 inline void pack(pack_t& targ,
const string&, is_array,
631 char &arg,
int dims,
size_t ncopies,...)
635 va_start(ap,ncopies);
636 for (i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
638 targ.packraw(&arg,ncopies);
641 inline void unpack(unpack_t& targ,
const string&, is_array,
642 char &arg,
int dims,
size_t ncopies,...)
646 va_start(ap,ncopies);
647 for (i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
649 targ.unpackraw(&arg,ncopies);
654 template<
class C,
class T>
655 void pack(pack_t&,
const string&, C&, T) {}
657 template<
class C,
class T>
658 void unpack(unpack_t&,
const string&, C&, T) {}
663 template <
class C,
class R,
class A1>
664 void pack(pack_t& targ,
const string& desc, R (C::*&arg)(A1))
665 {targ.packraw((
char*)&arg,
sizeof(arg));}
667 template <
class C,
class R,
class A1>
668 void unpack(pack_t& targ,
const string& desc, R (C::*&arg)(A1))
669 {targ.unpackraw((
char*)&arg,
sizeof(arg));}
681 template <
class T,
class U>
684 template <
class T,
class U>
707 using classdesc::pack_onbase;
708 using classdesc::unpack_onbase;
713 #pragma omit pack classdesc::string 714 #pragma omit pack eco_strstream 715 #pragma omit pack xdr_pack 716 #pragma omit unpack classdesc::string 717 #pragma omit unpack eco_strstream 718 #pragma omit unpack xdr_pack size_t size() const
size of buffer
Definition: pack_base.h:154
virtual int cmp(const pack_t &x) const
Definition: pack_base.h:255
Definition: pack_base.h:404
Definition: pack_base.h:100
Definition: pack_base.h:330
Definition: classdesc.h:631
Definition: pack_base.h:38
int deepCmp(const T &x, const T &y)
deep comparison of two serialisable items
Definition: pack_base.h:270
class to allow access to private members
Definition: classdesc_access.h:21
Definition: classdesc.h:626
helper for constructing null descriptors
Definition: classdesc.h:784
char * data()
actual buffer
Definition: pack_base.h:153
Ptr_flag
Definition: pack_base.h:80
Definition: pack_base.h:51
bool deepEq(const T &x, const T &y)
deep equality of two serialisable items
Definition: pack_base.h:276
size_t m_size
size of buffer
Definition: pack_base.h:144
size_t m_pos
position of read pointer
Definition: pack_base.h:145
class to allow access to private members
Definition: classdesc_access.h:22
void pack(pack_t &targ, const string &desc, is_treenode dum, const T *const &arg)
serialise a tree (or DAG)
Definition: pack_graph.h:28
Definition: pack_base.h:65
Definition: classdesc.h:588
Definition: pack_base.h:438
const char * data() const
actual buffer
Definition: pack_base.h:152
Definition: classdesc.h:630
serialisation for standard containers
Definition: pack_base.h:425
Definition: pack_base.h:110
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
Definition: pack_base.h:124
Definition: pack_base.h:87
controlled template specialisation: stolen from boost::enable_if.
Definition: classdesc.h:249
char * m_data
actual buffer
Definition: pack_base.h:143
size_t pos() const
position of read pointer
Definition: pack_base.h:155
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
base class for exceptions thrown by classdesc
Definition: classdesc.h:366
unsigned recur_max
recursion limit for pack_graph
Definition: pack_base.h:150
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition: pack_graph.h:44