00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef FXSTREAM_H
00026 #define FXSTREAM_H
00027
00028 #include "fxdefs.h"
00029 #include "fxver.h"
00030 #include "QIODevice.h"
00031 #include "FXGenericTools.h"
00032
00033 namespace FX {
00034
00039 namespace Generic
00040 {
00041 template<typename type> struct hasSerialise;
00042 template<typename type> struct hasDeserialise;
00043 namespace hasSerialiseImpl
00044 {
00045 struct FakeStreamTypeBase { };
00046 }
00047 }
00048
00049
00051 enum FXStreamDirection {
00052 FXStreamDead=0,
00053 FXStreamSave=1,
00054 FXStreamLoad=2
00055 };
00056
00057
00059 enum FXStreamStatus {
00060 FXStreamOK=0,
00061 FXStreamEnd=1,
00062 FXStreamFull=2,
00063 FXStreamNoWrite=3,
00064 FXStreamNoRead=4,
00065 FXStreamFormat=5,
00066 FXStreamUnknown=6,
00067 FXStreamAlloc=7,
00068 FXStreamFailure=8
00069 };
00070
00071
00073 enum FXWhence {
00074 FXFromStart=0,
00075 FXFromCurrent=1,
00076 FXFromEnd=2
00077 };
00078
00079
00080 class FXHash;
00081 class FXString;
00082 class QIODevice;
00083
00084
00085
00142 class FXStreamBase
00143 {
00144 friend FXStreamBase &operator<<(FXStreamBase &, const Generic::hasSerialiseImpl::FakeStreamTypeBase &);
00145 friend FXStreamBase &operator>>(FXStreamBase &, const Generic::hasSerialiseImpl::FakeStreamTypeBase &);
00146 };
00147 class FXAPI FXStream : private FXStreamBase
00148 {
00149 template<typename type> friend struct Generic::hasSerialise;
00150 template<typename type> friend struct Generic::hasDeserialise;
00151 protected:
00152 FXHash *hash;
00153 const FXObject *parent;
00154 FXuchar *begptr;
00155 FXuchar *endptr;
00156 FXuchar *wrptr;
00157 FXuchar *rdptr;
00158 FXlong pos;
00159 FXStreamDirection dir;
00160 FXStreamStatus code;
00161 FXuint seq;
00162 bool owns;
00163 bool swap;
00164
00165 protected:
00166 QIODevice *dev;
00167 public:
00168
00170 FXStream(QIODevice *dev=0, const FXObject* cont=NULL);
00171
00173 QIODevice *device() const { return dev; }
00175 void setDevice(QIODevice *dev);
00177 FXDEPRECATEDEXT void unsetDevice() { setDevice(0); }
00179 bool atEnd() const { return dev->atEnd(); }
00180
00181 enum ByteOrder
00182 {
00183 BigEndian=0,
00184 LittleEndian
00185 };
00187 int byteOrder() const { return ((swap!=0)==!FOX_BIGENDIAN) ? BigEndian : LittleEndian; }
00189 void setByteOrder(int b) { swap=(b==BigEndian) ? !FOX_BIGENDIAN : FOX_BIGENDIAN; }
00190
00192 FXDEPRECATEDEXT FXStream &readBytes(char *&s, FXuint &l);
00194 FXStream &readRawBytes(char *buffer, FXuval len)
00195 {
00196 if(len!=dev->readBlock(buffer, len)) int_throwPrematureEOF();
00197 return *this;
00198 }
00199
00201 FXStream &readRawBytes(FXuchar *buffer, FXuval len) { return readRawBytes((char *) buffer, len); }
00203 FXDEPRECATEDEXT FXStream &writeBytes(const char *s, FXuint l);
00205 FXStream &writeRawBytes(const char *buffer, FXuval len)
00206 {
00207 dev->writeBlock(buffer, len);
00208 return *this;
00209 }
00211 FXStream &writeRawBytes(const FXuchar *buffer, FXuval len) { return writeRawBytes((char *) buffer, len); }
00212
00214 FXfval rewind(FXint amount);
00215
00216 protected:
00217
00222 virtual FXuval writeBuffer(FXuval count);
00223
00228 virtual FXuval readBuffer(FXuval count);
00229
00230 public:
00231
00239 FXDEPRECATEDEXT FXStream(const FXObject* cont);
00240
00248 FXDEPRECATEDEXT bool open(FXStreamDirection save_or_load,FXuval size=8192,FXuchar* data=NULL);
00249
00254 virtual FXDEPRECATEDEXT bool flush();
00255
00260 virtual bool close();
00261
00266 FXDEPRECATEDEXT FXuval getSpace() const;
00267
00272 FXDEPRECATEDEXT void setSpace(FXuval sp);
00273
00278 FXDEPRECATEDEXT FXStreamStatus status() const { return code; }
00279
00281 bool eof() const { return atEnd(); }
00282
00287 FXDEPRECATEDEXT void setError(FXStreamStatus err);
00288
00293 FXDEPRECATEDEXT FXStreamDirection direction() const { return dir; }
00294
00299 FXDEPRECATEDEXT const FXObject* container() const { return parent; }
00300
00302 FXlong position() const;
00303
00305 virtual bool position(FXlong offset,FXWhence whence=FXFromStart);
00306
00308 void swapBytes(FXint s){ swap=(s<0) ? !FOX_BIGENDIAN : (s!=0); }
00309
00313 bool swapBytes() const { return swap; }
00314
00320 void setBigEndian(bool big){ swap=(big^FOX_BIGENDIAN); }
00321
00325 bool isBigEndian() const { return (swap^FOX_BIGENDIAN); }
00326 private:
00327 void int_throwPrematureEOF();
00328 public:
00330 friend inline FXStream& operator<<(FXStream& s, const FXuchar& v)
00331 {
00332 s.dev->putch(v);
00333 return s;
00334 }
00335 friend inline FXStream& operator<<(FXStream& s, const FXchar& v){ return s << reinterpret_cast<const FXuchar&>(v); }
00336 friend inline FXStream& operator<<(FXStream& s, const FXushort& _v)
00337 {
00338 FXushort v=_v;
00339 if(s.swap){fxendianswap(v);}
00340 s.dev->writeBlock((char *) &v,2);
00341 return s;
00342 }
00343 friend inline FXStream& operator<<(FXStream& s, const FXshort& v){ return s << reinterpret_cast<const FXushort&>(v); }
00344 friend inline FXStream& operator<<(FXStream& s, const FXuint& _v)
00345 {
00346 FXuint v=_v;
00347 if(s.swap){fxendianswap(v);}
00348 s.dev->writeBlock((char *) &v,4);
00349 return s;
00350 }
00351 friend inline FXStream& operator<<(FXStream& s, const FXint& v){ return s << reinterpret_cast<const FXuint&>(v); }
00352 friend inline FXStream& operator<<(FXStream& s, const FXfloat& _v)
00353 {
00354 FXuint v=*(FXuint *)&_v;
00355 if(s.swap){fxendianswap(v);}
00356 s.dev->writeBlock((char *) &v,4);
00357 return s;
00358 }
00359 friend inline FXStream& operator<<(FXStream& s, const FXdouble& _v)
00360 {
00361 FXulong v=*(FXulong *)&_v;
00362 if(s.swap){fxendianswap(v);}
00363 s.dev->writeBlock((char *) &v,8);
00364 return s;
00365 }
00366 friend inline FXStream& operator<<(FXStream& s, const FXlong& v){ return s << reinterpret_cast<const FXulong&>(v); }
00367 friend inline FXStream& operator<<(FXStream& s, const FXulong& _v)
00368 {
00369 FXulong v=_v;
00370 if(s.swap){fxendianswap(v);}
00371 s.dev->writeBlock((char *) &v,8);
00372 return s;
00373 }
00374 friend inline FXStream& operator<<(FXStream& s, const char *v)
00375 {
00376 s.dev->writeBlock(v, strlen(v));
00377 return s;
00378 }
00379 friend inline FXStream& operator<<(FXStream& s, const bool& _v)
00380 {
00381 s.dev->putch(_v);
00382 return s;
00383 }
00384
00386 inline FXStream& save(const FXuchar* p,unsigned long n){
00387 FXASSERT(n==0 || (n>0 && p!=NULL));
00388 dev->writeBlock((char *) p,n);
00389 return *this;
00390 }
00391 FXStream& save(const FXchar* p,unsigned long n){ return save(reinterpret_cast<const FXuchar*>(p),n); }
00392 FXStream& save(const FXushort* p,unsigned long n);
00393 FXStream& save(const FXshort* p,unsigned long n){ return save(reinterpret_cast<const FXushort*>(p),n); }
00394 FXStream& save(const FXuint* p,unsigned long n);
00395 FXStream& save(const FXint* p,unsigned long n){ return save(reinterpret_cast<const FXuint*>(p),n); }
00396 FXStream& save(const FXfloat* p,unsigned long n);
00397 FXStream& save(const FXdouble* p,unsigned long n);
00398 FXStream& save(const FXlong* p,unsigned long n){ return save(reinterpret_cast<const FXulong*>(p),n); }
00399 FXStream& save(const FXulong* p,unsigned long n);
00400
00402 friend inline FXStream& operator>>(FXStream& s, FXuchar& v)
00403 {
00404 int _v=s.dev->getch();
00405 v=(FXuchar) _v;
00406 if(-1==_v) s.int_throwPrematureEOF();
00407 return s;
00408 }
00409 friend inline FXStream& operator>>(FXStream& s, FXchar& v){ return s >> reinterpret_cast<FXuchar&>(v); }
00410 friend inline FXStream& operator>>(FXStream& s, FXushort& v)
00411 {
00412 if(2!=s.dev->readBlock((char *) &v,2)) s.int_throwPrematureEOF();
00413 if(s.swap){fxendianswap(v);}
00414 return s;
00415 }
00416 friend inline FXStream& operator>>(FXStream& s, FXshort& v){ return s >> reinterpret_cast<FXushort&>(v); }
00417 friend inline FXStream& operator>>(FXStream& s, FXuint& v)
00418 {
00419 if(4!=s.dev->readBlock((char *) &v,4)) s.int_throwPrematureEOF();
00420 if(s.swap){fxendianswap(v);}
00421 return s;
00422 }
00423 friend inline FXStream& operator>>(FXStream& s, FXint& v){ return s >> reinterpret_cast<FXuint&>(v); }
00424 friend inline FXStream& operator>>(FXStream& s, FXfloat& v)
00425 {
00426 if(4!=s.dev->readBlock((char *) &v,4)) s.int_throwPrematureEOF();
00427 if(s.swap){fxendianswap(*(FXuint *)&v);}
00428 return s;
00429 }
00430 friend inline FXStream& operator>>(FXStream& s, FXdouble& v)
00431 {
00432 if(8!=s.dev->readBlock((char *) &v,8)) s.int_throwPrematureEOF();
00433 if(s.swap){fxendianswap(*(FXulong *)&v);}
00434 return s;
00435 }
00436 friend inline FXStream& operator>>(FXStream& s, FXlong& v){ return s >> reinterpret_cast<FXulong&>(v); }
00437 friend inline FXStream& operator>>(FXStream& s, FXulong& v)
00438 {
00439 if(8!=s.dev->readBlock((char *) &v,8)) s.int_throwPrematureEOF();
00440 if(s.swap){fxendianswap(v);}
00441 return s;
00442 }
00443 friend inline FXStream& operator>>(FXStream& s, bool& v)
00444 {
00445 int _v=s.dev->getch();
00446 v=(_v!=0);
00447 if(-1==_v) s.int_throwPrematureEOF();
00448 return s;
00449 }
00450
00451
00453 FXStream& load(FXuchar* p,unsigned long n){
00454 FXASSERT(n==0 || (n>0 && p!=NULL));
00455 if(n!=dev->readBlock((char *) p,n)) int_throwPrematureEOF();
00456 return *this;
00457 }
00458 FXStream& load(FXchar* p,unsigned long n){ return load(reinterpret_cast<FXuchar*>(p),n); }
00459 FXStream& load(FXushort* p,unsigned long n);
00460 FXStream& load(FXshort* p,unsigned long n){ return load(reinterpret_cast<FXushort*>(p),n); }
00461 FXStream& load(FXuint* p,unsigned long n);
00462 FXStream& load(FXint* p,unsigned long n){ return load(reinterpret_cast<FXuint*>(p),n); }
00463 FXStream& load(FXfloat* p,unsigned long n);
00464 FXStream& load(FXdouble* p,unsigned long n);
00465 FXStream& load(FXlong* p,unsigned long n){ return load(reinterpret_cast<FXulong*>(p),n); }
00466 FXStream& load(FXulong* p,unsigned long n);
00467
00469 FXStream& saveObject(const FXObject* v);
00470
00472 FXStream& loadObject(FXObject*& v);
00473
00475 FXStream& addObject(const FXObject* v);
00476
00478 virtual ~FXStream();
00479 };
00480
00482 typedef FXStream QDataStream;
00483
00484
00485 inline FXStream &operator<<(FXStream &store, const FXString &s)
00486 {
00487 FXint len=s.length();
00488 store << len;
00489 store.save(s.str,len);
00490 return store;
00491 }
00492 inline FXStream &operator>>(FXStream &store, FXString &s)
00493 {
00494 FXint len;
00495 store >> len;
00496 s.length(len);
00497 store.load(s.str,len);
00498 return store;
00499 }
00500
00501
00502 namespace Generic
00503 {
00504 namespace hasSerialiseImpl
00505 {
00506 template<bool isIntegralOrPtr, typename type> struct FakeStreamType : type
00507 {
00508 operator hasSerialiseImpl::FakeStreamTypeBase &();
00509 };
00510 template<typename type> struct FakeStreamType<true, type>
00511 {
00512 operator type &();
00513 operator hasSerialiseImpl::FakeStreamTypeBase &();
00514 };
00515 }
00520 template<typename type> struct hasSerialise
00521 {
00522 private:
00523 static FXStream &makeStream();
00524 static hasSerialiseImpl::FakeStreamType<0!=indirs<type>::value || -1!=TL::find<IntegralLists::All, typename leastIndir<type>::value>::value, type> &makeType();
00525 public:
00526 static const int value=(sizeof(FXStream)==sizeof(makeStream() << makeType()));
00527 };
00532 template<typename type> struct hasDeserialise
00533 {
00534 private:
00535 static FXStream &makeStream();
00536 static hasSerialiseImpl::FakeStreamType<0!=indirs<type>::value || -1!=TL::find<IntegralLists::All, typename leastIndir<type>::value>::value, type> &makeType();
00537 public:
00538 static const int value=(sizeof(FXStream)==sizeof(makeStream() >> makeType()));
00539 };
00540 }
00541
00542 }
00543
00544 #endif