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

wvbufbase.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  * A generic buffering API.
00006  * Please declare specializations in a separate header file,
00007  * See "wvbuf.h".
00008  */
00009 #ifndef __WVBUFFERBASE_H
00010 #define __WVBUFFERBASE_H
00011 
00012 #include "wvbufstore.h"
00013 
00014 template<class T>
00015 class WvBufBase;
00016 
00017 /**
00018  * An abstract generic buffer template.
00019  * Buffers are simple data queues designed to ease the construction of
00020  * functions that must generate, consume, or transform large amount of
00021  * data in pipeline fashion.  Concrete buffer subclases define the actual
00022  * storage mechanism and queuing machinery.  In addition they may provide
00023  * additional functionality for accomplishing particular tasks.
00024  *
00025  * The base component is split into two parts, WvBufBaseCommonImpl
00026  * that defines the common API for all buffer types, and WvBufBase
00027  * that allows specializations to be defined to add functionality
00028  * to the base type.  When passing around buffer objects, you should
00029  * use the WvBufBase<T> type rather than WvBufBaseCommonImpl<T>.
00030  *
00031  * See WvBufBase<T>
00032  * "T" is the type of object to store, must be a primitive or a struct
00033  *        without special initialization, copy, or assignment semantics
00034  */
00035 template<class T>
00036 class WvBufBaseCommonImpl
00037 {
00038 protected:
00039     typedef T Elem;
00040     typedef WvBufBase<T> Buffer;
00041 
00042     WvBufStore *store;
00043     
00044     // discourage copying
00045     explicit WvBufBaseCommonImpl(
00046         const WvBufBaseCommonImpl &other) { }
00047 
00048 protected:
00049     /**
00050      * Initializes the buffer.
00051      * 
00052      * Note: Does not take ownership of the storage object.
00053      * 
00054      *
00055      * "store" is the low-level storage object
00056      */
00057     explicit WvBufBaseCommonImpl(WvBufStore *store) :
00058         store(store) { }
00059 
00060 public:
00061     /** Destroys the buffer. */
00062     virtual ~WvBufBaseCommonImpl() { }
00063 
00064     /**
00065      * Returns a pointer to the underlying storage class object.
00066      *
00067      * Returns: the low-level storage class object pointer, non-null
00068      */
00069     WvBufStore *getstore()
00070     {
00071         return store;
00072     }
00073 
00074     /*** Buffer Reading ***/
00075 
00076     /**
00077      * Returns true if the buffer supports reading.
00078      *
00079      * Returns: true if reading is supported
00080      */
00081     bool isreadable() const
00082     {
00083         return store->isreadable();
00084     }
00085     
00086     /**
00087      * Returns the number of elements in the buffer currently
00088      * available for reading.
00089      * 
00090      * This function could also be called gettable().
00091      */
00092     size_t used() const
00093     {
00094         return store->used() / sizeof(Elem);
00095     }
00096 
00097     /**
00098      * Reads exactly the specified number of elements and returns
00099      * a pointer to a storage location owned by the buffer.
00100      * 
00101      * The pointer is only valid until the next non-const buffer
00102      * member is called. eg. alloc(size_t)
00103      * 
00104      * If count == 0, a NULL pointer may be returned.
00105      * 
00106      * It is an error for count to be greater than used().
00107      * 
00108      * For maximum efficiency, call this function multiple times
00109      * with count no greater than optgettable() each time.
00110      * 
00111      * After this operation, at least count elements may be ungotten.
00112      */
00113     const T *get(size_t count)
00114     {
00115         if (count > used())
00116             return NULL;
00117 
00118         return static_cast<const T*>(
00119             store->get(count * sizeof(Elem)));
00120     }
00121 
00122     /**
00123      * Skips exactly the specified number of elements.
00124      * 
00125      * This is equivalent to invoking get(size_t) with the count
00126      * and discarding the result, but may be faster for certain
00127      * types of buffers.  As with get(size_t), the call may be
00128      * followed up by an unget(size_t).
00129      * 
00130      *
00131      * "count" is the number of elements
00132      */
00133     void skip(size_t count)
00134     {
00135         store->skip(count * sizeof(Elem));
00136     }
00137 
00138     /**
00139      * Returns the optimal maximum number of elements in the
00140      * buffer currently available for reading without incurring
00141      * significant overhead.
00142      * 
00143      * Invariants:
00144      * 
00145      *  - optgettable() <= used()
00146      *  - optgettable() != 0 if used() != 0
00147      * 
00148      *
00149      * Returns: the number of elements
00150      */
00151     size_t optgettable() const
00152     {
00153         size_t avail = store->optgettable();
00154         size_t elems = avail / sizeof(Elem);
00155         if (elems != 0) return elems;
00156         return avail != 0 && store->used() >= sizeof(Elem) ? 1 : 0;
00157     }
00158 
00159     /**
00160      * Ungets exactly the specified number of elements by returning
00161      * them to the buffer for subsequent reads.
00162      * 
00163      * This operation may always be safely performed with count
00164      * less than or equal to that specified in the last get(size_t)
00165      * if no non-const buffer members have been called since then.
00166      * 
00167      * If count == 0, nothing happens.
00168      * 
00169      * It is an error for count to be greater than ungettable().
00170      * 
00171      *
00172      * "count" is the number of elements
00173      */
00174     void unget(size_t count)
00175     {
00176         store->unget(count * sizeof(Elem));
00177     }
00178 
00179     /**
00180      * Returns the maximum number of elements that may be ungotten
00181      * at this time.
00182      *
00183      * Returns: the number of elements
00184      */
00185     size_t ungettable() const
00186     {
00187         return store->ungettable() / sizeof(Elem);
00188     }
00189 
00190     /**
00191      * Returns a const pointer into the buffer at the specified
00192      * offset to the specified number of elements without actually
00193      * adjusting the current get() index.
00194      * 
00195      * The pointer is only valid until the next non-const buffer
00196      * member is called. eg. alloc(size_t)
00197      * 
00198      * If count == 0, a NULL pointer may be returned.
00199      * 
00200      * If offset is greater than zero, then elements will be returned
00201      * beginning with the with the offset'th element that would be
00202      * returned by get(size_t).
00203      * 
00204      * If offset equals zero, then elements will be returned beginning
00205      * with the next one available for get(size_t).
00206      * 
00207      * If offset is less than zero, then elements will be returned
00208      * beginning with the first one that would be returned on a
00209      * get(size_t) following an unget(-offset).
00210      * 
00211      * It is an error for count to be greater than peekable(offset).
00212      * 
00213      * For maximum efficiency, call this function multiple times
00214      * with count no greater than that returned by optpeekable(size_t)
00215      * at incremental offsets.
00216      * 
00217      *
00218      * "offset" is the buffer offset
00219      * "count" is the number of elements
00220      * Returns: the element storage pointer
00221      */
00222     const T *peek(int offset, size_t count)
00223     {
00224         return static_cast<const T*>(store->peek(
00225             offset * sizeof(Elem), count * sizeof(Elem)));
00226     }
00227 
00228     size_t peekable(int offset)
00229     {
00230         return store->peekable(offset * sizeof(Elem)) / sizeof(Elem);
00231     }
00232 
00233     size_t optpeekable(int offset)
00234     {
00235         offset *= sizeof(Elem);
00236         size_t avail = store->optpeekable(offset);
00237         size_t elems = avail / sizeof(Elem);
00238         if (elems != 0) return elems;
00239         return avail != 0 &&
00240             store->peekable(offset) >= sizeof(Elem) ? 1 : 0;
00241     }
00242 
00243     /**
00244      * Clears the buffer.
00245      * 
00246      * For many types of buffers, calling zap() will increased the
00247      * amount of free space available for writing (see below) by
00248      * an amount greater than used().  Hence it is wise to zap()
00249      * a buffer just before writing to it to maximize free space.
00250      * 
00251      * After this operation, used() == 0, and often ungettable() == 0.
00252      * 
00253      */
00254     void zap()
00255     {
00256         store->zap();
00257     }
00258 
00259     /**
00260      * Reads the next element from the buffer.
00261      * 
00262      * It is an error to invoke this method if used() == 0.
00263      * 
00264      * After this operation, at least 1 element may be ungotten.
00265      * 
00266      *
00267      * Returns: the element
00268      */
00269     T get()
00270     {
00271         return *get(1);
00272     }
00273 
00274     /**
00275      * Returns the element at the specified offset in the buffer.
00276      * 
00277      * It is an error to invoke this method if used() == 0.
00278      * 
00279      *
00280      * "offset" is the offset, default 0
00281      * Returns: the element
00282      */
00283     T peek(int offset = 0)
00284     {
00285         return *peek(offset * sizeof(Elem), sizeof(Elem));
00286     }
00287 
00288     /**
00289      * Efficiently copies the specified number of elements from the
00290      * buffer to the specified UNINITIALIZED storage location
00291      * and removes the elements from the buffer.
00292      * 
00293      * It is an error for count to be greater than used().
00294      * 
00295      * For maximum efficiency, choose as large a count as possible.
00296      * 
00297      * The pointer buf may be NULL only if count == 0.
00298      * 
00299      * After this operation, an indeterminate number of elements
00300      * may be ungotten.
00301      * 
00302      *
00303      * "buf" is the buffer that will receive the elements
00304      * "count" is the number of elements
00305      */
00306     void move(T *buf, size_t count)
00307     {
00308         store->move(buf, count * sizeof(Elem));
00309     }
00310     
00311     /**
00312      * Efficiently copies the specified number of elements from the
00313      * buffer to the specified UNINITIALIZED storage location
00314      * but does not remove the elements from the buffer.
00315      * 
00316      * It is an error for count to be greater than peekable(offset).
00317      * 
00318      * For maximum efficiency, choose as large a count as possible.
00319      * 
00320      * The pointer buf may be NULL only if count == 0.
00321      * 
00322      *
00323      * "buf" is the buffer that will receive the elements
00324      * "offset" is the buffer offset
00325      * "count" is the number of elements
00326      */
00327     void copy(T *buf, int offset, size_t count)
00328     {
00329         store->copy(buf, offset * sizeof(Elem), count * sizeof(Elem));
00330     }
00331     
00332     /*** Buffer Writing ***/
00333     
00334     /**
00335      * Returns true if the buffer supports writing.
00336      *
00337      * Returns: true if writing is supported
00338      */
00339     bool iswritable() const
00340     {
00341         return true;
00342     }
00343     
00344     /**
00345      * Returns the number of elements that the buffer can currently
00346      * accept for writing.
00347      * 
00348      * Returns: the number of elements
00349      */
00350     size_t free() const
00351     {
00352         return store->free() / sizeof(Elem);
00353     }
00354     
00355     /**
00356      * Allocates exactly the specified number of elements and returns
00357      * a pointer to an UNINITIALIZED storage location owned by the
00358      * buffer.
00359      * 
00360      * The pointer is only valid until the next non-const buffer
00361      * member is called. eg. alloc(size_t)
00362      * 
00363      * If count == 0, a NULL pointer may be returned.
00364      * 
00365      * It is an error for count to be greater than free().
00366      * 
00367      * For best results, call this function multiple times with
00368      * count no greater than optallocable() each time.
00369      * 
00370      * After this operation, at least count elements may be unallocated.
00371      * 
00372      *
00373      * "count" is the number of elements
00374      * Returns: the element storage pointer
00375      */
00376     T *alloc(size_t count)
00377     {
00378         return static_cast<T*>(store->alloc(count * sizeof(Elem)));
00379     }
00380     
00381     /**
00382      * Returns the optimal maximum number of elements that the
00383      * buffer can currently accept for writing without incurring
00384      * significant overhead.
00385      * 
00386      * Invariants:
00387      * 
00388      *  - optallocable() <= free()
00389      *  - optallocable() != 0 if free() != 0
00390      * 
00391      *
00392      * Returns: the number of elements
00393      */
00394     size_t optallocable() const
00395     {
00396         size_t avail = store->optallocable();
00397         size_t elems = avail / sizeof(Elem);
00398         if (elems != 0) return elems;
00399         return avail != 0 && store->free() >= sizeof(Elem) ? 1 : 0;
00400     }
00401 
00402     /**
00403      * Unallocates exactly the specified number of elements by removing
00404      * them from the buffer and releasing their storage.
00405      * 
00406      * This operation may always be safely performed with count
00407      * less than or equal to that specified in the last alloc(size_t)
00408      * or put(const T*, size_t) if no non-const buffer members have
00409      * been called since then.
00410      * 
00411      * If count == 0, nothing happens.
00412      * 
00413      * It is an error for count to be greater than unallocable().
00414      * 
00415      *
00416      * "count" is the number of elements
00417      */
00418     void unalloc(size_t count)
00419     {
00420         return store->unalloc(count * sizeof(Elem));
00421     }
00422 
00423     /**
00424      * Returns the maximum number of elements that may be unallocated
00425      * at this time.
00426      * 
00427      * For all practical purposes, this number will always be at least
00428      * as large as the amount currently in use.  It is provided
00429      * primarily for symmetry, but also to handle cases where
00430      * buffer reading (hence used()) is not supported by the
00431      * implementation.
00432      * 
00433      * Invariants:
00434      * 
00435      *  - unallocable() >= used()
00436      * 
00437      *
00438      * Returns: the number of elements
00439      */
00440     size_t unallocable() const
00441     {
00442         return store->unallocable() / sizeof(Elem);
00443     }
00444     
00445     /**
00446      * Returns a non-const pointer info the buffer at the specified
00447      * offset to the specified number of elements without actually
00448      * adjusting the current get() index.
00449      * 
00450      * Other than the fact that the returned storage is mutable,
00451      * operates identically to peek(int, size_t).
00452      * 
00453      *
00454      * "offset" is the buffer offset
00455      * "count" is the number of elements
00456      * Returns: the element storage pointer
00457      */
00458     T *mutablepeek(int offset, size_t count)
00459     {
00460         return static_cast<T*>(store->mutablepeek(
00461             offset * sizeof(Elem), count * sizeof(Elem)));
00462     }
00463 
00464     /**
00465      * Writes the specified number of elements from the specified
00466      * storage location into the buffer at its tail.
00467      * 
00468      * It is an error for count to be greater than free().
00469      * 
00470      * For maximum efficiency, choose as large a count as possible.
00471      * 
00472      * The pointer buf may be NULL only if count == 0.
00473      * 
00474      * After this operation, at least count elements may be unallocated.
00475      * 
00476      *
00477      * "data" is the buffer that contains the elements
00478      * "count" is the number of elements
00479      */
00480     void put(const T *data, size_t count)
00481     {
00482         store->put(data, count * sizeof(Elem));
00483     }
00484 
00485     /**
00486      * Efficiently copies the specified number of elements from the
00487      * specified storage location into the buffer at a particular
00488      * offset.
00489      * 
00490      * If offset <= used() and offset + count > used(), the
00491      * remaining data is simply tacked onto the end of the buffer
00492      * with put().
00493      * 
00494      * It is an error for count to be greater than free() - offset.
00495      * 
00496      *
00497      * "data" is the buffer that contains the elements
00498      * "count" is the number of elements
00499      * "offset" is the buffer offset, default 0
00500      */
00501     void poke(const T *data, int offset, size_t count)
00502     {
00503         store->poke(data, offset * sizeof(Elem), count * sizeof(Elem));
00504     }
00505 
00506     /**
00507      * Writes the element into the buffer at its tail.
00508      * 
00509      * It is an error to invoke this method if free() == 0.
00510      * 
00511      * After this operation, at least 1 element may be unallocated.
00512      * 
00513      *
00514      * "valid" is the element
00515      */
00516     void put(T &value)
00517     {
00518         store->fastput(& value, sizeof(Elem));
00519     }
00520 
00521     /**
00522      * Writes the element into the buffer at the specified offset.
00523      * 
00524      * It is an error to invoke this method if free() == 0.
00525      * 
00526      * After this operation, at least 1 element may be unallocated.
00527      * 
00528      *
00529      * "value" is the element
00530      * "offset" is the buffer offset
00531      */
00532     void poke(T &value, int offset)
00533     {
00534         poke(& value, offset, 1);
00535     }
00536 
00537 
00538     /*** Buffer to Buffer Transfers ***/
00539 
00540     /**
00541      * Efficiently moves count bytes from the specified buffer into
00542      * this one.  In some cases, this may be a zero-copy operation.
00543      * 
00544      * It is an error for count to be greater than inbuf.used().
00545      * 
00546      * For maximum efficiency, choose as large a count as possible.
00547      * 
00548      * After this operation, an indeterminate number of elements
00549      * may be ungotten from inbuf.
00550      * 
00551      *
00552      * "inbuf" is the buffer from which to read
00553      * "count" is the number of elements
00554      */
00555     void merge(Buffer &inbuf, size_t count)
00556     {
00557         store->merge(*inbuf.store, count * sizeof(Elem));
00558     }
00559 
00560     /**
00561      * Efficiently merges the entire contents of a buffer into this one.
00562      *
00563      * "inbuf" is the buffer from which to read
00564      */
00565     void merge(Buffer &inbuf)
00566     {
00567         merge(inbuf, inbuf.used());
00568     }
00569 };
00570 
00571 
00572 
00573 /**
00574  * The generic buffer base type.
00575  * To specialize buffers to add new functionality, declare a template
00576  * specialization of this type that derives from WvBufBaseCommonImpl.
00577  *
00578  * See WvBufBaseCommonImpl<T>
00579  * "T" is the type of object to store, must be a primitive or a struct
00580  *        without special initialization, copy, or assignment semantics
00581  */
00582 template<class T>
00583 class WvBufBase : public WvBufBaseCommonImpl<T>
00584 {
00585 public:
00586     explicit WvBufBase(WvBufStore *store) :
00587         WvBufBaseCommonImpl<T>(store) { }
00588 };
00589 
00590 
00591 
00592 /**
00593  * A buffer that wraps a pre-allocated array and provides
00594  * read-write access to its elements.
00595  *
00596  * "T" is the type of object to store, must be a primitive or a struct
00597  *        without special initialization, copy, or assignment semantics
00598  */
00599 template<class T>
00600 class WvInPlaceBufBase : public WvBufBase<T>
00601 {
00602 protected:
00603     typedef T Elem;
00604 
00605     WvInPlaceBufStore mystore;
00606 
00607 public:
00608     /**
00609      * Creates a new buffer backed by the supplied array.
00610      *
00611      * "_data" is the array of data to wrap
00612      * "_avail" is the amount of data available for reading
00613      * "_size" is the size of the array
00614      * "_autofree" is if true, the array will be freed when discarded
00615      */
00616     WvInPlaceBufBase(T *_data, size_t _avail, size_t _size,
00617         bool _autofree = false) :
00618         WvBufBase<T>(& mystore),
00619         mystore(sizeof(Elem), _data, _avail * sizeof(Elem),
00620             _size * sizeof(Elem), _autofree) { }
00621 
00622     /**
00623      * Creates a new empty buffer backed by a new array.
00624      *
00625      * "_size" is the size of the array
00626      */
00627     explicit WvInPlaceBufBase(size_t _size) :
00628         WvBufBase<T>(& mystore),
00629         mystore(sizeof(Elem), _size * sizeof(Elem)) { }
00630 
00631     /** Creates a new empty buffer with no backing array. */
00632     WvInPlaceBufBase() :
00633         WvBufBase<T>(& mystore),
00634         mystore(sizeof(Elem), NULL, 0, 0, false) { }
00635 
00636     /**
00637      * Destroys the buffer.
00638      * 
00639      * Frees the underlying array if autofree().
00640      * 
00641      */
00642     virtual ~WvInPlaceBufBase() { }
00643 
00644     /**
00645      * Returns the underlying array pointer.
00646      *
00647      * Returns: the element pointer
00648      */
00649     T *ptr() const
00650     {
00651         return static_cast<T*>(mystore.ptr());
00652     }
00653 
00654     /**
00655      * Returns the total size of the buffer.
00656      *
00657      * Returns: the number of elements
00658      */
00659     size_t size() const
00660     {
00661         return mystore.size() / sizeof(Elem);
00662     }
00663 
00664     /**
00665      * Returns the autofree flag.
00666      *
00667      * Returns: the autofree flag
00668      */
00669     bool autofree() const
00670     {
00671         return mystore.autofree();
00672     }
00673 
00674     /**
00675      * Sets or clears the auto_free flag.
00676      *
00677      * "_autofree" is if true, the array will be freed when discarded
00678      */
00679     void setautofree(bool _autofree)
00680     {
00681         mystore.setautofree(_autofree);
00682     }
00683 
00684     /**
00685      * Resets the underlying buffer pointer and properties.
00686      * 
00687      * If the old and new buffer pointers differ and the old buffer
00688      * was specified as auto_free, the old buffer is destroyed.
00689      * 
00690      * "_data" is the array of data to wrap
00691      * "_avail" is the amount of data available for reading
00692      * "_size" is the size of the array
00693      * "_autofree" is if true, the array will be freed when discarded
00694      */
00695     void reset(T *_data, size_t _avail, size_t _size,
00696         bool _autofree = false)
00697     {
00698         mystore.reset(_data, _avail * sizeof(Elem),
00699             _size * sizeof(Elem), _autofree);
00700     }
00701 
00702     /**
00703      * Sets the amount of available data using the current buffer
00704      * and resets the read index to the beginning of the buffer.
00705      *
00706      * "_avail" is the amount of data available for reading
00707      */
00708     void setavail(size_t _avail)
00709     {
00710         mystore.setavail(_avail * sizeof(Elem));
00711     }
00712 };
00713 
00714 
00715 
00716 /**
00717  * A buffer that wraps a pre-allocated array and provides
00718  * read-only access to its elements.
00719  *
00720  * "T" is the type of object to store, must be a primitive or a struct
00721  *        without special initialization, copy, or assignment semantics
00722  */
00723 template<class T>
00724 class WvConstInPlaceBufBase : public WvBufBase<T>
00725 {
00726 protected:
00727     typedef T Elem;
00728 
00729     WvConstInPlaceBufStore mystore;
00730 
00731 public:
00732     /**
00733      * Creates a new buffer backed by the supplied array.
00734      *
00735      * "_data" is the array of data to wrap
00736      * "_avail" is the amount of data available for reading
00737      */
00738     WvConstInPlaceBufBase(const T *_data, size_t _avail) :
00739         WvBufBase<T>(& mystore),
00740         mystore(sizeof(Elem), _data, _avail * sizeof(Elem)) { }
00741 
00742     /** Creates a new empty buffer with no backing array. */
00743     WvConstInPlaceBufBase() :
00744         WvBufBase<T>(& mystore),
00745         mystore(sizeof(Elem), NULL, 0) { }
00746 
00747     /**
00748      * Destroys the buffer.
00749      * 
00750      * Never frees the underlying array.
00751      * 
00752      */
00753     virtual ~WvConstInPlaceBufBase() { }
00754 
00755     /**
00756      * Returns the underlying array pointer.
00757      *
00758      * Returns: the element pointer
00759      */
00760     const T *ptr() const
00761     {
00762         return static_cast<const T*>(mystore.ptr());
00763     }
00764 
00765     /**
00766      * Resets the underlying buffer pointer and properties.
00767      * 
00768      * Never frees the old buffer.
00769      * 
00770      *
00771      * "_data" is the array of data to wrap
00772      * "_avail" is the amount of data available for reading
00773      */
00774     void reset(const T *_data, size_t _avail)
00775     {
00776         mystore.reset(_data, _avail * sizeof(Elem));
00777     }
00778 
00779     /**
00780      * Sets the amount of available data using the current buffer
00781      * and resets the read index to the beginning of the buffer.
00782      *
00783      * "_avail" is the amount of data available for reading
00784      */
00785     void setavail(size_t _avail)
00786     {
00787         mystore.setavail(_avail * sizeof(Elem));
00788     }
00789 };
00790 
00791 
00792 
00793 /**
00794  * A buffer that wraps a pre-allocated array and provides
00795  * read-write access to its elements using a circular buffering
00796  * scheme rather than a purely linear one, as used by
00797  * WvInPlaceBuf.  
00798  *
00799  * When there is insufficient contigous free/used space to
00800  * satisfy a read or write request, the data is automatically
00801  * reordered in-place to coalesce the free/used spaces into
00802  * sufficiently large chunks.  The process may also be manually
00803  * triggered to explicitly renormalize the array and shift its
00804  * contents to the front.
00805  *
00806  * "T" is the type of object to store, must be a primitive or a struct
00807  *        without special initialization, copy, or assignment semantics
00808  */
00809 template<class T>
00810 class WvCircularBufBase : public WvBufBase<T>
00811 {
00812 protected:
00813     typedef T Elem;
00814 
00815     WvCircularBufStore mystore;
00816 
00817 public:
00818     /**
00819      * Creates a new circular buffer backed by the supplied array.
00820      *
00821      * "_data" is the array of data to wrap
00822      * "_avail" is the amount of data available for reading
00823      *               at the beginning of the buffer
00824      * "_size" is the size of the array
00825      * "_autofree" is if true, the array will be freed when discarded
00826      */
00827     WvCircularBufBase(T *_data, size_t _avail, size_t _size,
00828         bool _autofree = false) :
00829         WvBufBase<T>(& mystore),
00830         mystore(sizeof(Elem), _data, _avail * sizeof(Elem),
00831             _size * sizeof(Elem), _autofree) { }
00832 
00833     /**
00834      * Creates a new empty circular buffer backed by a new array.
00835      *
00836      * "_size" is the size of the array
00837      */
00838     explicit WvCircularBufBase(size_t _size) :
00839         WvBufBase<T>(& mystore),
00840         mystore(sizeof(Elem), _size * sizeof(Elem)) { }
00841 
00842     /** Creates a new empty buffer with no backing array. */
00843     WvCircularBufBase() :
00844         WvBufBase<T>(& mystore),
00845         mystore(sizeof(Elem), NULL, 0, 0, false) { }
00846 
00847     /**
00848      * Destroys the buffer.
00849      * 
00850      * Frees the underlying array if autofree().
00851      * 
00852      */
00853     virtual ~WvCircularBufBase() { }
00854 
00855     /**
00856      * Returns the underlying array pointer.
00857      *
00858      * Returns: the element pointer
00859      */
00860     T *ptr() const
00861     {
00862         return static_cast<T*>(mystore.ptr());
00863     }
00864 
00865     /**
00866      * Returns the total size of the buffer.
00867      *
00868      * Returns: the number of elements
00869      */
00870     size_t size() const
00871     {
00872         return mystore.size() / sizeof(Elem);
00873     }
00874 
00875     /**
00876      * Returns the autofree flag.
00877      *
00878      * Returns: the autofree flag
00879      */
00880     bool autofree() const
00881     {
00882         return mystore.autofree();
00883     }
00884 
00885     /**
00886      * Sets or clears the auto_free flag.
00887      *
00888      * "_autofree" is if true, the array will be freed when discarded
00889      */
00890     void setautofree(bool _autofree)
00891     {
00892         mystore.setautofree(_autofree);
00893     }
00894 
00895     /**
00896      * Resets the underlying buffer pointer and properties.
00897      * 
00898      * If the old and new buffer pointers differ and the old buffer
00899      * was specified as auto_free, the old buffer is destroyed.
00900      * 
00901      * "_data" is the array of data to wrap
00902      * "_avail" is the amount of data available for reading 
00903      *               at the beginning of the buffer
00904      * "_size" is the size of the array
00905      * "_autofree" is if true, the array will be freed when discarded
00906      */
00907     void reset(T *_data, size_t _avail, size_t _size,
00908         bool _autofree = false)
00909     {
00910         mystore.reset(_data, _avail * sizeof(Elem),
00911             _size * sizeof(Elem), _autofree);
00912     }
00913 
00914     /**
00915      * Sets the amount of available data using the current buffer
00916      * and resets the read index to the beginning of the buffer.
00917      *
00918      * "_avail" is the amount of data available for reading
00919      *               at the beginning of the buffer
00920      */
00921     void setavail(size_t _avail)
00922     {
00923         mystore.setavail(_avail * sizeof(Elem));
00924     }
00925 
00926     /**
00927      * Normalizes the arrangement of the data such that the
00928      * contents of the buffer are stored at the beginning of
00929      * the array starting with the next element that would be
00930      * returned by get(size_t).
00931      * 
00932      * After invocation, ungettable() may equal 0.
00933      * 
00934      */
00935     void normalize()
00936     {
00937         mystore.normalize();
00938     }
00939 };
00940 
00941 
00942 
00943 /**
00944  * A buffer that dynamically grows and shrinks based on demand.
00945  *
00946  * "T" is the type of object to store, must be a primitive or a struct
00947  *        without special initialization, copy, or assignment semantics
00948  */
00949 template<class T>
00950 class WvDynBufBase : public WvBufBase<T>
00951 {
00952 protected:
00953     typedef T Elem;
00954 
00955     WvDynBufStore mystore;
00956     
00957 public:
00958     /**
00959      * Creates a new buffer.
00960      * 
00961      * Provides some parameters for tuning response to buffer
00962      * growth.
00963      * 
00964      * "_minalloc" is the minimum number of elements to allocate
00965      *      at once when creating a new internal buffer segment
00966      * "_maxalloc" is the maximum number of elements to allocate
00967      *      at once when creating a new internal buffer segment
00968      *      before before reverting to a linear growth pattern
00969      */
00970     explicit WvDynBufBase(size_t _minalloc = 1024,
00971         size_t _maxalloc = 1048576) :
00972         WvBufBase<T>(& mystore),
00973         mystore(sizeof(Elem), _minalloc * sizeof(Elem),
00974             _maxalloc * sizeof(Elem)) { }
00975 };
00976 
00977 
00978 
00979 /**
00980  * A buffer that is always empty.
00981  *
00982  * "T" is the type of object to store, must be a primitive or a struct
00983  *        without special initialization, copy, or assignment semantics
00984  */
00985 template<class T>
00986 class WvNullBufBase : public WvBufBase<T>
00987 {
00988 protected:
00989     typedef T Elem;
00990 
00991     WvNullBufStore mystore;
00992 
00993 public:
00994     /** Creates a new buffer. */
00995     WvNullBufBase() :
00996         WvBufBase<T>(& mystore),
00997         mystore(sizeof(Elem)) { }
00998 };
00999 
01000 
01001 
01002 /**
01003  * A buffer that acts like a cursor over a portion of another buffer.
01004  * The underlying buffer's get() position is not affected by
01005  * reading from this buffer.
01006  *
01007  * "T" is the type of object to store, must be a primitive or a struct
01008  *        without special initialization, copy, or assignment semantics
01009  */
01010 template<class T>
01011 class WvBufCursorBase : public WvBufBase<T>
01012 {
01013 protected:
01014     typedef T Elem;
01015 
01016     WvBufCursorStore mystore;
01017 
01018 public:
01019     /**
01020      * Creates a new buffer.
01021      * 
01022      * Does not take ownership of the supplied buffer.
01023      * 
01024      *
01025      * "_buf" is a pointer to the buffer to be wrapped
01026      * "_start" is the buffer offset of the window start position
01027      * "_length" is the length of the window
01028      */
01029     WvBufCursorBase(WvBufBase<T> &_buf, int _start,
01030         size_t _length) :
01031         WvBufBase<T>(& mystore),
01032         mystore(sizeof(Elem), _buf.getstore(),
01033             _start * sizeof(Elem), _length * sizeof(Elem)) { }
01034 };
01035 
01036 
01037 /**
01038  * A buffer that provides a read-write view over another buffer
01039  * with a different datatype.  Reading and writing through this
01040  * buffer implicitly performs the equivalent of reinterpret_cast
01041  * on each element.
01042  *
01043  * Most useful for manipulating data backed by a raw memory buffer.
01044  *
01045  * "T" is the type of object to store, must be a primitive or a struct
01046  *        without special initialization, copy, or assignment semantics
01047  */
01048 template<class T>
01049 class WvBufViewBase : public WvBufBase<T>
01050 {
01051 public:
01052     /**
01053      * Creates a new buffer.
01054      * 
01055      * Does not take ownership of the supplied buffer.
01056      * 
01057      *
01058      * "_buf" is a pointer to the buffer to be wrapped
01059      */
01060     template<typename S>
01061     WvBufViewBase(WvBufBase<S> &_buf) :
01062         WvBufBase<T>(_buf.getstore()) { }
01063 };
01064 
01065 #endif // __WVBUFFERBASE_H

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