WvStreams
wvbufstore.h
1 /* -*- Mode: C++ -*-
2  * Worldvisions Weaver Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * Defines basic buffer storage classes.
6  * These are not intended for use directly by clients.
7  * See "wvbufbase.h" for the public API.
8  */
9 #ifndef __WVBUFFERSTORE_H
10 #define __WVBUFFERSTORE_H
11 
12 #include "wvlinklist.h"
13 #include <assert.h>
14 #include <limits.h>
15 #include <assert.h>
16 
23 #define UNLIMITED_FREE_SPACE (INT_MAX/2)
24 
27 {
28  // discourage copying
29  explicit WvBufStore(const WvBufStore &other) { }
30 
31 protected:
32  // the suggested granularity
33  int granularity;
34 
40  explicit WvBufStore(int _granularity);
41 
42 public:
43  virtual ~WvBufStore() { }
44 
45  /*** Buffer Reading ***/
46 
47  virtual bool isreadable() const
48  { return true; }
49  virtual size_t used() const = 0;
50  virtual size_t optgettable() const
51  { return used(); }
52  virtual const void *get(size_t count) = 0;
53  virtual void skip(size_t count)
54  { get(count); }
55  virtual void unget(size_t count) = 0;
56  virtual size_t ungettable() const = 0;
57  virtual size_t peekable(int offset) const;
58  virtual size_t optpeekable(int offset) const
59  { return peekable(offset); }
60  virtual const void *peek(int offset, size_t count)
61  { return mutablepeek(offset, count); }
62  virtual void zap() = 0;
63 
64  // helpers
65  void move(void *buf, size_t count);
66  void copy(void *buf, int offset, size_t count);
67 
68  /*** Buffer Writing ***/
69 
70  virtual bool iswritable() const
71  { return true; }
72  virtual size_t free() const = 0;
73  virtual size_t optallocable() const
74  { return free(); }
75  virtual void *alloc(size_t count) = 0;
76  virtual void unalloc(size_t count) = 0;
77  virtual size_t unallocable() const = 0;
78  virtual void *mutablepeek(int offset, size_t count) = 0;
79 
80  // helpers
81  void put(const void *data, size_t count);
82  void fastput(const void *data, size_t count);
83  void poke(const void *data, int offset, size_t count);
84 
85  /*** Buffer to Buffer Transfers ***/
86 
87  virtual void merge(WvBufStore &instore, size_t count);
88 
89  // default implementation
90  void basicmerge(WvBufStore &instore, size_t count);
91 
92 protected:
93  /*** Support for buffers with subbuffers ***/
94 
96  virtual bool usessubbuffers() const
97  { return false; }
98 
100  virtual size_t numsubbuffers() const
101  { return 0; }
102 
107  virtual WvBufStore *firstsubbuffer() const
108  { return NULL; }
109 
111  virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
112  { /*assert(! "not supported");*/ }
113 
115  virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
116  { /*assert(! "not supported");*/ }
117 
123  virtual bool unlinksubbuffer(WvBufStore *buffer,
124  bool allowautofree)
125  { /*assert(! "not supported");*/ return true; }
126 };
127 
128 // lists of buffer stores are sometimes useful
129 DeclareWvList(WvBufStore);
130 
131 
132 
138 template<class Super>
139 class WvReadOnlyBufferStoreMixin : public Super
140 {
141 public:
142  explicit WvReadOnlyBufferStoreMixin(int _granularity) :
143  Super(_granularity) { }
144  virtual bool iswritable() const
145  {
146  return false;
147  }
148  virtual size_t free() const
149  {
150  return 0;
151  }
152  virtual size_t optallocable() const
153  {
154  return 0;
155  }
156  virtual void *alloc(size_t count)
157  {
158  assert(count == 0 ||
159  ! "non-zero alloc() called on non-writable buffer");
160  return NULL;
161  }
162  virtual void unalloc(size_t count)
163  {
164  assert(count == 0 ||
165  ! "non-zero unalloc() called on non-writable buffer");
166  }
167  virtual size_t unallocable() const
168  {
169  return 0;
170  }
171  virtual void *mutablepeek(int offset, size_t count)
172  {
173  assert(count == 0 ||
174  ! "mutablepeek() called on non-writable buffer");
175  return NULL;
176  }
177  virtual void merge(WvBufStore &instore, size_t count)
178  {
179  assert(count == 0 ||
180  ! "non-zero merge() called on non-writable buffer");
181  }
182 };
183 
184 
185 
190 template<class Super>
191 class WvWriteOnlyBufferStoreMixin : public Super
192 {
193 public:
194  explicit WvWriteOnlyBufferStoreMixin(int _granularity) :
195  Super(_granularity) { }
196  virtual bool isreadable() const
197  {
198  return false;
199  }
200  virtual size_t used() const
201  {
202  return 0;
203  }
204  virtual size_t optgettable() const
205  {
206  return 0;
207  }
208  virtual size_t peekable(int offset) const
209  {
210  return 0;
211  }
212  virtual size_t optpeekable(int offset) const
213  {
214  return 0;
215  }
216  virtual const void *get(size_t count)
217  {
218  assert(count == 0 ||
219  ! "non-zero get() called on non-readable buffer");
220  return NULL;
221  }
222  virtual void skip(size_t count)
223  {
224  assert(count == 0 ||
225  ! "non-zero skip() called on non-readable buffer");
226  }
227  virtual void unget(size_t count)
228  {
229  assert(count == 0 ||
230  ! "non-zero unget() called on non-readable buffer");
231  }
232  virtual size_t ungettable() const
233  {
234  return 0;
235  }
236  virtual const void *peek(int offset, size_t count)
237  {
238  assert(count == 0 ||
239  ! "peek() called on non-readable buffer");
240  return NULL;
241  }
242  virtual void zap()
243  {
244  // nothing to zap
245  }
246 };
247 
248 
249 
252 {
253 protected:
254  void *data;
255  size_t xsize;
256  size_t readidx;
257  size_t writeidx;
258  bool xautofree;
259 
260 public:
261  WvInPlaceBufStore(int _granularity,
262  void *_data, size_t _avail, size_t _size, bool _autofree);
263  WvInPlaceBufStore(int _granularity, size_t _size);
264  virtual ~WvInPlaceBufStore();
265  void *ptr() const
266  { return data; }
267  size_t size() const
268  { return xsize; }
269  bool get_autofree() const
270  { return xautofree; }
271  void set_autofree(bool _autofree)
272  { xautofree = _autofree; }
273  void reset(void *_data, size_t _avail, size_t _size, bool _autofree);
274  void setavail(size_t _avail);
275 
276  /*** Overridden Members ***/
277  virtual size_t used() const;
278  virtual const void *get(size_t count);
279  virtual void unget(size_t count);
280  virtual size_t ungettable() const;
281  virtual void zap();
282  virtual size_t free() const;
283  virtual void *alloc(size_t count);
284  virtual void unalloc(size_t count);
285  virtual size_t unallocable() const;
286  virtual void *mutablepeek(int offset, size_t count);
287 };
288 
289 
290 
293  public WvReadOnlyBufferStoreMixin<WvBufStore>
294 {
295 protected:
296  const void *data;
297  size_t avail;
298  size_t readidx;
299 
300 public:
301  WvConstInPlaceBufStore(int _granularity,
302  const void *_data, size_t _avail);
303  const void *ptr() const
304  { return data; }
305  void reset(const void *_data, size_t _avail);
306  void setavail(size_t _avail);
307 
308  /*** Overridden Members ***/
309  virtual size_t used() const;
310  virtual const void *get(size_t count);
311  virtual void unget(size_t count);
312  virtual size_t ungettable() const;
313  virtual const void *peek(int offset, size_t count);
314  virtual void zap();
315 };
316 
317 
318 
321 {
322 protected:
323  void *data;
324  size_t xsize;
325  size_t head;
326  size_t totalused;
327  size_t totalinit;
328  bool xautofree;
329 
330 public:
331  WvCircularBufStore(int _granularity,
332  void *_data, size_t _avail, size_t _size, bool _autofree);
333  WvCircularBufStore(int _granularity, size_t _size);
334  virtual ~WvCircularBufStore();
335  void *ptr() const
336  { return data; }
337  size_t size() const
338  { return xsize; }
339  bool get_autofree() const
340  { return xautofree; }
341  void set_autofree(bool _autofree)
342  { xautofree = _autofree; }
343  void reset(void *_data, size_t _avail, size_t _size, bool _autofree);
344  void setavail(size_t _avail);
345  void normalize();
346 
347  /*** Overridden Members ***/
348  virtual size_t used() const;
349  virtual size_t optgettable() const;
350  virtual const void *get(size_t count);
351  virtual void unget(size_t count);
352  virtual size_t ungettable() const;
353  virtual void zap();
354  virtual size_t free() const;
355  virtual size_t optallocable() const;
356  virtual void *alloc(size_t count);
357  virtual void unalloc(size_t count);
358  virtual size_t unallocable() const;
359  virtual void *mutablepeek(int offset, size_t count);
360 
361 protected:
372  size_t ensurecontiguous(int offset, size_t count, bool keephistory);
373 
383  static void compact(void *data, size_t size,
384  size_t head, size_t count);
385 };
386 
387 
388 
402 {
403 protected:
404  WvBufStoreList list;
405  size_t totalused;
406  size_t maxungettable;
407 
408 public:
409  explicit WvLinkedBufferStore(int _granularity);
410 
411  /*** Overridden Members ***/
412  virtual size_t used() const;
413  virtual size_t optgettable() const;
414  virtual const void *get(size_t count);
415  virtual void unget(size_t count);
416  virtual size_t ungettable() const;
417  virtual void zap();
418  virtual size_t free() const;
419  virtual size_t optallocable() const;
420  virtual void *alloc(size_t count);
421  virtual void unalloc(size_t count);
422  virtual size_t unallocable() const;
423  virtual size_t optpeekable(int offset) const;
424  virtual void *mutablepeek(int offset, size_t count);
425 
426 protected:
427  virtual bool usessubbuffers() const;
428  virtual size_t numsubbuffers() const;
429  virtual WvBufStore *firstsubbuffer() const;
430  virtual void appendsubbuffer(WvBufStore *buffer, bool autofree);
431  virtual void prependsubbuffer(WvBufStore *buffer, bool autofree);
432  virtual bool unlinksubbuffer(WvBufStore *buffer,
433  bool allowautofree);
434 
435 protected:
442  virtual WvBufStore *newbuffer(size_t minsize);
443 
450  virtual void recyclebuffer(WvBufStore *buffer);
451 
460  int search(WvBufStoreList::Iter &it, int offset) const;
461 
469  WvBufStore *coalesce(WvBufStoreList::Iter &it,
470  size_t count);
471 
472 private:
473  // unlinks and recycles the buffer pointed at by the iterator
474  void do_xunlink(WvBufStoreList::Iter &it);
475 };
476 
477 
478 
481 {
482  size_t minalloc;
483  size_t maxalloc;
484 
485 public:
486  WvDynBufStore(size_t _granularity,
487  size_t _minalloc, size_t _maxalloc);
488 
489  /*** Overridden Members ***/
490  virtual size_t free() const;
491  virtual size_t optallocable() const;
492  virtual void *alloc(size_t count);
493 
494 protected:
495  virtual WvBufStore *newbuffer(size_t minsize);
496 };
497 
498 
499 
502  WvReadOnlyBufferStoreMixin<WvBufStore> >
503 {
504 public:
505  explicit WvNullBufStore(size_t _granularity);
506 };
507 
508 
509 
512  public WvReadOnlyBufferStoreMixin<WvBufStore>
513 {
514 protected:
515  WvBufStore *buf;
516  int start;
517  size_t length;
518  size_t shift;
519 
520 public:
521  WvBufCursorStore(size_t _granularity, WvBufStore *_buf,
522  int _start, size_t _length);
523 
524  /*** Overridden Members ***/
525  virtual bool isreadable() const;
526  virtual size_t used() const;
527  virtual size_t optgettable() const;
528  virtual const void *get(size_t count);
529  virtual void skip(size_t count);
530  virtual void unget(size_t count);
531  virtual size_t ungettable() const;
532  virtual size_t peekable(int offset) const;
533  virtual size_t optpeekable(int offset) const;
534  virtual const void *peek(int offset, size_t count);
535  virtual void zap();
536  virtual bool iswritable() const;
537  virtual void *mutablepeek(int offset, size_t count);
538 };
539 
540 #endif // __WVBUFFERSTORE_H
WvBufStore::usessubbuffers
virtual bool usessubbuffers() const
Returns true if the buffer uses subbuffers for storage.
Definition: wvbufstore.h:96
WvLinkedBufferStore::unlinksubbuffer
virtual bool unlinksubbuffer(WvBufStore *buffer, bool allowautofree)
Unlinks the specified subbuffer.
Definition: wvbufferstore.cc:780
WvConstInPlaceBufStore
The WvConstInPlaceBuf storage class.
Definition: wvbufstore.h:292
WvLinkedBufferStore::appendsubbuffer
virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
Appends a subbuffer to the buffer.
Definition: wvbufferstore.cc:763
WvDynBufStore
The WvDynBuf storage class.
Definition: wvbufstore.h:480
WvWriteOnlyBufferStoreMixin
A statically bound mixin template for buffer implementations that are write-only.
Definition: wvbufstore.h:191
WvBufStore::unlinksubbuffer
virtual bool unlinksubbuffer(WvBufStore *buffer, bool allowautofree)
Unlinks the specified subbuffer.
Definition: wvbufstore.h:123
WvLinkedBufferStore::search
int search(WvBufStoreList::Iter &it, int offset) const
Searches for the buffer containing the offset.
Definition: wvbufferstore.cc:1010
WvDynBufStore::newbuffer
virtual WvBufStore * newbuffer(size_t minsize)
Called when a new buffer must be allocated to coalesce chunks.
Definition: wvbufferstore.cc:1152
WvLinkedBufferStore::firstsubbuffer
virtual WvBufStore * firstsubbuffer() const
Returns the first subbuffer.
Definition: wvbufferstore.cc:757
WvCircularBufStore
The WvCircularBuf storage class.
Definition: wvbufstore.h:320
WvLinkedBufferStore::newbuffer
virtual WvBufStore * newbuffer(size_t minsize)
Called when a new buffer must be allocated to coalesce chunks.
Definition: wvbufferstore.cc:996
WvLinkedBufferStore::recyclebuffer
virtual void recyclebuffer(WvBufStore *buffer)
Called when a buffer with autofree is removed from the list.
Definition: wvbufferstore.cc:1004
WvBufStore
The abstract buffer storage base class.
Definition: wvbufstore.h:26
WvLinkedBufferStore::coalesce
WvBufStore * coalesce(WvBufStoreList::Iter &it, size_t count)
Coalesces a sequence of buffers.
Definition: wvbufferstore.cc:1042
WvBufStore::firstsubbuffer
virtual WvBufStore * firstsubbuffer() const
Returns the first subbuffer.
Definition: wvbufstore.h:107
WvBufStore::appendsubbuffer
virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
Appends a subbuffer to the buffer.
Definition: wvbufstore.h:111
WvInPlaceBufStore
The WvInPlaceBuf storage class.
Definition: wvbufstore.h:251
WvReadOnlyBufferStoreMixin
A statically bound mixin template for buffer implementations that are read-only.
Definition: wvbufstore.h:139
WvLinkedBufferStore::numsubbuffers
virtual size_t numsubbuffers() const
Returns the number of subbuffers in the buffer.
Definition: wvbufferstore.cc:751
WvLinkedBufferStore::prependsubbuffer
virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
Prepends a subbuffer to the buffer.
Definition: wvbufferstore.cc:771
WvBufStore::prependsubbuffer
virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
Prepends a subbuffer to the buffer.
Definition: wvbufstore.h:115
WvCircularBufStore::ensurecontiguous
size_t ensurecontiguous(int offset, size_t count, bool keephistory)
Ensures that count new bytes can be read from or written to the buffer beginning at the specified off...
Definition: wvbufferstore.cc:647
WvLinkedBufferStore::usessubbuffers
virtual bool usessubbuffers() const
Returns true if the buffer uses subbuffers for storage.
Definition: wvbufferstore.cc:745
WvBufStore::numsubbuffers
virtual size_t numsubbuffers() const
Returns the number of subbuffers in the buffer.
Definition: wvbufstore.h:100
WvNullBufStore
The WvNullBuf storage class.
Definition: wvbufstore.h:501
WvLinkedBufferStore
The WvLinkedBuffer storage class.
Definition: wvbufstore.h:401
WvCircularBufStore::compact
static void compact(void *data, size_t size, size_t head, size_t count)
Compacts an array arranged as a circular buffer such that the specified region is moved to the beginn...
Definition: wvbufferstore.cc:684
WvBufCursorStore
The WvBufCursor storage class.
Definition: wvbufstore.h:511