00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __WVBUFFERSTORE_H
00010 #define __WVBUFFERSTORE_H
00011
00012 #include "wvlinklist.h"
00013 #include <limits.h>
00014
00015
00016
00017
00018
00019
00020
00021 #define UNLIMITED_FREE_SPACE (INT_MAX/2)
00022
00023
00024 class WvBufStore
00025 {
00026
00027 explicit WvBufStore(const WvBufStore &other) { }
00028
00029 protected:
00030
00031 int granularity;
00032
00033
00034
00035
00036
00037
00038 explicit WvBufStore(int _granularity);
00039
00040 public:
00041 virtual ~WvBufStore() { }
00042
00043
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
00063 void move(void *buf, size_t count);
00064 void copy(void *buf, int offset, size_t count);
00065
00066
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
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
00084
00085 virtual void merge(WvBufStore &instore, size_t count);
00086
00087
00088 void basicmerge(WvBufStore &instore, size_t count);
00089
00090 protected:
00091
00092
00093
00094 virtual bool usessubbuffers() const
00095 { return false; }
00096
00097
00098 virtual size_t numsubbuffers() const
00099 { return 0; }
00100
00101
00102
00103
00104
00105 virtual WvBufStore *firstsubbuffer() const
00106 { return NULL; }
00107
00108
00109 virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
00110 { assert(! "not supported"); }
00111
00112
00113 virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
00114 { assert(! "not supported"); }
00115
00116
00117
00118
00119
00120
00121 virtual bool unlinksubbuffer(WvBufStore *buffer,
00122 bool allowautofree)
00123 { assert(! "not supported"); return true; }
00124 };
00125
00126
00127 DeclareWvList(WvBufStore);
00128
00129
00130
00131
00132
00133
00134
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
00186
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
00243 }
00244 };
00245
00246
00247
00248
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
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
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
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
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
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
00362
00363
00364
00365
00366
00367
00368
00369
00370 size_t ensurecontiguous(int offset, size_t count, bool keephistory);
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 static void compact(void *data, size_t size,
00382 size_t head, size_t count);
00383 };
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
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
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
00436
00437
00438
00439
00440 virtual WvBufStore *newbuffer(size_t minsize);
00441
00442
00443
00444
00445
00446
00447
00448 virtual void recyclebuffer(WvBufStore *buffer);
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 int search(WvBufStoreList::Iter &it, int offset) const;
00459
00460
00461
00462
00463
00464
00465
00466
00467 WvBufStore *coalesce(WvBufStoreList::Iter &it,
00468 size_t count);
00469
00470 private:
00471
00472 void do_xunlink(WvBufStoreList::Iter &it);
00473 };
00474
00475
00476
00477
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
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
00499 class WvNullBufStore : public WvWriteOnlyBufferStoreMixin<
00500 WvReadOnlyBufferStoreMixin<WvBufStore> >
00501 {
00502 public:
00503 explicit WvNullBufStore(size_t _granularity);
00504 };
00505
00506
00507
00508
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
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