Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members

FXStream.h

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,2004 by Jeroen van der Zijp.   All Rights Reserved.        *
00007 *********************************************************************************
00008 * This library is free software; you can redistribute it and/or                 *
00009 * modify it under the terms of the GNU Lesser General Public                    *
00010 * License as published by the Free Software Foundation; either                  *
00011 * version 2.1 of the License, or (at your option) any later version.            *
00012 *                                                                               *
00013 * This library is distributed in the hope that it will be useful,               *
00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
00016 * Lesser General Public License for more details.                               *
00017 *                                                                               *
00018 * You should have received a copy of the GNU Lesser General Public              *
00019 * License along with this library; if not, write to the Free Software           *
00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
00021 *********************************************************************************
00022 * $Id: FXStream.h,v 1.29 2004/01/13 20:56:04 fox Exp $                          *
00023 ********************************************************************************/
00024 #ifndef FXSTREAM_H
00025 #define FXSTREAM_H
00026 
00027 
00028 namespace FX {
00029 
00030 
00031 /// Stream data flow direction
00032 enum FXStreamDirection {
00033   FXStreamDead=0,               /// Unopened stream
00034   FXStreamSave=1,               /// Saving stuff to stream
00035   FXStreamLoad=2                /// Loading stuff from stream
00036   };
00037 
00038 
00039 /// Stream status codes
00040 enum FXStreamStatus {
00041   FXStreamOK=0,                 /// OK
00042   FXStreamEnd=1,                /// Try read past end of stream
00043   FXStreamFull=2,               /// Filled up stream buffer or disk full
00044   FXStreamNoWrite=3,            /// Unable to open for write
00045   FXStreamNoRead=4,             /// Unable to open for read
00046   FXStreamFormat=5,             /// Stream format error
00047   FXStreamUnknown=6,            /// Trying to read unknown class
00048   FXStreamAlloc=7,              /// Alloc failed
00049   FXStreamFailure=8             /// General failure
00050   };
00051 
00052 
00053 /// Stream seeking
00054 enum FXWhence {
00055   FXFromStart=0,                /// Seek from start position
00056   FXFromCurrent=1,              /// Seek from current position
00057   FXFromEnd=2                   /// Seek from end position
00058   };
00059 
00060 
00061 /**
00062 * A stream is a way to serialize data and objects into a byte stream.
00063 * Each item of data that is saved or loaded from the stream may be byte-swapped,
00064 * thus allowing little-endian machines to read data produced on big endian ones
00065 * and vice-versa.
00066 * Data is serialized exactly as-is.  There are no tags or other markers
00067 * inserted into the stream; thus, the stream may be used to save or load arbitrary
00068 * binary data.
00069 * Objects derived from FXObjects may be serialized also; whenever a reference to an
00070 * object is serialized, a table is consulted to determine if the same object has
00071 * been encountered previously; if not, the object is added to the table and then
00072 * its contents are serialized.  If the object has been encountered before, only a
00073 * reference to the object is serialized.
00074 * When loading back a serialized object, new instances are constructed using
00075 * the default constructor, and subsequently the object's contents are loaded.
00076 * A special container object may be passed in which is placed in the table
00077 * as if it had been encountered before; this will cause only references to this
00078 * object to be saved.  The container object is typically the top-level document
00079 * object which manages all objects contained by it.
00080 */
00081 class FXAPI FXStream {
00082 private:
00083   struct FXStreamHashEntry {
00084     FXuint    ref;              // Object reference number
00085     FXObject* obj;              // Pointer to object
00086     };
00087 private:
00088   const FXObject*    parent;    // Parent object
00089   FXStreamHashEntry* table;     // Hash table
00090   FXuint             ntable;    // Table size
00091   FXuint             no;        // Count objects
00092   FXbool             swap;      // Swap bytes on readin
00093   void               grow();    // Enlarge the table
00094 protected:
00095   FXuchar           *begptr;    // Begin of buffer
00096   FXuchar           *endptr;    // End of buffer
00097   FXuchar           *wrptr;     // Write pointer
00098   FXuchar           *rdptr;     // Read pointer
00099   unsigned long      pos;       // Position
00100   FXStreamDirection  dir;       // Direction of current transfer
00101   FXStreamStatus     code;      // Status code
00102   FXbool             owns;      // Stream owns buffer
00103 protected:
00104 
00105   /**
00106   * Write at least count bytes from the buffer;
00107   * returns number of bytes available to be written.
00108   */
00109   virtual unsigned long writeBuffer(unsigned long count);
00110 
00111   /**
00112   * Read at least count bytes into the buffer;
00113   * returns number of bytes available to be read.
00114   */
00115   virtual unsigned long readBuffer(unsigned long count);
00116 
00117 public:
00118 
00119   /**
00120   * Construct stream with given container object.  The container object
00121   * is an object that will itself not be saved to or loaded from the stream,
00122   * but which may be referenced by other objects.  These references will be
00123   * properly saved and restored.
00124   */
00125   FXStream(const FXObject* cont=NULL);
00126 
00127   /**
00128   * Open stream for reading (FXStreamLoad) or for writing (FXStreamSave).
00129   * An initial buffer size may be given, which must be at least 16 bytes.
00130   * If data is not NULL, it is expected to point to an external data buffer
00131   * of length size; otherwise stream will use an internally managed buffer.
00132   */
00133   FXbool open(FXStreamDirection save_or_load,unsigned long size=8192,FXuchar* data=NULL);
00134 
00135   /// Close; return TRUE if OK
00136   virtual FXbool close();
00137 
00138   /// Flush buffer
00139   virtual FXbool flush();
00140 
00141   /// Get available buffer space
00142   unsigned long getSpace() const;
00143 
00144   /// Set available buffer space
00145   void setSpace(unsigned long sp);
00146 
00147   /// Get status code
00148   FXStreamStatus status() const { return code; }
00149 
00150   /// Return TRUE if at end of file or error
00151   FXbool eof() const { return code!=FXStreamOK; }
00152 
00153   /// Set status code
00154   void setError(FXStreamStatus err);
00155 
00156   /// Obtain stream direction
00157   FXStreamDirection direction() const { return dir; }
00158 
00159   /// Get parent object
00160   const FXObject* container() const { return parent; }
00161 
00162   /// Get position
00163   unsigned long position() const { return pos; }
00164 
00165   /// Move to position relative to head, tail, or current location
00166   virtual FXbool position(long offset,FXWhence whence=FXFromStart);
00167 
00168   /**
00169   * Change swap bytes flag.
00170   */
00171   void swapBytes(FXbool s){ swap=s; }
00172 
00173   /**
00174   * Get state of the swap bytes flag.
00175   */
00176   FXbool swapBytes() const { return swap; }
00177 
00178   /// Return implementation's endianness
00179   static FXbool isLittleEndian(){ return !FOX_BIGENDIAN; }
00180 
00181   /// Save single items to stream
00182   FXStream& operator<<(const FXuchar& v);
00183   FXStream& operator<<(const FXchar& v){ return *this << reinterpret_cast<const FXuchar&>(v); }
00184   FXStream& operator<<(const FXushort& v);
00185   FXStream& operator<<(const FXshort& v){ return *this << reinterpret_cast<const FXushort&>(v); }
00186   FXStream& operator<<(const FXuint& v);
00187   FXStream& operator<<(const FXint& v){ return *this << reinterpret_cast<const FXuint&>(v); }
00188   FXStream& operator<<(const FXfloat& v){ return *this << reinterpret_cast<const FXuint&>(v); }
00189   FXStream& operator<<(const FXdouble& v);
00190 #ifdef FX_LONG
00191   FXStream& operator<<(const FXlong& v){ return *this << reinterpret_cast<const FXdouble&>(v); }
00192   FXStream& operator<<(const FXulong& v){ return *this << reinterpret_cast<const FXdouble&>(v); }
00193 #endif
00194 
00195   /// Save arrays of items to stream
00196   FXStream& save(const FXuchar* p,unsigned long n);
00197   FXStream& save(const FXchar* p,unsigned long n){ return save(reinterpret_cast<const FXuchar*>(p),n); }
00198   FXStream& save(const FXushort* p,unsigned long n);
00199   FXStream& save(const FXshort* p,unsigned long n){ return save(reinterpret_cast<const FXushort*>(p),n); }
00200   FXStream& save(const FXuint* p,unsigned long n);
00201   FXStream& save(const FXint* p,unsigned long n){ return save(reinterpret_cast<const FXuint*>(p),n); }
00202   FXStream& save(const FXfloat* p,unsigned long n){ return save(reinterpret_cast<const FXuint*>(p),n); }
00203   FXStream& save(const FXdouble* p,unsigned long n);
00204 #ifdef FX_LONG
00205   FXStream& save(const FXlong* p,unsigned long n){ return save(reinterpret_cast<const FXdouble*>(p),n); }
00206   FXStream& save(const FXulong* p,unsigned long n){ return save(reinterpret_cast<const FXdouble*>(p),n); }
00207 #endif
00208 
00209   /// Load single items from stream
00210   FXStream& operator>>(FXuchar& v);
00211   FXStream& operator>>(FXchar& v){ return *this >> reinterpret_cast<FXuchar&>(v); }
00212   FXStream& operator>>(FXushort& v);
00213   FXStream& operator>>(FXshort& v){ return *this >> reinterpret_cast<FXushort&>(v); }
00214   FXStream& operator>>(FXuint& v);
00215   FXStream& operator>>(FXint& v){ return *this >> reinterpret_cast<FXuint&>(v); }
00216   FXStream& operator>>(FXfloat& v){ return *this >> reinterpret_cast<FXuint&>(v); }
00217   FXStream& operator>>(FXdouble& v);
00218 #ifdef FX_LONG
00219   FXStream& operator>>(FXlong& v){ return *this >> reinterpret_cast<FXdouble&>(v); }
00220   FXStream& operator>>(FXulong& v){ return *this >> reinterpret_cast<FXdouble&>(v); }
00221 #endif
00222 
00223   /// Load arrays of items from stream
00224   FXStream& load(FXuchar* p,unsigned long n);
00225   FXStream& load(FXchar* p,unsigned long n){ return load(reinterpret_cast<FXuchar*>(p),n); }
00226   FXStream& load(FXushort* p,unsigned long n);
00227   FXStream& load(FXshort* p,unsigned long n){ return load(reinterpret_cast<FXushort*>(p),n); }
00228   FXStream& load(FXuint* p,unsigned long n);
00229   FXStream& load(FXint* p,unsigned long n){ return load(reinterpret_cast<FXuint*>(p),n); }
00230   FXStream& load(FXfloat* p,unsigned long n){ return load(reinterpret_cast<FXuint*>(p),n); }
00231   FXStream& load(FXdouble* p,unsigned long n);
00232 #ifdef FX_LONG
00233   FXStream& load(FXlong* p,unsigned long n){ return load(reinterpret_cast<FXdouble*>(p),n); }
00234   FXStream& load(FXulong* p,unsigned long n){ return load(reinterpret_cast<FXdouble*>(p),n); }
00235 #endif
00236 
00237   /// Save object
00238   FXStream& saveObject(const FXObject* v);
00239 
00240   /// Load object
00241   FXStream& loadObject(FXObject*& v);
00242 
00243   /// Destructor
00244   virtual ~FXStream();
00245   };
00246 
00247 }
00248 
00249 #endif

Copyright © 1997-2004 Jeroen van der Zijp