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