00001
00002
00003
00004
00005
00006
00007
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
00029 explicit WvBufStore(const WvBufStore &other) { }
00030
00031 protected:
00032
00033 int granularity;
00034
00040 explicit WvBufStore(int _granularity);
00041
00042 public:
00043 virtual ~WvBufStore() { }
00044
00045
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
00065 void move(void *buf, size_t count);
00066 void copy(void *buf, int offset, size_t count);
00067
00068
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
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
00086
00087 virtual void merge(WvBufStore &instore, size_t count);
00088
00089
00090 void basicmerge(WvBufStore &instore, size_t count);
00091
00092 protected:
00093
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 { }
00113
00115 virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
00116 { }
00117
00123 virtual bool unlinksubbuffer(WvBufStore *buffer,
00124 bool allowautofree)
00125 { return true; }
00126 };
00127
00128
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
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
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
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
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
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
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
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
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