Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvbufstore.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * Defines basic buffer storage classes. 00006 * These are not intended for use directly by clients. 00007 * See "wvbufbase.h" for the public API. 00008 */ 00009 #ifndef __WVBUFFERSTORE_H 00010 #define __WVBUFFERSTORE_H 00011 00012 #include "wvlinklist.h" 00013 #include <limits.h> 00014 00015 /** 00016 * This value is used internally to signal unlimited free space. 00017 * It is merely meant to be as large as possible yet leave enough 00018 * room to accomodate simple arithmetic operations without overflow. 00019 * Clients should NOT check for the presence of this value explicitly. 00020 */ 00021 #define UNLIMITED_FREE_SPACE (INT_MAX/2) 00022 00023 /** The abstract buffer storage base class. */ 00024 class WvBufStore 00025 { 00026 // discourage copying 00027 explicit WvBufStore(const WvBufStore &other) { } 00028 00029 protected: 00030 // the suggested granularity 00031 int granularity; 00032 00033 /** 00034 * Creates a new buffer. 00035 * "_granularity" is the suggested granularity for data allocation 00036 * and alignment purposes 00037 */ 00038 explicit WvBufStore(int _granularity); 00039 00040 public: 00041 virtual ~WvBufStore() { } 00042 00043 /*** Buffer Reading ***/ 00044 00045 virtual bool isreadable() const 00046 { return true; } 00047 virtual size_t used() const = 0; 00048 virtual size_t optgettable() const 00049 { return used(); } 00050 virtual const void *get(size_t count) = 0; 00051 virtual void skip(size_t count) 00052 { get(count); } 00053 virtual void unget(size_t count) = 0; 00054 virtual size_t ungettable() const = 0; 00055 virtual size_t peekable(int offset) const; 00056 virtual size_t optpeekable(int offset) const 00057 { return peekable(offset); } 00058 virtual const void *peek(int offset, size_t count) 00059 { return mutablepeek(offset, count); } 00060 virtual void zap() = 0; 00061 00062 // helpers 00063 void move(void *buf, size_t count); 00064 void copy(void *buf, int offset, size_t count); 00065 00066 /*** Buffer Writing ***/ 00067 00068 virtual bool iswritable() const 00069 { return true; } 00070 virtual size_t free() const = 0; 00071 virtual size_t optallocable() const 00072 { return free(); } 00073 virtual void *alloc(size_t count) = 0; 00074 virtual void unalloc(size_t count) = 0; 00075 virtual size_t unallocable() const = 0; 00076 virtual void *mutablepeek(int offset, size_t count) = 0; 00077 00078 // helpers 00079 void put(const void *data, size_t count); 00080 void fastput(const void *data, size_t count); 00081 void poke(const void *data, int offset, size_t count); 00082 00083 /*** Buffer to Buffer Transfers ***/ 00084 00085 virtual void merge(WvBufStore &instore, size_t count); 00086 00087 // default implementation 00088 void basicmerge(WvBufStore &instore, size_t count); 00089 00090 protected: 00091 /*** Support for buffers with subbuffers ***/ 00092 00093 /** Returns true if the buffer uses subbuffers for storage. */ 00094 virtual bool usessubbuffers() const 00095 { return false; } 00096 00097 /** Returns the number of subbuffers in the buffer. */ 00098 virtual size_t numsubbuffers() const 00099 { return 0; } 00100 00101 /** 00102 * Returns the first subbuffer. 00103 * Returns: the buffer or NULL if none or not supported 00104 */ 00105 virtual WvBufStore *firstsubbuffer() const 00106 { return NULL; } 00107 00108 /** Appends a subbuffer to the buffer. */ 00109 virtual void appendsubbuffer(WvBufStore *buffer, bool autofree) 00110 { assert(! "not supported"); } 00111 00112 /** Prepends a subbuffer to the buffer. */ 00113 virtual void prependsubbuffer(WvBufStore *buffer, bool autofree) 00114 { assert(! "not supported"); } 00115 00116 /** 00117 * Unlinks the specified subbuffer. 00118 * Only autofrees the buffer if allowautofree == true. 00119 * Returns: the autofree flag for the buffer 00120 */ 00121 virtual bool unlinksubbuffer(WvBufStore *buffer, 00122 bool allowautofree) 00123 { assert(! "not supported"); return true; } 00124 }; 00125 00126 // lists of buffer stores are sometimes useful 00127 DeclareWvList(WvBufStore); 00128 00129 00130 00131 /** 00132 * A statically bound mixin template for buffer implementations that are 00133 * read-only. It is an error to attempt to write to a read-only buffer. 00134 * Note that read-only in this context does not mean the same as "const". 00135 */ 00136 template<class Super> 00137 class WvReadOnlyBufferStoreMixin : public Super 00138 { 00139 public: 00140 explicit WvReadOnlyBufferStoreMixin(int _granularity) : 00141 Super(_granularity) { } 00142 virtual bool iswritable() const 00143 { 00144 return false; 00145 } 00146 virtual size_t free() const 00147 { 00148 return 0; 00149 } 00150 virtual size_t optallocable() const 00151 { 00152 return 0; 00153 } 00154 virtual void *alloc(size_t count) 00155 { 00156 assert(count == 0 || 00157 ! "non-zero alloc() called on non-writable buffer"); 00158 return NULL; 00159 } 00160 virtual void unalloc(size_t count) 00161 { 00162 assert(count == 0 || 00163 ! "non-zero unalloc() called on non-writable buffer"); 00164 } 00165 virtual size_t unallocable() const 00166 { 00167 return 0; 00168 } 00169 virtual void *mutablepeek(int offset, size_t count) 00170 { 00171 assert(count == 0 || 00172 ! "mutablepeek() called on non-writable buffer"); 00173 return NULL; 00174 } 00175 virtual void merge(WvBufStore &instore, size_t count) 00176 { 00177 assert(count == 0 || 00178 ! "non-zero merge() called on non-writable buffer"); 00179 } 00180 }; 00181 00182 00183 00184 /** 00185 * A statically bound mixin template for buffer implementations that are 00186 * write-only. It is an error to attempt to read from a write-only buffer. 00187 */ 00188 template<class Super> 00189 class WvWriteOnlyBufferStoreMixin : public Super 00190 { 00191 public: 00192 explicit WvWriteOnlyBufferStoreMixin(int _granularity) : 00193 Super(_granularity) { } 00194 virtual bool isreadable() const 00195 { 00196 return false; 00197 } 00198 virtual size_t used() const 00199 { 00200 return 0; 00201 } 00202 virtual size_t optgettable() const 00203 { 00204 return 0; 00205 } 00206 virtual size_t peekable(int offset) const 00207 { 00208 return 0; 00209 } 00210 virtual size_t optpeekable(int offset) const 00211 { 00212 return 0; 00213 } 00214 virtual const void *get(size_t count) 00215 { 00216 assert(count == 0 || 00217 ! "non-zero get() called on non-readable buffer"); 00218 return NULL; 00219 } 00220 virtual void skip(size_t count) 00221 { 00222 assert(count == 0 || 00223 ! "non-zero skip() called on non-readable buffer"); 00224 } 00225 virtual void unget(size_t count) 00226 { 00227 assert(count == 0 || 00228 ! "non-zero unget() called on non-readable buffer"); 00229 } 00230 virtual size_t ungettable() const 00231 { 00232 return 0; 00233 } 00234 virtual const void *peek(int offset, size_t count) 00235 { 00236 assert(count == 0 || 00237 ! "peek() called on non-readable buffer"); 00238 return NULL; 00239 } 00240 virtual void zap() 00241 { 00242 // nothing to zap 00243 } 00244 }; 00245 00246 00247 00248 /** The WvInPlaceBuf storage class. */ 00249 class WvInPlaceBufStore : public WvBufStore 00250 { 00251 protected: 00252 void *data; 00253 size_t xsize; 00254 size_t readidx; 00255 size_t writeidx; 00256 bool xautofree; 00257 00258 public: 00259 WvInPlaceBufStore(int _granularity, 00260 void *_data, size_t _avail, size_t _size, bool _autofree); 00261 WvInPlaceBufStore(int _granularity, size_t _size); 00262 virtual ~WvInPlaceBufStore(); 00263 void *ptr() const 00264 { return data; } 00265 size_t size() const 00266 { return xsize; } 00267 bool autofree() const 00268 { return xautofree; } 00269 void setautofree(bool _autofree) 00270 { xautofree = _autofree; } 00271 void reset(void *_data, size_t _avail, size_t _size, bool _autofree); 00272 void setavail(size_t _avail); 00273 00274 /*** Overridden Members ***/ 00275 virtual size_t used() const; 00276 virtual const void *get(size_t count); 00277 virtual void unget(size_t count); 00278 virtual size_t ungettable() const; 00279 virtual void zap(); 00280 virtual size_t free() const; 00281 virtual void *alloc(size_t count); 00282 virtual void unalloc(size_t count); 00283 virtual size_t unallocable() const; 00284 virtual void *mutablepeek(int offset, size_t count); 00285 }; 00286 00287 00288 00289 /** The WvConstInPlaceBuf storage class. */ 00290 class WvConstInPlaceBufStore : 00291 public WvReadOnlyBufferStoreMixin<WvBufStore> 00292 { 00293 protected: 00294 const void *data; 00295 size_t avail; 00296 size_t readidx; 00297 00298 public: 00299 WvConstInPlaceBufStore(int _granularity, 00300 const void *_data, size_t _avail); 00301 const void *ptr() const 00302 { return data; } 00303 void reset(const void *_data, size_t _avail); 00304 void setavail(size_t _avail); 00305 00306 /*** Overridden Members ***/ 00307 virtual size_t used() const; 00308 virtual const void *get(size_t count); 00309 virtual void unget(size_t count); 00310 virtual size_t ungettable() const; 00311 virtual const void *peek(int offset, size_t count); 00312 virtual void zap(); 00313 }; 00314 00315 00316 00317 /** The WvCircularBuf storage class. */ 00318 class WvCircularBufStore : public WvBufStore 00319 { 00320 protected: 00321 void *data; 00322 size_t xsize; 00323 size_t head; 00324 size_t totalused; 00325 size_t totalinit; 00326 bool xautofree; 00327 00328 public: 00329 WvCircularBufStore(int _granularity, 00330 void *_data, size_t _avail, size_t _size, bool _autofree); 00331 WvCircularBufStore(int _granularity, size_t _size); 00332 virtual ~WvCircularBufStore(); 00333 void *ptr() const 00334 { return data; } 00335 size_t size() const 00336 { return xsize; } 00337 bool autofree() const 00338 { return xautofree; } 00339 void setautofree(bool _autofree) 00340 { xautofree = _autofree; } 00341 void reset(void *_data, size_t _avail, size_t _size, bool _autofree); 00342 void setavail(size_t _avail); 00343 void normalize(); 00344 00345 /*** Overridden Members ***/ 00346 virtual size_t used() const; 00347 virtual size_t optgettable() const; 00348 virtual const void *get(size_t count); 00349 virtual void unget(size_t count); 00350 virtual size_t ungettable() const; 00351 virtual void zap(); 00352 virtual size_t free() const; 00353 virtual size_t optallocable() const; 00354 virtual void *alloc(size_t count); 00355 virtual void unalloc(size_t count); 00356 virtual size_t unallocable() const; 00357 virtual void *mutablepeek(int offset, size_t count); 00358 00359 protected: 00360 /** 00361 * Ensures that count new bytes can be read from or written 00362 * to the buffer beginning at the specified offset as one 00363 * large contiguous block. 00364 * 00365 * "offset" is the offset 00366 * "count" is the number of bytes 00367 * "keephistory" is if true, does not purge unget history 00368 * Returns: the offset of the first available byte 00369 */ 00370 size_t ensurecontiguous(int offset, size_t count, bool keephistory); 00371 00372 /** 00373 * Compacts an array arranged as a circular buffer such that 00374 * the specified region is moved to the beginning of the array. 00375 * 00376 * "data" is the array base 00377 * "size" is the size of the array 00378 * "head" is the beginning of the region to keep 00379 * "count" is the number of bytes in the region to keep 00380 */ 00381 static void compact(void *data, size_t size, 00382 size_t head, size_t count); 00383 }; 00384 00385 00386 00387 /** 00388 * The WvLinkedBuffer storage class. 00389 * 00390 * A buffer store built out of a list of other buffers linked together. 00391 * Buffers may be appended or prepended to the list at any time, at 00392 * which point they act as slaves for the master buffer. Slaves may 00393 * be expunged from the list at any time when the master buffer 00394 * determines that they are of no further use. 00395 * 00396 * This is mostly useful for building other buffer storage classes. 00397 * 00398 */ 00399 class WvLinkedBufferStore : public WvBufStore 00400 { 00401 protected: 00402 WvBufStoreList list; 00403 size_t totalused; 00404 size_t maxungettable; 00405 00406 public: 00407 explicit WvLinkedBufferStore(int _granularity); 00408 00409 /*** Overridden Members ***/ 00410 virtual size_t used() const; 00411 virtual size_t optgettable() const; 00412 virtual const void *get(size_t count); 00413 virtual void unget(size_t count); 00414 virtual size_t ungettable() const; 00415 virtual void zap(); 00416 virtual size_t free() const; 00417 virtual size_t optallocable() const; 00418 virtual void *alloc(size_t count); 00419 virtual void unalloc(size_t count); 00420 virtual size_t unallocable() const; 00421 virtual size_t optpeekable(int offset) const; 00422 virtual void *mutablepeek(int offset, size_t count); 00423 00424 protected: 00425 virtual bool usessubbuffers() const; 00426 virtual size_t numsubbuffers() const; 00427 virtual WvBufStore *firstsubbuffer() const; 00428 virtual void appendsubbuffer(WvBufStore *buffer, bool autofree); 00429 virtual void prependsubbuffer(WvBufStore *buffer, bool autofree); 00430 virtual bool unlinksubbuffer(WvBufStore *buffer, 00431 bool allowautofree); 00432 00433 protected: 00434 /** 00435 * Called when a new buffer must be allocated to coalesce chunks. 00436 * 00437 * "minsize" is the minimum size for the new buffer 00438 * Returns: the new buffer 00439 */ 00440 virtual WvBufStore *newbuffer(size_t minsize); 00441 00442 /** 00443 * Called when a buffer with autofree is removed from the list. 00444 * This function is not called during object destruction. 00445 * 00446 * "buffer" is the buffer to be destroyed 00447 */ 00448 virtual void recyclebuffer(WvBufStore *buffer); 00449 00450 /** 00451 * Searches for the buffer containing the offset. 00452 * 00453 * "it" is the iterator updated to point to buffer found, 00454 * or to an invalid region if the offset is invalid 00455 * "offset" is the offset for which to search 00456 * Returns: the corrected offset within the buffer at it.ptr() 00457 */ 00458 int search(WvBufStoreList::Iter &it, int offset) const; 00459 00460 /** 00461 * Coalesces a sequence of buffers. 00462 * 00463 * "it" is the iterator pointing to the first buffer 00464 * "count" is the required number of contiguous used bytes 00465 * Returns: the composite buffer 00466 */ 00467 WvBufStore *coalesce(WvBufStoreList::Iter &it, 00468 size_t count); 00469 00470 private: 00471 // unlinks and recycles the buffer pointed at by the iterator 00472 void do_xunlink(WvBufStoreList::Iter &it); 00473 }; 00474 00475 00476 00477 /** The WvDynBuf storage class. */ 00478 class WvDynBufStore : public WvLinkedBufferStore 00479 { 00480 size_t minalloc; 00481 size_t maxalloc; 00482 00483 public: 00484 WvDynBufStore(size_t _granularity, 00485 size_t _minalloc, size_t _maxalloc); 00486 00487 /*** Overridden Members ***/ 00488 virtual size_t free() const; 00489 virtual size_t optallocable() const; 00490 virtual void *alloc(size_t count); 00491 00492 protected: 00493 virtual WvBufStore *newbuffer(size_t minsize); 00494 }; 00495 00496 00497 00498 /** The WvNullBuf storage class. */ 00499 class WvNullBufStore : public WvWriteOnlyBufferStoreMixin< 00500 WvReadOnlyBufferStoreMixin<WvBufStore> > 00501 { 00502 public: 00503 explicit WvNullBufStore(size_t _granularity); 00504 }; 00505 00506 00507 00508 /** The WvBufCursor storage class. */ 00509 class WvBufCursorStore : 00510 public WvReadOnlyBufferStoreMixin<WvBufStore> 00511 { 00512 protected: 00513 WvBufStore *buf; 00514 int start; 00515 size_t length; 00516 size_t shift; 00517 00518 public: 00519 WvBufCursorStore(size_t _granularity, WvBufStore *_buf, 00520 int _start, size_t _length); 00521 00522 /*** Overridden Members ***/ 00523 virtual bool isreadable() const; 00524 virtual size_t used() const; 00525 virtual size_t optgettable() const; 00526 virtual const void *get(size_t count); 00527 virtual void skip(size_t count); 00528 virtual void unget(size_t count); 00529 virtual size_t ungettable() const; 00530 virtual size_t peekable(int offset) const; 00531 virtual size_t optpeekable(int offset) const; 00532 virtual const void *peek(int offset, size_t count); 00533 virtual void zap(); 00534 virtual bool iswritable() const; 00535 virtual void *mutablepeek(int offset, size_t count); 00536 }; 00537 00538 #endif // __WVBUFFERSTORE_H

Generated on Tue Oct 5 01:09:20 2004 for WvStreams by doxygen 1.3.7