FXStream.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *       P e r s i s t e n t   S t o r a g e   S t r e a m   C l a s s e s       *
00004 *                                                                               *
00005 *********************************************************************************
00006 * Copyright (C) 1997,2006 by Jeroen van der Zijp.   All Rights Reserved.        *
00007 * TnFOX Extensions (C) 2003-2006 Niall Douglas                                       *
00008 *********************************************************************************
00009 * This library is free software; you can redistribute it and/or                 *
00010 * modify it under the terms of the GNU Lesser General Public                    *
00011 * License as published by the Free Software Foundation; either                  *
00012 * version 2.1 of the License, or (at your option) any later version.            *
00013 *                                                                               *
00014 * This library is distributed in the hope that it will be useful,               *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
00017 * Lesser General Public License for more details.                               *
00018 *                                                                               *
00019 * You should have received a copy of the GNU Lesser General Public              *
00020 * License along with this library; if not, write to the Free Software           *
00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
00022 *********************************************************************************
00023 * $Id: FXStream.h,v 1.42 2006/01/22 17:58:10 fox Exp $                          *
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 /************************  Persistent Store Definition  *************************/
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;      // Hash table
00153   const FXObject    *parent;    // Parent object
00154   FXuchar           *begptr;    // Begin of buffer
00155   FXuchar           *endptr;    // End of buffer
00156   FXuchar           *wrptr;     // Write pointer
00157   FXuchar           *rdptr;     // Read pointer
00158   FXlong             pos;       // Position
00159   FXStreamDirection  dir;       // Direction of current transfer
00160   FXStreamStatus     code;      // Status code
00161   FXuint             seq;       // Sequence number
00162   bool               owns;      // Stream owns buffer
00163   bool               swap;      // Swap bytes on readin
00164 
00165 protected: // TnFOX stuff
00166   QIODevice         *dev;       // i/o device
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){  // inlined as FXString uses it
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){   // inlined as FXString uses it
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 // FXString serialisation (can't be defined in FXString.h as FXStream needs FXString)
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         {   // This being for user defined struct types
00508             operator hasSerialiseImpl::FakeStreamTypeBase &();
00509         };
00510         template<typename type> struct FakeStreamType<true, type>
00511         {   // This being for pointers, references and integrals
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

(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:31:24 2009 for TnFOX by doxygen v1.4.7