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

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

Copyright © 1997-2009 Jeroen van der Zijp