WvStreams
|
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