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,2005 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.37 2005/01/16 16:06:06 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. Additional objects may be 00080 * added using addObject(); these will not be actually saved or loaded. 00081 */ 00082 class FXAPI FXStream { 00083 protected: 00084 FXHash hash; // Hash table 00085 const FXObject *parent; // Parent object 00086 FXuchar *begptr; // Begin of buffer 00087 FXuchar *endptr; // End of buffer 00088 FXuchar *wrptr; // Write pointer 00089 FXuchar *rdptr; // Read pointer 00090 FXlong pos; // Position 00091 FXStreamDirection dir; // Direction of current transfer 00092 FXStreamStatus code; // Status code 00093 FXuint seq; // Sequence number 00094 FXbool owns; // Stream owns buffer 00095 FXbool swap; // Swap bytes on readin 00096 protected: 00097 00098 /** 00099 * Write at least count bytes from the buffer; 00100 * returns number of bytes available to be written. 00101 */ 00102 virtual unsigned long writeBuffer(unsigned long count); 00103 00104 /** 00105 * Read at least count bytes into the buffer; 00106 * returns number of bytes available to be read. 00107 */ 00108 virtual unsigned long readBuffer(unsigned long count); 00109 00110 public: 00111 00112 /** 00113 * Construct stream with given container object. The container object 00114 * is an object that will itself not be saved to or loaded from the stream, 00115 * but which may be referenced by other objects. These references will be 00116 * properly saved and restored. 00117 */ 00118 FXStream(const FXObject* cont=NULL); 00119 00120 /** 00121 * Open stream for reading (FXStreamLoad) or for writing (FXStreamSave). 00122 * An initial buffer size may be given, which must be at least 16 bytes. 00123 * If data is not NULL, it is expected to point to an external data buffer 00124 * of length size; otherwise stream will use an internally managed buffer. 00125 */ 00126 FXbool open(FXStreamDirection save_or_load,unsigned long size=8192,FXuchar* data=NULL); 00127 00128 /// Close; return TRUE if OK 00129 virtual FXbool close(); 00130 00131 /// Flush buffer 00132 virtual FXbool flush(); 00133 00134 /// Get available buffer space 00135 unsigned long getSpace() const; 00136 00137 /// Set available buffer space 00138 void setSpace(unsigned long sp); 00139 00140 /// Get status code 00141 FXStreamStatus status() const { return code; } 00142 00143 /// Return TRUE if at end of file or error 00144 FXbool eof() const { return code!=FXStreamOK; } 00145 00146 /// Set status code 00147 void setError(FXStreamStatus err); 00148 00149 /// Obtain stream direction 00150 FXStreamDirection direction() const { return dir; } 00151 00152 /// Get parent object 00153 const FXObject* container() const { return parent; } 00154 00155 /// Get position 00156 FXlong position() const { return pos; } 00157 00158 /// Move to position relative to head, tail, or current location 00159 virtual FXbool position(FXlong offset,FXWhence whence=FXFromStart); 00160 00161 /** 00162 * Change swap bytes flag. 00163 */ 00164 void swapBytes(FXbool s){ swap=s; } 00165 00166 /** 00167 * Get state of the swap bytes flag. 00168 */ 00169 FXbool swapBytes() const { return swap; } 00170 00171 /** 00172 * Set stream to big endian mode if TRUE. Byte swapping will 00173 * be enabled if the machine native byte order is not equal to 00174 * the desired byte order. 00175 */ 00176 void setBigEndian(FXbool big){ swap=(big^FOX_BIGENDIAN); } 00177 00178 /** 00179 * Return TRUE if big endian mode. 00180 */ 00181 FXbool isBigEndian() const { return (swap^FOX_BIGENDIAN); } 00182 00183 /// Save single items to stream 00184 FXStream& operator<<(const FXuchar& v); 00185 FXStream& operator<<(const FXchar& v){ return *this << reinterpret_cast<const FXuchar&>(v); } 00186 FXStream& operator<<(const FXushort& v); 00187 FXStream& operator<<(const FXshort& v){ return *this << reinterpret_cast<const FXushort&>(v); } 00188 FXStream& operator<<(const FXuint& v); 00189 FXStream& operator<<(const FXint& v){ return *this << reinterpret_cast<const FXuint&>(v); } 00190 FXStream& operator<<(const FXfloat& v){ return *this << reinterpret_cast<const FXuint&>(v); } 00191 FXStream& operator<<(const FXdouble& v); 00192 FXStream& operator<<(const FXlong& v){ return *this << reinterpret_cast<const FXdouble&>(v); } 00193 FXStream& operator<<(const FXulong& v){ return *this << reinterpret_cast<const FXdouble&>(v); } 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 FXStream& save(const FXlong* p,unsigned long n){ return save(reinterpret_cast<const FXdouble*>(p),n); } 00205 FXStream& save(const FXulong* p,unsigned long n){ return save(reinterpret_cast<const FXdouble*>(p),n); } 00206 00207 /// Load single items from stream 00208 FXStream& operator>>(FXuchar& v); 00209 FXStream& operator>>(FXchar& v){ return *this >> reinterpret_cast<FXuchar&>(v); } 00210 FXStream& operator>>(FXushort& v); 00211 FXStream& operator>>(FXshort& v){ return *this >> reinterpret_cast<FXushort&>(v); } 00212 FXStream& operator>>(FXuint& v); 00213 FXStream& operator>>(FXint& v){ return *this >> reinterpret_cast<FXuint&>(v); } 00214 FXStream& operator>>(FXfloat& v){ return *this >> reinterpret_cast<FXuint&>(v); } 00215 FXStream& operator>>(FXdouble& v); 00216 FXStream& operator>>(FXlong& v){ return *this >> reinterpret_cast<FXdouble&>(v); } 00217 FXStream& operator>>(FXulong& v){ return *this >> reinterpret_cast<FXdouble&>(v); } 00218 00219 /// Load arrays of items from stream 00220 FXStream& load(FXuchar* p,unsigned long n); 00221 FXStream& load(FXchar* p,unsigned long n){ return load(reinterpret_cast<FXuchar*>(p),n); } 00222 FXStream& load(FXushort* p,unsigned long n); 00223 FXStream& load(FXshort* p,unsigned long n){ return load(reinterpret_cast<FXushort*>(p),n); } 00224 FXStream& load(FXuint* p,unsigned long n); 00225 FXStream& load(FXint* p,unsigned long n){ return load(reinterpret_cast<FXuint*>(p),n); } 00226 FXStream& load(FXfloat* p,unsigned long n){ return load(reinterpret_cast<FXuint*>(p),n); } 00227 FXStream& load(FXdouble* p,unsigned long n); 00228 FXStream& load(FXlong* p,unsigned long n){ return load(reinterpret_cast<FXdouble*>(p),n); } 00229 FXStream& load(FXulong* p,unsigned long n){ return load(reinterpret_cast<FXdouble*>(p),n); } 00230 00231 /// Save object 00232 FXStream& saveObject(const FXObject* v); 00233 00234 /// Load object 00235 FXStream& loadObject(FXObject*& v); 00236 00237 /// Add object without saving or loading 00238 FXStream& addObject(const FXObject* v); 00239 00240 /// Destructor 00241 virtual ~FXStream(); 00242 }; 00243 00244 } 00245 00246 #endif

Copyright © 1997-2005 Jeroen van der Zijp