Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvbufstore.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Defines basic buffer storage classes.
00006  * These are not intended for use directly by clients.
00007  * See "wvbufbase.h" for the public API.
00008  */
00009 #ifndef __WVBUFFERSTORE_H
00010 #define __WVBUFFERSTORE_H
00011 
00012 #include "wvlinklist.h"
00013 #include <limits.h>
00014 
00015 /**
00016  * This value is used internally to signal unlimited free space.
00017  * It is merely meant to be as large as possible yet leave enough
00018  * room to accomodate simple arithmetic operations without overflow.
00019  * Clients should NOT check for the presence of this value explicitly.
00020  */
00021 #define UNLIMITED_FREE_SPACE (INT_MAX/2)
00022 
00023 /** The abstract buffer storage base class. */
00024 class WvBufStore
00025 {
00026     // discourage copying
00027     explicit WvBufStore(const WvBufStore &other) { }
00028 
00029 protected:
00030     // the suggested granularity
00031     int granularity;
00032 
00033     /**
00034      * Creates a new buffer.
00035      * "_granularity" is the suggested granularity for data allocation
00036      *        and alignment purposes
00037      */
00038     explicit WvBufStore(int _granularity);
00039     
00040 public:
00041     virtual ~WvBufStore() { }
00042 
00043     /*** Buffer Reading ***/
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     // helpers
00063     void move(void *buf, size_t count);
00064     void copy(void *buf, int offset, size_t count);
00065     
00066     /*** Buffer Writing ***/
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     // helpers
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     /*** Buffer to Buffer Transfers ***/
00084 
00085     virtual void merge(WvBufStore &instore, size_t count);
00086 
00087     // default implementation
00088     void basicmerge(WvBufStore &instore, size_t count);
00089 
00090 protected:
00091     /*** Support for buffers with subbuffers ***/
00092 
00093     /** Returns true if the buffer uses subbuffers for storage. */
00094     virtual bool usessubbuffers() const
00095         { return false; }
00096 
00097     /** Returns the number of subbuffers in the buffer. */
00098     virtual size_t numsubbuffers() const
00099         { return 0; }
00100 
00101     /**
00102      * Returns the first subbuffer.
00103      * Returns: the buffer or NULL if none or not supported
00104      */
00105     virtual WvBufStore *firstsubbuffer() const
00106         { return NULL; }
00107 
00108     /** Appends a subbuffer to the buffer. */
00109     virtual void appendsubbuffer(WvBufStore *buffer, bool autofree)
00110         { assert(! "not supported"); }
00111 
00112     /** Prepends a subbuffer to the buffer. */
00113     virtual void prependsubbuffer(WvBufStore *buffer, bool autofree)
00114         { assert(! "not supported"); }
00115 
00116     /**
00117      * Unlinks the specified subbuffer.
00118      * Only autofrees the buffer if allowautofree == true.
00119      * Returns: the autofree flag for the buffer
00120      */
00121     virtual bool unlinksubbuffer(WvBufStore *buffer,
00122         bool allowautofree)
00123         { assert(! "not supported"); return true; }
00124 };
00125 
00126 // lists of buffer stores are sometimes useful
00127 DeclareWvList(WvBufStore);
00128 
00129 
00130 
00131 /**
00132  * A statically bound mixin template for buffer implementations that are
00133  * read-only.  It is an error to attempt to write to a read-only buffer.
00134  * Note that read-only in this context does not mean the same as "const".
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  * A statically bound mixin template for buffer implementations that are
00186  * write-only.  It is an error to attempt to read from a write-only buffer.
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         // nothing to zap
00243     }
00244 };
00245 
00246 
00247 
00248 /** The WvInPlaceBuf storage class. */
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     /*** Overridden Members ***/
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 /** The WvConstInPlaceBuf storage class. */
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     /*** Overridden Members ***/
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 /** The WvCircularBuf storage class. */
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     /*** Overridden Members ***/
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      * Ensures that count new bytes can be read from or written
00362      * to the buffer beginning at the specified offset as one
00363      * large contiguous block.
00364      *
00365      * "offset" is the offset
00366      * "count" is the number of bytes
00367      * "keephistory" is if true, does not purge unget history
00368      * Returns: the offset of the first available byte
00369      */
00370     size_t ensurecontiguous(int offset, size_t count, bool keephistory);
00371 
00372     /**
00373      * Compacts an array arranged as a circular buffer such that
00374      * the specified region is moved to the beginning of the array.
00375      *
00376      * "data" is the array base
00377      * "size" is the size of the array
00378      * "head" is the beginning of the region to keep
00379      * "count" is the number of bytes in the region to keep
00380      */
00381     static void compact(void *data, size_t size,
00382         size_t head, size_t count);
00383 };
00384 
00385 
00386 
00387 /**
00388  * The WvLinkedBuffer storage class.
00389  * 
00390  * A buffer store built out of a list of other buffers linked together.
00391  * Buffers may be appended or prepended to the list at any time, at
00392  * which point they act as slaves for the master buffer.  Slaves may
00393  * be expunged from the list at any time when the master buffer
00394  * determines that they are of no further use.
00395  * 
00396  * This is mostly useful for building other buffer storage classes.
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     /*** Overridden Members ***/
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      * Called when a new buffer must be allocated to coalesce chunks.
00436      *
00437      * "minsize" is the minimum size for the new buffer
00438      * Returns: the new buffer
00439      */
00440     virtual WvBufStore *newbuffer(size_t minsize);
00441 
00442     /**
00443      * Called when a buffer with autofree is removed from the list.
00444      * This function is not called during object destruction.
00445      *
00446      * "buffer" is the buffer to be destroyed
00447      */
00448     virtual void recyclebuffer(WvBufStore *buffer);
00449 
00450     /**
00451      * Searches for the buffer containing the offset.
00452      * 
00453      * "it" is the iterator updated to point to buffer found,
00454      *        or to an invalid region if the offset is invalid
00455      * "offset" is the offset for which to search
00456      * Returns: the corrected offset within the buffer at it.ptr()
00457      */
00458     int search(WvBufStoreList::Iter &it, int offset) const;
00459 
00460     /**
00461      * Coalesces a sequence of buffers.
00462      *
00463      * "it" is the iterator pointing to the first buffer
00464      * "count" is the required number of contiguous used bytes
00465      * Returns: the composite buffer
00466      */
00467     WvBufStore *coalesce(WvBufStoreList::Iter &it,
00468         size_t count);
00469 
00470 private:
00471     // unlinks and recycles the buffer pointed at by the iterator
00472     void do_xunlink(WvBufStoreList::Iter &it);
00473 };
00474 
00475 
00476 
00477 /** The WvDynBuf storage class. */
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     /*** Overridden Members ***/
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 /** The WvNullBuf storage class. */
00499 class WvNullBufStore : public WvWriteOnlyBufferStoreMixin<
00500     WvReadOnlyBufferStoreMixin<WvBufStore> >
00501 {
00502 public:
00503     explicit WvNullBufStore(size_t _granularity);
00504 };
00505 
00506 
00507 
00508 /** The WvBufCursor storage class. */
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     /*** Overridden Members ***/
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

Generated on Sat Feb 21 21:05:24 2004 for WvStreams by doxygen 1.3.5