WvStreams
wvbufbase.h
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 
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:
00057     explicit WvBufBaseCommonImpl(WvBufStore *store) :
00058         store(store) { }
00059 
00060 public:
00062     virtual ~WvBufBaseCommonImpl() { }
00063 
00069     WvBufStore *getstore()
00070     {
00071         return store;
00072     }
00073 
00074     /*** Buffer Reading ***/
00075 
00081     bool isreadable() const
00082     {
00083         return store->isreadable();
00084     }
00085     
00092     size_t used() const
00093     {
00094         return store->used() / sizeof(Elem);
00095     }
00096 
00114     const T *get(size_t count)
00115     {
00116         if (count > used())
00117             return NULL;
00118 
00119         return static_cast<const T*>(
00120             store->get(count * sizeof(Elem)));
00121     }
00122 
00136     void skip(size_t count)
00137     {
00138         store->skip(count * sizeof(Elem));
00139     }
00140 
00154     size_t optgettable() const
00155     {
00156         size_t avail = store->optgettable();
00157         size_t elems = avail / sizeof(Elem);
00158         if (elems != 0) return elems;
00159         return avail != 0 && store->used() >= sizeof(Elem) ? 1 : 0;
00160     }
00161 
00177     void unget(size_t count)
00178     {
00179         store->unget(count * sizeof(Elem));
00180     }
00181 
00188     size_t ungettable() const
00189     {
00190         return store->ungettable() / sizeof(Elem);
00191     }
00192 
00225     const T *peek(int offset, size_t count)
00226     {
00227         return static_cast<const T*>(store->peek(
00228             offset * sizeof(Elem), count * sizeof(Elem)));
00229     }
00230 
00231     size_t peekable(int offset)
00232     {
00233         return store->peekable(offset * sizeof(Elem)) / sizeof(Elem);
00234     }
00235 
00236     size_t optpeekable(int offset)
00237     {
00238         offset *= sizeof(Elem);
00239         size_t avail = store->optpeekable(offset);
00240         size_t elems = avail / sizeof(Elem);
00241         if (elems != 0) return elems;
00242         return avail != 0 &&
00243             store->peekable(offset) >= sizeof(Elem) ? 1 : 0;
00244     }
00245 
00257     void zap()
00258     {
00259         store->zap();
00260     }
00261 
00272     T get()
00273     {
00274         return *get(1);
00275     }
00276 
00286     T peek(int offset = 0)
00287     {
00288         return *peek(offset * sizeof(Elem), sizeof(Elem));
00289     }
00290 
00309     void move(T *buf, size_t count)
00310     {
00311         store->move(buf, count * sizeof(Elem));
00312     }
00313     
00330     void copy(T *buf, int offset, size_t count)
00331     {
00332         store->copy(buf, offset * sizeof(Elem), count * sizeof(Elem));
00333     }
00334     
00335     /*** Buffer Writing ***/
00336     
00342     bool iswritable() const
00343     {
00344         return true;
00345     }
00346     
00353     size_t free() const
00354     {
00355         return store->free() / sizeof(Elem);
00356     }
00357     
00379     T *alloc(size_t count)
00380     {
00381         return static_cast<T*>(store->alloc(count * sizeof(Elem)));
00382     }
00383     
00397     size_t optallocable() const
00398     {
00399         size_t avail = store->optallocable();
00400         size_t elems = avail / sizeof(Elem);
00401         if (elems != 0) return elems;
00402         return avail != 0 && store->free() >= sizeof(Elem) ? 1 : 0;
00403     }
00404 
00421     void unalloc(size_t count)
00422     {
00423         return store->unalloc(count * sizeof(Elem));
00424     }
00425 
00443     size_t unallocable() const
00444     {
00445         return store->unallocable() / sizeof(Elem);
00446     }
00447     
00461     T *mutablepeek(int offset, size_t count)
00462     {
00463         return static_cast<T*>(store->mutablepeek(
00464             offset * sizeof(Elem), count * sizeof(Elem)));
00465     }
00466 
00483     void put(const T *data, size_t count)
00484     {
00485         store->put(data, count * sizeof(Elem));
00486     }
00487 
00504     void poke(const T *data, int offset, size_t count)
00505     {
00506         store->poke(data, offset * sizeof(Elem), count * sizeof(Elem));
00507     }
00508 
00519     void put(T &value)
00520     {
00521         store->fastput(& value, sizeof(Elem));
00522     }
00523 
00535     void poke(T &value, int offset)
00536     {
00537         poke(& value, offset, 1);
00538     }
00539 
00540 
00541     /*** Buffer to Buffer Transfers ***/
00542 
00558     void merge(Buffer &inbuf, size_t count)
00559     {
00560         store->merge(*inbuf.store, count * sizeof(Elem));
00561     }
00562 
00568     void merge(Buffer &inbuf)
00569     {
00570         merge(inbuf, inbuf.used());
00571     }
00572 };
00573 
00574 
00575 
00585 template<class T>
00586 class WvBufBase : public WvBufBaseCommonImpl<T>
00587 {
00588 public:
00589     explicit WvBufBase(WvBufStore *store) :
00590         WvBufBaseCommonImpl<T>(store) { }
00591 };
00592 
00593 
00594 
00602 template<class T>
00603 class WvInPlaceBufBase : public WvBufBase<T>
00604 {
00605 protected:
00606     typedef T Elem;
00607 
00608     WvInPlaceBufStore mystore;
00609 
00610 public:
00619     WvInPlaceBufBase(T *_data, size_t _avail, size_t _size,
00620         bool _autofree = false) :
00621         WvBufBase<T>(& mystore),
00622         mystore(sizeof(Elem), _data, _avail * sizeof(Elem),
00623             _size * sizeof(Elem), _autofree) { }
00624 
00630     explicit WvInPlaceBufBase(size_t _size) :
00631         WvBufBase<T>(& mystore),
00632         mystore(sizeof(Elem), _size * sizeof(Elem)) { }
00633 
00635     WvInPlaceBufBase() :
00636         WvBufBase<T>(& mystore),
00637         mystore(sizeof(Elem), NULL, 0, 0, false) { }
00638 
00645     virtual ~WvInPlaceBufBase() { }
00646 
00652     T *ptr() const
00653     {
00654         return static_cast<T*>(mystore.ptr());
00655     }
00656 
00662     size_t size() const
00663     {
00664         return mystore.size() / sizeof(Elem);
00665     }
00666 
00672     bool get_autofree() const
00673     {
00674         return mystore.get_autofree();
00675     }
00676 
00682     void set_autofree(bool _autofree)
00683     {
00684         mystore.set_autofree(_autofree);
00685     }
00686 
00698     void reset(T *_data, size_t _avail, size_t _size,
00699         bool _autofree = false)
00700     {
00701         mystore.reset(_data, _avail * sizeof(Elem),
00702             _size * sizeof(Elem), _autofree);
00703     }
00704 
00711     void setavail(size_t _avail)
00712     {
00713         mystore.setavail(_avail * sizeof(Elem));
00714     }
00715 };
00716 
00717 
00718 
00726 template<class T>
00727 class WvConstInPlaceBufBase : public WvBufBase<T>
00728 {
00729 protected:
00730     typedef T Elem;
00731 
00732     WvConstInPlaceBufStore mystore;
00733 
00734 public:
00741     WvConstInPlaceBufBase(const T *_data, size_t _avail) :
00742         WvBufBase<T>(& mystore),
00743         mystore(sizeof(Elem), _data, _avail * sizeof(Elem)) { }
00744 
00746     WvConstInPlaceBufBase() :
00747         WvBufBase<T>(& mystore),
00748         mystore(sizeof(Elem), NULL, 0) { }
00749 
00756     virtual ~WvConstInPlaceBufBase() { }
00757 
00763     const T *ptr() const
00764     {
00765         return static_cast<const T*>(mystore.ptr());
00766     }
00767 
00777     void reset(const T *_data, size_t _avail)
00778     {
00779         mystore.reset(_data, _avail * sizeof(Elem));
00780     }
00781 
00788     void setavail(size_t _avail)
00789     {
00790         mystore.setavail(_avail * sizeof(Elem));
00791     }
00792 };
00793 
00794 
00795 
00812 template<class T>
00813 class WvCircularBufBase : public WvBufBase<T>
00814 {
00815 protected:
00816     typedef T Elem;
00817 
00818     WvCircularBufStore mystore;
00819 
00820 public:
00830     WvCircularBufBase(T *_data, size_t _avail, size_t _size,
00831         bool _autofree = false) :
00832         WvBufBase<T>(& mystore),
00833         mystore(sizeof(Elem), _data, _avail * sizeof(Elem),
00834             _size * sizeof(Elem), _autofree) { }
00835 
00841     explicit WvCircularBufBase(size_t _size) :
00842         WvBufBase<T>(& mystore),
00843         mystore(sizeof(Elem), _size * sizeof(Elem)) { }
00844 
00846     WvCircularBufBase() :
00847         WvBufBase<T>(& mystore),
00848         mystore(sizeof(Elem), NULL, 0, 0, false) { }
00849 
00856     virtual ~WvCircularBufBase() { }
00857 
00863     T *ptr() const
00864     {
00865         return static_cast<T*>(mystore.ptr());
00866     }
00867 
00873     size_t size() const
00874     {
00875         return mystore.size() / sizeof(Elem);
00876     }
00877 
00883     bool get_autofree() const
00884     {
00885         return mystore.get_autofree();
00886     }
00887 
00893     void set_autofree(bool _autofree)
00894     {
00895         mystore.set_autofree(_autofree);
00896     }
00897 
00910     void reset(T *_data, size_t _avail, size_t _size,
00911         bool _autofree = false)
00912     {
00913         mystore.reset(_data, _avail * sizeof(Elem),
00914             _size * sizeof(Elem), _autofree);
00915     }
00916 
00924     void setavail(size_t _avail)
00925     {
00926         mystore.setavail(_avail * sizeof(Elem));
00927     }
00928 
00938     void normalize()
00939     {
00940         mystore.normalize();
00941     }
00942 };
00943 
00944 
00945 
00952 template<class T>
00953 class WvDynBufBase : public WvBufBase<T>
00954 {
00955 protected:
00956     typedef T Elem;
00957 
00958     WvDynBufStore mystore;
00959     
00960 public:
00973     explicit WvDynBufBase(size_t _minalloc = 1024,
00974         size_t _maxalloc = 1048576) :
00975         WvBufBase<T>(& mystore),
00976         mystore(sizeof(Elem), _minalloc * sizeof(Elem),
00977             _maxalloc * sizeof(Elem)) { }
00978 };
00979 
00980 
00981 
00988 template<class T>
00989 class WvNullBufBase : public WvBufBase<T>
00990 {
00991 protected:
00992     typedef T Elem;
00993 
00994     WvNullBufStore mystore;
00995 
00996 public:
00998     WvNullBufBase() :
00999         WvBufBase<T>(& mystore),
01000         mystore(sizeof(Elem)) { }
01001 };
01002 
01003 
01004 
01013 template<class T>
01014 class WvBufCursorBase : public WvBufBase<T>
01015 {
01016 protected:
01017     typedef T Elem;
01018 
01019     WvBufCursorStore mystore;
01020 
01021 public:
01032     WvBufCursorBase(WvBufBase<T> &_buf, int _start,
01033         size_t _length) :
01034         WvBufBase<T>(& mystore),
01035         mystore(sizeof(Elem), _buf.getstore(),
01036             _start * sizeof(Elem), _length * sizeof(Elem)) { }
01037 };
01038 
01039 
01051 template<class T>
01052 class WvBufViewBase : public WvBufBase<T>
01053 {
01054 public:
01063     template<typename S>
01064     WvBufViewBase(WvBufBase<S> &_buf) :
01065         WvBufBase<T>(_buf.getstore()) { }
01066 };
01067 
01068 #endif // __WVBUFFERBASE_H