WvStreams
include/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
26class WvBufStore
27{
28 // discourage copying
29 explicit WvBufStore(const WvBufStore &other) { }
30
31protected:
32 // the suggested granularity
33 int granularity;
34
40 explicit WvBufStore(int _granularity);
41
42public:
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
92protected:
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
129DeclareWvList(WvBufStore);
130
131
132
138template<class Super>
139class WvReadOnlyBufferStoreMixin : public Super
140{
141public:
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
190template<class Super>
191class WvWriteOnlyBufferStoreMixin : public Super
192{
193public:
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
251class WvInPlaceBufStore : public WvBufStore
252{
253protected:
254 void *data;
255 size_t xsize;
256 size_t readidx;
257 size_t writeidx;
258 bool xautofree;
259
260public:
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{
295protected:
296 const void *data;
297 size_t avail;
298 size_t readidx;
299
300public:
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
320class WvCircularBufStore : public WvBufStore
321{
322protected:
323 void *data;
324 size_t xsize;
325 size_t head;
326 size_t totalused;
327 size_t totalinit;
328 bool xautofree;
329
330public:
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
361protected:
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
401class WvLinkedBufferStore : public WvBufStore
402{
403protected:
404 WvBufStoreList list;
405 size_t totalused;
406 size_t maxungettable;
407
408public:
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
426protected:
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
435protected:
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
472private:
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
485public:
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
494protected:
495 virtual WvBufStore *newbuffer(size_t minsize);
496};
497
498
499
502 WvReadOnlyBufferStoreMixin<WvBufStore> >
503{
504public:
505 explicit WvNullBufStore(size_t _granularity);
506};
507
508
509
511class WvBufCursorStore :
512 public WvReadOnlyBufferStoreMixin<WvBufStore>
513{
514protected:
515 WvBufStore *buf;
516 int start;
517 size_t length;
518 size_t shift;
519
520public:
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
The abstract buffer storage base class.
virtual size_t numsubbuffers() const
Returns the number of subbuffers in the buffer.
virtual bool usessubbuffers() const
Returns true if the buffer uses subbuffers for storage.
virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
Appends a subbuffer to the buffer.
virtual WvBufStore * firstsubbuffer() const
Returns the first subbuffer.
WvBufStore(int _granularity)
Creates a new buffer.
virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
Prepends a subbuffer to the buffer.
virtual bool unlinksubbuffer(WvBufStore *buffer, bool allowautofree)
Unlinks the specified subbuffer.
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...
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...
virtual WvBufStore * newbuffer(size_t minsize)
Called when a new buffer must be allocated to coalesce chunks.
virtual bool unlinksubbuffer(WvBufStore *buffer, bool allowautofree)
Unlinks the specified subbuffer.
virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
Appends a subbuffer to the buffer.
int search(WvBufStoreList::Iter &it, int offset) const
Searches for the buffer containing the offset.
virtual WvBufStore * firstsubbuffer() const
Returns the first subbuffer.
virtual void recyclebuffer(WvBufStore *buffer)
Called when a buffer with autofree is removed from the list.
virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
Prepends a subbuffer to the buffer.
virtual bool usessubbuffers() const
Returns true if the buffer uses subbuffers for storage.
virtual size_t numsubbuffers() const
Returns the number of subbuffers in the buffer.
virtual WvBufStore * newbuffer(size_t minsize)
Called when a new buffer must be allocated to coalesce chunks.
WvBufStore * coalesce(WvBufStoreList::Iter &it, size_t count)
Coalesces a sequence of buffers.
A statically bound mixin template for buffer implementations that are read-only.
A statically bound mixin template for buffer implementations that are write-only.