WvStreams
|
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 <assert.h> 00014 #include <limits.h> 00015 #include <assert.h> 00016 00023 #define UNLIMITED_FREE_SPACE (INT_MAX/2) 00024 00026 class WvBufStore 00027 { 00028 // discourage copying 00029 explicit WvBufStore(const WvBufStore &other) { } 00030 00031 protected: 00032 // the suggested granularity 00033 int granularity; 00034 00040 explicit WvBufStore(int _granularity); 00041 00042 public: 00043 virtual ~WvBufStore() { } 00044 00045 /*** Buffer Reading ***/ 00046 00047 virtual bool isreadable() const 00048 { return true; } 00049 virtual size_t used() const = 0; 00050 virtual size_t optgettable() const 00051 { return used(); } 00052 virtual const void *get(size_t count) = 0; 00053 virtual void skip(size_t count) 00054 { get(count); } 00055 virtual void unget(size_t count) = 0; 00056 virtual size_t ungettable() const = 0; 00057 virtual size_t peekable(int offset) const; 00058 virtual size_t optpeekable(int offset) const 00059 { return peekable(offset); } 00060 virtual const void *peek(int offset, size_t count) 00061 { return mutablepeek(offset, count); } 00062 virtual void zap() = 0; 00063 00064 // helpers 00065 void move(void *buf, size_t count); 00066 void copy(void *buf, int offset, size_t count); 00067 00068 /*** Buffer Writing ***/ 00069 00070 virtual bool iswritable() const 00071 { return true; } 00072 virtual size_t free() const = 0; 00073 virtual size_t optallocable() const 00074 { return free(); } 00075 virtual void *alloc(size_t count) = 0; 00076 virtual void unalloc(size_t count) = 0; 00077 virtual size_t unallocable() const = 0; 00078 virtual void *mutablepeek(int offset, size_t count) = 0; 00079 00080 // helpers 00081 void put(const void *data, size_t count); 00082 void fastput(const void *data, size_t count); 00083 void poke(const void *data, int offset, size_t count); 00084 00085 /*** Buffer to Buffer Transfers ***/ 00086 00087 virtual void merge(WvBufStore &instore, size_t count); 00088 00089 // default implementation 00090 void basicmerge(WvBufStore &instore, size_t count); 00091 00092 protected: 00093 /*** Support for buffers with subbuffers ***/ 00094 00096 virtual bool usessubbuffers() const 00097 { return false; } 00098 00100 virtual size_t numsubbuffers() const 00101 { return 0; } 00102 00107 virtual WvBufStore *firstsubbuffer() const 00108 { return NULL; } 00109 00111 virtual void appendsubbuffer(WvBufStore *buffer, bool autofree) 00112 { /*assert(! "not supported");*/ } 00113 00115 virtual void prependsubbuffer(WvBufStore *buffer, bool autofree) 00116 { /*assert(! "not supported");*/ } 00117 00123 virtual bool unlinksubbuffer(WvBufStore *buffer, 00124 bool allowautofree) 00125 { /*assert(! "not supported");*/ return true; } 00126 }; 00127 00128 // lists of buffer stores are sometimes useful 00129 DeclareWvList(WvBufStore); 00130 00131 00132 00138 template<class Super> 00139 class WvReadOnlyBufferStoreMixin : public Super 00140 { 00141 public: 00142 explicit WvReadOnlyBufferStoreMixin(int _granularity) : 00143 Super(_granularity) { } 00144 virtual bool iswritable() const 00145 { 00146 return false; 00147 } 00148 virtual size_t free() const 00149 { 00150 return 0; 00151 } 00152 virtual size_t optallocable() const 00153 { 00154 return 0; 00155 } 00156 virtual void *alloc(size_t count) 00157 { 00158 assert(count == 0 || 00159 ! "non-zero alloc() called on non-writable buffer"); 00160 return NULL; 00161 } 00162 virtual void unalloc(size_t count) 00163 { 00164 assert(count == 0 || 00165 ! "non-zero unalloc() called on non-writable buffer"); 00166 } 00167 virtual size_t unallocable() const 00168 { 00169 return 0; 00170 } 00171 virtual void *mutablepeek(int offset, size_t count) 00172 { 00173 assert(count == 0 || 00174 ! "mutablepeek() called on non-writable buffer"); 00175 return NULL; 00176 } 00177 virtual void merge(WvBufStore &instore, size_t count) 00178 { 00179 assert(count == 0 || 00180 ! "non-zero merge() called on non-writable buffer"); 00181 } 00182 }; 00183 00184 00185 00190 template<class Super> 00191 class WvWriteOnlyBufferStoreMixin : public Super 00192 { 00193 public: 00194 explicit WvWriteOnlyBufferStoreMixin(int _granularity) : 00195 Super(_granularity) { } 00196 virtual bool isreadable() const 00197 { 00198 return false; 00199 } 00200 virtual size_t used() const 00201 { 00202 return 0; 00203 } 00204 virtual size_t optgettable() const 00205 { 00206 return 0; 00207 } 00208 virtual size_t peekable(int offset) const 00209 { 00210 return 0; 00211 } 00212 virtual size_t optpeekable(int offset) const 00213 { 00214 return 0; 00215 } 00216 virtual const void *get(size_t count) 00217 { 00218 assert(count == 0 || 00219 ! "non-zero get() called on non-readable buffer"); 00220 return NULL; 00221 } 00222 virtual void skip(size_t count) 00223 { 00224 assert(count == 0 || 00225 ! "non-zero skip() called on non-readable buffer"); 00226 } 00227 virtual void unget(size_t count) 00228 { 00229 assert(count == 0 || 00230 ! "non-zero unget() called on non-readable buffer"); 00231 } 00232 virtual size_t ungettable() const 00233 { 00234 return 0; 00235 } 00236 virtual const void *peek(int offset, size_t count) 00237 { 00238 assert(count == 0 || 00239 ! "peek() called on non-readable buffer"); 00240 return NULL; 00241 } 00242 virtual void zap() 00243 { 00244 // nothing to zap 00245 } 00246 }; 00247 00248 00249 00251 class WvInPlaceBufStore : public WvBufStore 00252 { 00253 protected: 00254 void *data; 00255 size_t xsize; 00256 size_t readidx; 00257 size_t writeidx; 00258 bool xautofree; 00259 00260 public: 00261 WvInPlaceBufStore(int _granularity, 00262 void *_data, size_t _avail, size_t _size, bool _autofree); 00263 WvInPlaceBufStore(int _granularity, size_t _size); 00264 virtual ~WvInPlaceBufStore(); 00265 void *ptr() const 00266 { return data; } 00267 size_t size() const 00268 { return xsize; } 00269 bool get_autofree() const 00270 { return xautofree; } 00271 void set_autofree(bool _autofree) 00272 { xautofree = _autofree; } 00273 void reset(void *_data, size_t _avail, size_t _size, bool _autofree); 00274 void setavail(size_t _avail); 00275 00276 /*** Overridden Members ***/ 00277 virtual size_t used() const; 00278 virtual const void *get(size_t count); 00279 virtual void unget(size_t count); 00280 virtual size_t ungettable() const; 00281 virtual void zap(); 00282 virtual size_t free() const; 00283 virtual void *alloc(size_t count); 00284 virtual void unalloc(size_t count); 00285 virtual size_t unallocable() const; 00286 virtual void *mutablepeek(int offset, size_t count); 00287 }; 00288 00289 00290 00292 class WvConstInPlaceBufStore : 00293 public WvReadOnlyBufferStoreMixin<WvBufStore> 00294 { 00295 protected: 00296 const void *data; 00297 size_t avail; 00298 size_t readidx; 00299 00300 public: 00301 WvConstInPlaceBufStore(int _granularity, 00302 const void *_data, size_t _avail); 00303 const void *ptr() const 00304 { return data; } 00305 void reset(const void *_data, size_t _avail); 00306 void setavail(size_t _avail); 00307 00308 /*** Overridden Members ***/ 00309 virtual size_t used() const; 00310 virtual const void *get(size_t count); 00311 virtual void unget(size_t count); 00312 virtual size_t ungettable() const; 00313 virtual const void *peek(int offset, size_t count); 00314 virtual void zap(); 00315 }; 00316 00317 00318 00320 class WvCircularBufStore : public WvBufStore 00321 { 00322 protected: 00323 void *data; 00324 size_t xsize; 00325 size_t head; 00326 size_t totalused; 00327 size_t totalinit; 00328 bool xautofree; 00329 00330 public: 00331 WvCircularBufStore(int _granularity, 00332 void *_data, size_t _avail, size_t _size, bool _autofree); 00333 WvCircularBufStore(int _granularity, size_t _size); 00334 virtual ~WvCircularBufStore(); 00335 void *ptr() const 00336 { return data; } 00337 size_t size() const 00338 { return xsize; } 00339 bool get_autofree() const 00340 { return xautofree; } 00341 void set_autofree(bool _autofree) 00342 { xautofree = _autofree; } 00343 void reset(void *_data, size_t _avail, size_t _size, bool _autofree); 00344 void setavail(size_t _avail); 00345 void normalize(); 00346 00347 /*** Overridden Members ***/ 00348 virtual size_t used() const; 00349 virtual size_t optgettable() const; 00350 virtual const void *get(size_t count); 00351 virtual void unget(size_t count); 00352 virtual size_t ungettable() const; 00353 virtual void zap(); 00354 virtual size_t free() const; 00355 virtual size_t optallocable() const; 00356 virtual void *alloc(size_t count); 00357 virtual void unalloc(size_t count); 00358 virtual size_t unallocable() const; 00359 virtual void *mutablepeek(int offset, size_t count); 00360 00361 protected: 00372 size_t ensurecontiguous(int offset, size_t count, bool keephistory); 00373 00383 static void compact(void *data, size_t size, 00384 size_t head, size_t count); 00385 }; 00386 00387 00388 00401 class WvLinkedBufferStore : public WvBufStore 00402 { 00403 protected: 00404 WvBufStoreList list; 00405 size_t totalused; 00406 size_t maxungettable; 00407 00408 public: 00409 explicit WvLinkedBufferStore(int _granularity); 00410 00411 /*** Overridden Members ***/ 00412 virtual size_t used() const; 00413 virtual size_t optgettable() const; 00414 virtual const void *get(size_t count); 00415 virtual void unget(size_t count); 00416 virtual size_t ungettable() const; 00417 virtual void zap(); 00418 virtual size_t free() const; 00419 virtual size_t optallocable() const; 00420 virtual void *alloc(size_t count); 00421 virtual void unalloc(size_t count); 00422 virtual size_t unallocable() const; 00423 virtual size_t optpeekable(int offset) const; 00424 virtual void *mutablepeek(int offset, size_t count); 00425 00426 protected: 00427 virtual bool usessubbuffers() const; 00428 virtual size_t numsubbuffers() const; 00429 virtual WvBufStore *firstsubbuffer() const; 00430 virtual void appendsubbuffer(WvBufStore *buffer, bool autofree); 00431 virtual void prependsubbuffer(WvBufStore *buffer, bool autofree); 00432 virtual bool unlinksubbuffer(WvBufStore *buffer, 00433 bool allowautofree); 00434 00435 protected: 00442 virtual WvBufStore *newbuffer(size_t minsize); 00443 00450 virtual void recyclebuffer(WvBufStore *buffer); 00451 00460 int search(WvBufStoreList::Iter &it, int offset) const; 00461 00469 WvBufStore *coalesce(WvBufStoreList::Iter &it, 00470 size_t count); 00471 00472 private: 00473 // unlinks and recycles the buffer pointed at by the iterator 00474 void do_xunlink(WvBufStoreList::Iter &it); 00475 }; 00476 00477 00478 00480 class WvDynBufStore : public WvLinkedBufferStore 00481 { 00482 size_t minalloc; 00483 size_t maxalloc; 00484 00485 public: 00486 WvDynBufStore(size_t _granularity, 00487 size_t _minalloc, size_t _maxalloc); 00488 00489 /*** Overridden Members ***/ 00490 virtual size_t free() const; 00491 virtual size_t optallocable() const; 00492 virtual void *alloc(size_t count); 00493 00494 protected: 00495 virtual WvBufStore *newbuffer(size_t minsize); 00496 }; 00497 00498 00499 00501 class WvNullBufStore : public WvWriteOnlyBufferStoreMixin< 00502 WvReadOnlyBufferStoreMixin<WvBufStore> > 00503 { 00504 public: 00505 explicit WvNullBufStore(size_t _granularity); 00506 }; 00507 00508 00509 00511 class WvBufCursorStore : 00512 public WvReadOnlyBufferStoreMixin<WvBufStore> 00513 { 00514 protected: 00515 WvBufStore *buf; 00516 int start; 00517 size_t length; 00518 size_t shift; 00519 00520 public: 00521 WvBufCursorStore(size_t _granularity, WvBufStore *_buf, 00522 int _start, size_t _length); 00523 00524 /*** Overridden Members ***/ 00525 virtual bool isreadable() const; 00526 virtual size_t used() const; 00527 virtual size_t optgettable() const; 00528 virtual const void *get(size_t count); 00529 virtual void skip(size_t count); 00530 virtual void unget(size_t count); 00531 virtual size_t ungettable() const; 00532 virtual size_t peekable(int offset) const; 00533 virtual size_t optpeekable(int offset) const; 00534 virtual const void *peek(int offset, size_t count); 00535 virtual void zap(); 00536 virtual bool iswritable() const; 00537 virtual void *mutablepeek(int offset, size_t count); 00538 }; 00539 00540 #endif // __WVBUFFERSTORE_H