00001
00002 #ifndef INCLUDED_LoadSave_h
00003 #define INCLUDED_LoadSave_h
00004
00005 #include <string>
00006 #include <sys/param.h>
00007 #include <stdexcept>
00008 #include <stdarg.h>
00009 #include "attributes.h"
00010
00011 #ifdef PLATFORM_APERIOS
00012
00013 int vasprintf(char** ret, const char* format, va_list al);
00014 #endif
00015
00016
00017
00018
00019
00020
00021 #ifndef LOADSAVE_SWAPBYTES
00022
00023 #ifdef BYTE_ORDER
00024 # if BYTE_ORDER == BIG_ENDIAN
00025 # define LOADSAVE_SWAPBYTES 1
00026 # elif BYTE_ORDER == LITTLE_ENDIAN
00027 # define LOADSAVE_SWAPBYTES 0
00028 # else
00029 # warning unknown byte ordering for current platform, assuming no swap
00030 # define LOADSAVE_SWAPBYTES 0
00031 # endif
00032 #else
00033
00034
00035 # ifdef PLATFORM_APERIOS
00036
00037 # define LOADSAVE_SWAPBYTES 0
00038 # else
00039 # warning unknown byte ordering for current platform, assuming no swap
00040 # define LOADSAVE_SWAPBYTES 0
00041 # endif
00042 #endif
00043
00044 #endif
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 class LoadSave {
00096 public:
00097
00098 static const unsigned int stringpad=sizeof(unsigned int)+1;
00099
00100
00101
00102 LoadSave() {}
00103 virtual ~LoadSave();
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 virtual unsigned int getBinSize() const =0;
00119
00120
00121
00122
00123 virtual unsigned int loadBuffer(const char buf[], unsigned int len)=0;
00124
00125
00126
00127
00128 virtual unsigned int saveBuffer(char buf[], unsigned int len) const =0;
00129
00130
00131
00132
00133
00134
00135 virtual unsigned int loadFile(const char* filename);
00136 virtual unsigned int saveFile(const char* filename) const;
00137
00138
00139
00140
00141 virtual unsigned int loadFileStream(FILE* f);
00142
00143
00144
00145 virtual unsigned int saveFileStream(FILE* f) const;
00146
00147
00148 virtual unsigned int LoadFile(const char* filename) ATTR_deprecated;
00149
00150 virtual unsigned int SaveFile(const char* filename) const ATTR_deprecated;
00151
00152
00153
00154
00155
00156
00157
00158
00159 static inline bool checkInc(int res, const char*& buf, unsigned int& len) throw();
00160
00161
00162
00163
00164
00165
00166
00167
00168 static inline bool checkInc(int res, const char*& buf, unsigned int& len, const char* msg, ...) throw() __attribute__((format(printf,4,5)));
00169
00170
00171
00172
00173
00174
00175
00176 static inline bool checkInc(int res, char*& buf, unsigned int& len) throw();
00177
00178
00179
00180
00181
00182
00183
00184
00185 static inline bool checkInc(int res, char*& buf, unsigned int& len, const char* msg, ...) throw() __attribute__((format(printf,4,5)));
00186
00187
00188
00189
00190
00191
00192
00193 static inline void checkIncT(int res, const char*& buf, unsigned int& len, const char* msg="LoadSave::check underflow", ...) throw(std::length_error) __attribute__((format(printf,4,5)));
00194
00195
00196
00197
00198
00199
00200
00201 static inline void checkIncT(int res, char*& buf, unsigned int& len, const char* msg="LoadSave::check underflow", ...) throw(std::length_error) __attribute__((format(printf,4,5)));
00202
00203
00204
00205
00206
00207
00208 template <class T> static inline bool encodeInc(const T& value, char*& buf, unsigned int& cap) throw();
00209
00210
00211
00212
00213
00214
00215
00216 template <class T> static inline bool encodeInc(const T& value, char*& buf, unsigned int& cap, const char* msg, ...) throw() __attribute__((format(printf,4,5)));
00217
00218
00219
00220
00221
00222
00223 template <class T> static inline bool decodeInc(T& value, const char*& buf, unsigned int& cap) throw();
00224
00225
00226
00227
00228
00229
00230
00231 template <class T> static inline bool decodeInc(T& value, const char*& buf, unsigned int& cap, const char* msg, ...) throw() __attribute__((format(printf,4,5)));
00232
00233
00234
00235
00236
00237
00238 template <class T> static inline bool decodeInc(T& value, char*& buf, unsigned int& cap) throw();
00239
00240
00241
00242
00243
00244
00245
00246 template <class T> static inline bool decodeInc(T& value, char*& buf, unsigned int& cap, const char* msg, ...) throw() __attribute__((format(printf,4,5)));
00247
00248
00249
00250
00251
00252
00253 template <class T> static inline void encodeIncT(const T& value, char*& buf, unsigned int& cap, const char* msg="LoadSave::encode overflow", ...) throw(std::length_error) __attribute__((format(printf,4,5)));
00254
00255
00256
00257
00258
00259
00260 template <class T> static inline void decodeIncT(T& value, const char*& buf, unsigned int& cap, const char* msg="LoadSave::decode underflow", ...) throw(std::length_error) __attribute__((format(printf,4,5)));
00261
00262
00263
00264
00265
00266
00267 template <class T> static inline void decodeIncT(T& value, char*& buf, unsigned int& cap, const char* msg="LoadSave::decode underflow", ...) throw(std::length_error) __attribute__((format(printf,4,5)));
00268
00269
00270 static bool chkAdvance(int res, const char** buf, unsigned int* len, const char* msg, ...) ATTR_deprecated __attribute__((format(printf,4,5)));
00271
00272
00273
00274
00275
00276 inline static unsigned int getSerializedSize(const LoadSave& x) throw() { return x.getBinSize(); }
00277 inline static unsigned int getSerializedSize(const std::string& x) throw() { return x.size()+stringpad; }
00278 inline static unsigned int getSerializedSize(const char* x) throw() { unsigned int sz=strlen(x); return sz+stringpad; }
00279 inline static unsigned int getSerializedSize(const void*) throw() { return sizeof(unsigned long long); }
00280 inline static unsigned int getSerializedSize(const bool&) throw() { return sizeof(char); }
00281 template <class T> inline static unsigned int getSerializedSize(const T& x) throw() { return sizeof(x); }
00282
00283 template <class T> inline static unsigned int getSerializedSize() throw() { throw std::invalid_argument("The template argument passed to getSerializedSize() is not supported by LoadSave"); }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 virtual unsigned int creatorSize(const char creator[]) const { return strlen(creator)+stringpad; }
00295
00296
00297
00298
00299
00300
00301 virtual unsigned int checkCreator(const char* creator, const char buf[], unsigned int len, bool isLoading=true) const throw();
00302
00303
00304
00305
00306
00307
00308 virtual bool checkCreatorInc(const char* creator, const char*& buf, unsigned int& len, bool isLoading=true) const throw();
00309
00310
00311
00312
00313
00314 virtual void checkCreatorIncT(const char* creator, const char*& buf, unsigned int& len, bool isLoading=true) const throw(std::runtime_error);
00315
00316
00317
00318
00319
00320 virtual unsigned int checkCreator(const char* creator, FILE* f, bool isLoading=true) const throw();
00321
00322
00323
00324
00325
00326 virtual unsigned int saveCreator(const char* creator, char buf[], unsigned int len) const throw();
00327
00328
00329
00330
00331
00332 virtual bool saveCreatorInc(const char* creator, char*& buf, unsigned int& len) const throw();
00333
00334
00335
00336
00337 virtual void saveCreatorIncT(const char* creator, char*& buf, unsigned int& len) const throw(std::runtime_error);
00338
00339
00340
00341
00342 virtual unsigned int saveCreator(const char* creator, FILE* f) const throw();
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 inline static unsigned int encode(const LoadSave& x, char buf[], unsigned int cap) { return x.saveBuffer(buf,cap); }
00356 inline static unsigned int decode(LoadSave& x, const char buf[], unsigned int cap) { return x.loadBuffer(buf,cap); }
00357 inline static unsigned int encode(const LoadSave& x, FILE* f) { return x.saveFileStream(f); }
00358 inline static unsigned int decode(LoadSave& x, FILE* f) { return x.loadFileStream(f); }
00359
00360 #if LOADSAVE_SWAPBYTES
00361
00362 inline static unsigned int encode(const double x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(double*)buf,x); return sizeof(x); }
00363 inline static unsigned int decode(double& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const double*)buf); return sizeof(x);}
00364 inline static unsigned int encode(const double x, FILE* f) throw() { double t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00365 inline static unsigned int decode(double& x, FILE* f) throw() { double t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00366
00367 inline static unsigned int encode(const float x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(float*)buf,x); return sizeof(x); }
00368 inline static unsigned int decode(float& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const float*)buf); return sizeof(x);}
00369 inline static unsigned int encode(const float x, FILE* f) throw() { float t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00370 inline static unsigned int decode(float& x, FILE* f) throw() { float t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00371
00372 inline static unsigned int encode(const long long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(long long*)buf,x); return sizeof(x); }
00373 inline static unsigned int decode(long long& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const long long*)buf); return sizeof(x);}
00374 inline static unsigned int encode(const long long x, FILE* f) throw() { long long t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00375 inline static unsigned int decode(long long& x, FILE* f) throw() { long long t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00376 inline static unsigned int encode(const unsigned long long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(unsigned long long*)buf,x); return sizeof(x); }
00377 inline static unsigned int decode(unsigned long long& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const unsigned long long*)buf); return sizeof(x);}
00378 inline static unsigned int encode(const unsigned long long x, FILE* f) throw() { unsigned long long t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00379 inline static unsigned int decode(unsigned long long& x, FILE* f) throw() { unsigned long long t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00380
00381 inline static unsigned int encode(const long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(long*)buf,x); return sizeof(x); }
00382 inline static unsigned int decode(long& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const long*)buf); return sizeof(x);}
00383 inline static unsigned int encode(const long x, FILE* f) throw() { long t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00384 inline static unsigned int decode(long& x, FILE* f) throw() { long t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00385 inline static unsigned int encode(const unsigned long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(unsigned long*)buf,x); return sizeof(x); }
00386 inline static unsigned int decode(unsigned long& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const unsigned long*)buf); return sizeof(x);}
00387 inline static unsigned int encode(const unsigned long x, FILE* f) throw() { unsigned long t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00388 inline static unsigned int decode(unsigned long& x, FILE* f) throw() { unsigned long t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00389
00390 inline static unsigned int encode(const int x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(int*)buf,x); return sizeof(x); }
00391 inline static unsigned int decode(int& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const int*)buf); return sizeof(x);}
00392 inline static unsigned int encode(const int x, FILE* f) throw() { int t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00393 inline static unsigned int decode(int& x, FILE* f) throw() { int t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00394 inline static unsigned int encode(const unsigned int x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(unsigned int*)buf,x); return sizeof(x); }
00395 inline static unsigned int decode(unsigned int& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const unsigned int*)buf); return sizeof(x);}
00396 inline static unsigned int encode(const unsigned int x, FILE* f) throw() { unsigned int t=0; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00397 inline static unsigned int decode(unsigned int& x, FILE* f) throw() { unsigned int t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00398
00399 inline static unsigned int encode(const short x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(short*)buf,x); return sizeof(x); }
00400 inline static unsigned int decode(short& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(x,*(const short*)buf); return sizeof(x);}
00401 inline static unsigned int encode(const short x, FILE* f) throw() { short t; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00402 inline static unsigned int decode(short& x, FILE* f) throw() { short t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00403 inline static unsigned int encode(const unsigned short x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; byteswap(*(unsigned short*)buf,x); return sizeof(x); }
00404 inline static unsigned int decode(unsigned short& x, const char buf[], unsigned int cap) throw(){ if(cap<sizeof(x)) return 0; byteswap(x,*(const unsigned short*)buf); return sizeof(x);}
00405 inline static unsigned int encode(const unsigned short x, FILE* f) throw() { unsigned short t; byteswap(t,x); return sizeof(x)*fwrite(&t,sizeof(x),1,f); }
00406 inline static unsigned int decode(unsigned short& x, FILE* f) throw() { unsigned short t=0; if(fread(&t,sizeof(x),1,f)==0) return 0; byteswap(x,t); return sizeof(x);}
00407
00408 #else
00409
00410 inline static unsigned int encode(const double x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00411 inline static unsigned int decode(double& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00412 inline static unsigned int encode(const double x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00413 inline static unsigned int decode(double& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00414
00415 inline static unsigned int encode(const float x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00416 inline static unsigned int decode(float& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00417 inline static unsigned int encode(const float x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00418 inline static unsigned int decode(float& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00419
00420 inline static unsigned int encode(const long long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00421 inline static unsigned int decode(long long& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00422 inline static unsigned int encode(const long long x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00423 inline static unsigned int decode(long long& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00424 inline static unsigned int encode(const unsigned long long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00425 inline static unsigned int decode(unsigned long long& x, const char buf[], unsigned int cap) throw(){ if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00426 inline static unsigned int encode(const unsigned long long x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00427 inline static unsigned int decode(unsigned long long& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00428
00429 inline static unsigned int encode(const long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00430 inline static unsigned int decode(long& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00431 inline static unsigned int encode(const long x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00432 inline static unsigned int decode(long& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00433 inline static unsigned int encode(const unsigned long x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00434 inline static unsigned int decode(unsigned long& x, const char buf[], unsigned int cap) throw(){ if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00435 inline static unsigned int encode(const unsigned long x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00436 inline static unsigned int decode(unsigned long& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00437
00438 inline static unsigned int encode(const int x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00439 inline static unsigned int decode(int& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00440 inline static unsigned int encode(const int x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00441 inline static unsigned int decode(int& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00442 inline static unsigned int encode(const unsigned int x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00443 inline static unsigned int decode(unsigned int& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00444 inline static unsigned int encode(const unsigned int x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00445 inline static unsigned int decode(unsigned int& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00446
00447 inline static unsigned int encode(const short x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00448 inline static unsigned int decode(short& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00449 inline static unsigned int encode(const short x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00450 inline static unsigned int decode(short& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00451 inline static unsigned int encode(const unsigned short x, char buf[], unsigned int cap) throw(){ if(cap<sizeof(x)) return 0; memcpy(buf,&x,sizeof(x)); return sizeof(x); }
00452 inline static unsigned int decode(unsigned short& x, const char buf[], unsigned int cap){ if(cap<sizeof(x)) return 0; memcpy(&x,buf,sizeof(x)); return sizeof(x); }
00453 inline static unsigned int encode(const unsigned short x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00454 inline static unsigned int decode(unsigned short& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00455
00456 #endif //end of big/little endian differences
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 inline static unsigned int encode(const std::string& x, char buf[], unsigned int cap) throw() { if(cap<sizeof(unsigned int)+x.size()+1) return 0; memcpy(buf+encode(static_cast<unsigned int>(x.size()),buf,cap),x.c_str(),x.size()+1); return x.size()+stringpad; }
00467 inline static unsigned int decode(std::string& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(unsigned int)) return 0; unsigned int sz=0; decode(sz,buf,cap); if(cap<sizeof(unsigned int)+sz+1) return 0; x.assign(buf+sizeof(unsigned int),sz); return x.size()+stringpad; }
00468 inline static unsigned int encode(const std::string& x, FILE* f) throw() { encode(static_cast<unsigned int>(x.size()),f); return sizeof(unsigned int)+fwrite(x.c_str(),1,sizeof(x)+1,f); }
00469 inline static unsigned int decode(std::string& x, FILE* f) throw() { unsigned int sz=0; decode(sz,f); char *tmp=new char[sz+1]; if(fread(tmp,1,sz+1,f)!=sz+1) { delete [] tmp; return 0; } x.assign(tmp,sz); delete [] tmp; return sz+stringpad; }
00470
00471 inline static unsigned int encode(const char* x, char buf[], unsigned int cap) throw() { unsigned int sz=strlen(x); if(cap<sizeof(unsigned int)+sz+1) return 0; memcpy(buf+encode(sz,buf,cap),x,sz+1); return sz+stringpad; }
00472 inline static unsigned int decode(char*& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(unsigned int)) return 0; unsigned int sz=0; decode(sz,buf,cap); if(cap<sizeof(unsigned int)+sz+1) return 0; x=new char[sz+1]; strncpy(x,buf+sizeof(unsigned int),sz+1); return sz+stringpad; }
00473 inline static unsigned int encode(const char* x, FILE* f) throw() { unsigned int sz=strlen(x); encode(sz,f); return sizeof(unsigned int)+fwrite(x,1,sz+1,f); }
00474 inline static unsigned int decode(char*& x, FILE* f) throw() { unsigned int sz=0; decode(sz,f); x=new char[sz+1]; if(fread(x,1,sz+1,f)!=sz+1) { delete [] x; x=NULL; return 0; } return sz+stringpad; }
00475
00476 inline static unsigned int encode(const char x, char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; buf[0]=x; return sizeof(x); }
00477 inline static unsigned int decode(char& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(x)) return 0; x=buf[0]; return sizeof(x);}
00478 inline static unsigned int encode(const char x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00479 inline static unsigned int decode(char& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00480 inline static unsigned int encode(const unsigned char x, char buf[], unsigned int cap) throw(){ if(cap<sizeof(x)) return 0; buf[0]=(char)x; return sizeof(x); }
00481 inline static unsigned int decode(unsigned char& x, const char buf[], unsigned int cap){ if(cap<sizeof(x)) return 0; x=(unsigned char)buf[0]; return sizeof(x);}
00482 inline static unsigned int encode(const unsigned char x, FILE* f) throw() { return sizeof(x)*fwrite(&x,sizeof(x),1,f); }
00483 inline static unsigned int decode(unsigned char& x, FILE* f) throw() { return sizeof(x)*fread(&x,sizeof(x),1,f); }
00484
00485 inline static unsigned int encode(const bool x, char buf[], unsigned int cap) throw() { if(cap<sizeof(char)) return 0; buf[0]=(char)(x?1:0); return sizeof(char); }
00486 inline static unsigned int decode(bool& x, const char buf[], unsigned int cap) throw() { if(cap<sizeof(char)) return 0; x=(buf[0]!=(char)0); return sizeof(char);}
00487 inline static unsigned int encode(const bool x, FILE* f) throw() { char t=(char)(x?1:0); return sizeof(char)*fwrite(&t,sizeof(char),1,f); }
00488 inline static unsigned int decode(bool& x, FILE* f) throw() { char t='\0'; fread(&t,sizeof(char),1,f); x=(t!=(char)0); return sizeof(char); }
00489
00490 protected:
00491
00492 template<class T> inline static void byteswap(T& dstc, const T& srcc) throw() {
00493 char* dst=(char*)&dstc;
00494 const char* src=(const char*)&srcc;
00495 for(unsigned int i=0; i<sizeof(T); i++)
00496 dst[sizeof(T)-1-i]=src[i];
00497 }
00498
00499
00500 #if defined(NEED_ASPRINTF)
00501 int vasprintf(char** ret, const char* format, va_list al) {
00502 va_list tmpal;
00503 va_copy(tmpal,al);
00504 int nc=vsnprintf(NULL,0,format,tmpal);
00505 *ret = (char*)malloc(nc+1);
00506 if(*ret==NULL) return -1;
00507 return vsnprintf(*ret,nc+1,format,al);
00508 }
00509 int asprintf(char **ret, const char *format, ...) {
00510 va_list ap;
00511 va_start (ap, format);
00512 int nc= vasprintf(ret, format, ap);
00513 va_end(ap);
00514 return nc;
00515 }
00516 #endif
00517 };
00518
00519
00520 #ifndef __DOXYGEN__
00521
00522 template <> inline unsigned int LoadSave::getSerializedSize<void*>() throw() { return sizeof(unsigned long long); }
00523 template <> inline unsigned int LoadSave::getSerializedSize<bool>() throw() { return sizeof(char); }
00524 template <> inline unsigned int LoadSave::getSerializedSize<char>() throw() { return sizeof(char); }
00525 template <> inline unsigned int LoadSave::getSerializedSize<unsigned char>() throw() { return sizeof(unsigned char); }
00526 template <> inline unsigned int LoadSave::getSerializedSize<short>() throw() { return sizeof(short); }
00527 template <> inline unsigned int LoadSave::getSerializedSize<unsigned short>() throw() { return sizeof(unsigned short); }
00528 template <> inline unsigned int LoadSave::getSerializedSize<int>() throw() { return sizeof(int); }
00529 template <> inline unsigned int LoadSave::getSerializedSize<unsigned int>() throw() { return sizeof(unsigned int); }
00530 template <> inline unsigned int LoadSave::getSerializedSize<long>() throw() { return sizeof(long); }
00531 template <> inline unsigned int LoadSave::getSerializedSize<unsigned long>() throw() { return sizeof(unsigned long); }
00532 template <> inline unsigned int LoadSave::getSerializedSize<long long>() throw() { return sizeof(long long); }
00533 template <> inline unsigned int LoadSave::getSerializedSize<unsigned long long>() throw() { return sizeof(unsigned long long); }
00534 template <> inline unsigned int LoadSave::getSerializedSize<float>() throw() { return sizeof(float); }
00535 template <> inline unsigned int LoadSave::getSerializedSize<double>() throw() { return sizeof(double); }
00536
00537 template <> inline unsigned int LoadSave::getSerializedSize<char*>() throw(std::invalid_argument) { throw std::invalid_argument("Cannot pass string as template arg to getSerializedSize() -- need instance to know length!"); }
00538 template <> inline unsigned int LoadSave::getSerializedSize<std::string>() throw(std::invalid_argument) { throw std::invalid_argument("Cannot pass string as template arg to getSerializedSize() -- need instance to know length!"); }
00539 template <> inline unsigned int LoadSave::getSerializedSize<LoadSave>() throw(std::invalid_argument) { throw std::invalid_argument("Cannot pass LoadSave subclass as template arg to getSerializedSize() -- need instance to know length!\nIf the subclass in question has a static size, you could add a getSerializedSize() template specialization to do the size calculation (and have getBinSize return that)."); }
00540 #endif
00541
00542 bool LoadSave::checkInc(int res, const char*& buf, unsigned int& len) throw() {
00543 if(res<0 || (unsigned int)res>len)
00544 return false;
00545 buf+=res;
00546 len-=res;
00547 return true;
00548 }
00549
00550 bool LoadSave::checkInc(int res, const char*& buf, unsigned int& len, const char* msg, ...) throw() {
00551 if(checkInc(res,buf,len))
00552 return true;
00553 if(msg[0]!='\0') {
00554 if((unsigned int)res>len)
00555 fprintf(stderr,"*** WARNING: reported check result length exceeded remaining buffer size; %u (signed %d) vs %u\n",(unsigned int)res,res,len);
00556 va_list al;
00557 va_start(al,msg);
00558 vfprintf(stderr,msg,al);
00559 va_end(al);
00560 }
00561 return false;
00562 }
00563
00564 bool LoadSave::checkInc(int res, char*& buf, unsigned int& len) throw() {
00565 if(res<0 || (unsigned int)res>len)
00566 return false;
00567 buf+=res;
00568 len-=res;
00569 return true;
00570 }
00571
00572 bool LoadSave::checkInc(int res, char*& buf, unsigned int& len, const char* msg, ...) throw() {
00573 if(checkInc(res,buf,len))
00574 return true;
00575 if(msg[0]!='\0') {
00576 if((unsigned int)res>len)
00577 fprintf(stderr,"*** WARNING: reported check result length exceeded remaining buffer size; %u (signed %d) vs %u\n",(unsigned int)res,res,len);
00578 va_list al;
00579 va_start(al,msg);
00580 vfprintf(stderr,msg,al);
00581 va_end(al);
00582 }
00583 return false;
00584 }
00585
00586 void LoadSave::checkIncT(int res, const char*& buf, unsigned int& len, const char* msg, ...) throw(std::length_error) {
00587 if(res>0 && (unsigned int)res<=len) {
00588 buf+=res;
00589 len-=res;
00590 } else {
00591 if((unsigned int)res>len && msg[0]!='\0')
00592 fprintf(stderr,"*** WARNING: reported check result length exceeded remaining buffer size; %u (signed %d) vs %u\n",(unsigned int)res,res,len);
00593 va_list al;
00594 va_start(al,msg);
00595 char * errmsg;
00596 vasprintf(&errmsg,msg,al);
00597 va_end(al);
00598 if(errmsg==NULL)
00599 throw std::length_error("unspecified");
00600 std::string serrmsg=errmsg;
00601 free(errmsg);
00602 throw std::length_error(serrmsg);
00603 }
00604 }
00605
00606 void LoadSave::checkIncT(int res, char*& buf, unsigned int& len, const char* msg, ...) throw(std::length_error) {
00607 if(res>0 && (unsigned int)res<=len) {
00608 buf+=res;
00609 len-=res;
00610 } else {
00611 if((unsigned int)res>len && msg[0]!='\0')
00612 fprintf(stderr,"*** WARNING: reported check result length exceeded remaining buffer size; %u (signed %d) vs %u\n",(unsigned int)res,res,len);
00613 va_list al;
00614 va_start(al,msg);
00615 char * errmsg;
00616 vasprintf(&errmsg,msg,al);
00617 va_end(al);
00618 if(errmsg==NULL)
00619 throw std::length_error("unspecified");
00620 std::string serrmsg=errmsg;
00621 free(errmsg);
00622 throw std::length_error(serrmsg);
00623 }
00624 }
00625
00626 template <class T>
00627 bool LoadSave::encodeInc(const T& value, char*& buf, unsigned int& cap) throw() {
00628 unsigned int res=encode(value,buf,cap);
00629 if(res==0)
00630 return false;
00631 #ifdef LOADSAVE_DEBUG
00632 if(res>cap) {
00633 fprintf(stderr,"*** WARNING: reported encode result length exceeded remaining buffer size; %u (signed %d) vs %u\n",res,(int)res,cap);
00634 return false;
00635 }
00636 #endif
00637 buf+=res;
00638 cap-=res;
00639 return true;
00640 }
00641 template <class T>
00642 bool LoadSave::encodeInc(const T& value, char*& buf, unsigned int& cap, const char* msg, ...) throw() {
00643 if(encodeInc(value,buf,cap))
00644 return true;
00645 if(msg[0]!='\0') {
00646 va_list al;
00647 va_start(al,msg);
00648 vfprintf(stderr,msg,al);
00649 va_end(al);
00650 }
00651 return false;
00652 }
00653 template <class T>
00654 bool LoadSave::decodeInc(T& value, const char*& buf, unsigned int& cap) throw() {
00655 unsigned int res=decode(value,buf,cap);
00656 if(res==0)
00657 return false;
00658 #ifdef LOADSAVE_DEBUG
00659 if(res>cap) {
00660 fprintf(stderr,"*** WARNING: reported decode result length exceeded remaining buffer size; %u (signed %d) vs %u\n",res,(int)res,cap);
00661 return false;
00662 }
00663 #endif
00664 buf+=res;
00665 cap-=res;
00666 return true;
00667 }
00668 template <class T>
00669 bool LoadSave::decodeInc(T& value, const char*& buf, unsigned int& cap, const char* msg, ...) throw() {
00670 if(decodeInc(value,buf,cap))
00671 return true;
00672 if(msg[0]!='\0') {
00673 va_list al;
00674 va_start(al,msg);
00675 vfprintf(stderr,msg,al);
00676 va_end(al);
00677 }
00678 return false;
00679 }
00680 template <class T>
00681 bool LoadSave::decodeInc(T& value, char*& buf, unsigned int& cap) throw() {
00682 unsigned int res=decode(value,buf,cap);
00683 if(res==0)
00684 return false;
00685 #ifdef LOADSAVE_DEBUG
00686 if(res>cap) {
00687 fprintf(stderr,"*** WARNING: reported decode result length exceeded remaining buffer size; %u (signed %d) vs %u\n",res,(int)res,cap);
00688 return false;
00689 }
00690 #endif
00691 buf+=res;
00692 cap-=res;
00693 return true;
00694 }
00695 template <class T>
00696 bool LoadSave::decodeInc(T& value, char*& buf, unsigned int& cap, const char* msg, ...) throw() {
00697 if(decodeInc(value,buf,cap))
00698 return true;
00699 if(msg[0]!='\0') {
00700 va_list al;
00701 va_start(al,msg);
00702 vfprintf(stderr,msg,al);
00703 va_end(al);
00704 }
00705 return false;
00706 }
00707
00708 template <class T>
00709 void LoadSave::encodeIncT(const T& value, char*& buf, unsigned int& cap, const char* msg, ...) throw(std::length_error) {
00710 unsigned int res=encode(value,buf,cap);
00711 #ifdef LOADSAVE_DEBUG
00712 if(res==0 || res>cap) {
00713 if(res>cap)
00714 fprintf(stderr,"*** WARNING: encode reported result length exceeded remaining buffer size; %u (signed %d) vs %u\n",res,(int)res,cap);
00715 #else
00716 if(res==0) {
00717 #endif
00718 va_list al;
00719 va_start(al,msg);
00720 char * errmsg;
00721 vasprintf(&errmsg,msg,al);
00722 va_end(al);
00723 if(errmsg==NULL)
00724 throw std::length_error("unspecified");
00725 std::string serrmsg=errmsg;
00726 free(errmsg);
00727 throw std::length_error(serrmsg);
00728
00729 #ifdef LOADSAVE_DEBUG
00730 }
00731 #else
00732 }
00733 #endif
00734 buf+=res;
00735 cap-=res;
00736 }
00737 template <class T>
00738 void LoadSave::decodeIncT(T& value, const char*& buf, unsigned int& cap, const char* msg, ...) throw(std::length_error) {
00739 unsigned int res=decode(value,buf,cap);
00740 #ifdef LOADSAVE_DEBUG
00741 if(res==0 || res>cap) {
00742 if(res>cap)
00743 fprintf(stderr,"*** WARNING: decode reported result length exceeded remaining buffer size; %u (signed %d) vs %u\n",res,(int)res,cap);
00744 #else
00745 if(res==0) {
00746 #endif
00747 va_list al;
00748 va_start(al,msg);
00749 char * errmsg;
00750 vasprintf(&errmsg,msg,al);
00751 va_end(al);
00752 if(errmsg==NULL)
00753 throw std::length_error("unspecified");
00754 std::string serrmsg=errmsg;
00755 free(errmsg);
00756 throw std::length_error(serrmsg);
00757
00758 #ifdef LOADSAVE_DEBUG
00759 }
00760 #else
00761 }
00762 #endif
00763 buf+=res;
00764 cap-=res;
00765 }
00766 template <class T>
00767 void LoadSave::decodeIncT(T& value, char*& buf, unsigned int& cap, const char* msg, ...) throw(std::length_error) {
00768 unsigned int res=decode(value,buf,cap);
00769 #ifdef LOADSAVE_DEBUG
00770 if(res==0 || res>cap) {
00771 if(res>cap)
00772 fprintf(stderr,"*** WARNING: decode reported result length exceeded remaining buffer size; %u (signed %d) vs %u\n",res,(int)res,cap);
00773 #else
00774 if(res==0) {
00775 #endif
00776 va_list al;
00777 va_start(al,msg);
00778 char * errmsg;
00779 vasprintf(&errmsg,msg,al);
00780 va_end(al);
00781 if(errmsg==NULL)
00782 throw std::length_error("unspecified");
00783 std::string serrmsg=errmsg;
00784 free(errmsg);
00785 throw std::length_error(serrmsg);
00786
00787 #ifdef LOADSAVE_DEBUG
00788 }
00789 #else
00790 }
00791 #endif
00792 buf+=res;
00793 cap-=res;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 #endif