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