AttributeBlob.h

Go to the documentation of this file.
00001 // $Id: AttributeBlob.h 114 2006-04-30 18:01:54Z bingmann $
00002 
00003 #ifndef VGS_AttributeBlob_H
00004 #define VGS_AttributeBlob_H
00005 
00006 #include <stdlib.h>
00007 #include <assert.h>
00008 
00009 #include <utility>
00010 #include <string>
00011 
00012 #include "GraphTypes.h"
00013 #include "AnyType.h"
00014 #include "AttributeProperties.h"
00015 
00016 namespace VGServer {
00017 
00024 template <typename AllocPolicy>
00025 class TpAttributeBlob
00026 {
00027 private:
00029     typedef TpAttributeBlob<AllocPolicy>        thistype;
00030 
00032     char *_data;
00033 
00035     unsigned int _size;
00036 
00040     //virtual unsigned int realloc_size(unsigned int current_capacity, unsigned int min_new_capacity) = 0;
00041 
00042 public:
00044     inline TpAttributeBlob()
00045         : _data(NULL), _size(0)
00046     {
00047     }
00048 
00050     explicit inline TpAttributeBlob(unsigned int n)
00051         : _data(NULL), _size(0)
00052     {
00053         alloc(n);
00054     }
00055 
00057     explicit inline TpAttributeBlob(const void *data, unsigned int len)
00058         : _data(NULL), _size(0)
00059     {
00060         copy(0, data, len);
00061     }
00062 
00064     inline TpAttributeBlob(const thistype &other)
00065         : _data(NULL), _size(0)
00066     {
00067         copy(0, other.data(), other.size());
00068     }
00069 
00072     inline thistype& operator=(const thistype &other)
00073     {
00074         copy(0, other.data(), other.size());
00075         return *this;
00076     }
00077 
00079     inline virtual ~TpAttributeBlob() {
00080         dealloc();
00081     }
00082 
00084     inline const char *data() const
00085     { return _data; }
00086 
00088     inline char *data()
00089     { return _data; }
00090 
00093     inline const char *data(unsigned int i) const
00094     { return _data + i; }
00095 
00098     inline unsigned int size() const
00099     { return _size; }
00100 
00102     inline bool empty() const
00103     { return size() == 0; }
00104 
00106     inline void alloc(unsigned int n)
00107     { if (_size < n) _alloc(n); }
00108 
00110     void _alloc(unsigned int n)
00111     {
00112         if (_size < n)
00113         {
00114             unsigned int newcap = AllocPolicy::realloc_size(_size, n);
00115             assert(n <= newcap);
00116 
00117             _data = static_cast<char*>(realloc(_data, newcap));
00118             //printf("TpAttributeBlob::realloc: %u\n", _size);
00119 
00120             // TODO: remove this debug tool
00121             for(unsigned int i = _size; i < newcap; i++)
00122                 _data[i] = i;
00123 
00124             _size = newcap;
00125         }
00126     }
00127 
00129     void clear()
00130     { _size = 0; }
00131 
00134     inline void dealloc()
00135     {
00136         if (_data) free(_data);
00137         _data = NULL;
00138         _size = 0;
00139     }
00140 
00142     inline const char *detach() {
00143         const char *data = _data;
00144         _data = NULL;
00145         _size = 0;
00146         return data;
00147     }
00148 
00151     inline std::pair<const char*, unsigned int> detach_pair()
00152     {
00153         std::pair<const char*, unsigned int> pair(_data, _size);
00154         _data = NULL;
00155         _size = 0;
00156         return pair;
00157     }
00158 
00161     inline std::string getRange(unsigned int i, unsigned int len) const
00162     { assert(i+len < _size); return std::string(data(i), len); }
00163 
00165     inline void swap(thistype &other)
00166     {
00167         std::swap(_data, other._data);
00168         std::swap(_size, other._size);
00169     }
00170 
00171     // *** Read Functions
00172 
00174     inline char operator[](unsigned int i) const
00175     {
00176         assert(i < _size);
00177         return _data[i];
00178     }
00179 
00184     inline bool getBool(unsigned int i, unsigned int bitnum) const
00185     {
00186         i += bitnum / 8;
00187         bitnum %= 8;
00188         assert(i < _size);
00189 
00190         return (_data[i] & (1 << bitnum)) != 0;
00191     }
00192 
00195     template <typename T>
00196     inline T get(unsigned int i) const
00197     {
00198         assert(i + sizeof(T)-1 < _size);
00199         return *reinterpret_cast<T*>(_data+i);
00200     }
00201 
00203     inline std::string getString(unsigned int i) const
00204     {
00205         unsigned char slen = get<unsigned char>(i);
00206         assert(i + sizeof(char)-1 + slen < _size);
00207         return std::string(_data + i + 1, slen);
00208     }
00209 
00211     inline std::string getLongstring(unsigned int i) const
00212     {
00213         unsigned int slen = get<unsigned int>(i);
00214         assert(i + sizeof(int)-1 + slen < _size);
00215         return std::string(_data + i + 4, slen);
00216     }
00217 
00219     void getAnyType(unsigned int i, AnyType &v) const;
00220 
00221     // *** Write Functions
00222 
00224     inline void copy(unsigned int i, const void *indata, unsigned int inlen)
00225     {
00226         alloc(i + inlen);
00227         memcpy(_data + i, indata, inlen);
00228     }
00229 
00231     inline void zero(unsigned int i, unsigned int len)
00232     {
00233         alloc(i + len);
00234         memset(_data + i, 0, len);
00235     }
00236 
00239     inline void move(unsigned int src, unsigned int dst, unsigned int len)
00240     {
00241         alloc(dst + len);
00242         assert(src + len <= _size);
00243         memmove(_data + dst, _data + src, len);
00244     }
00245 
00251     inline void putBool(unsigned int i, unsigned int bitnum, bool v)
00252     {
00253         i += bitnum / 8;
00254         bitnum %= 8;
00255         alloc(i + 1);
00256 
00257         if (v) {
00258             _data[i] |= (1 << bitnum);
00259         }
00260         else {
00261             _data[i] &= ~(1 << bitnum);
00262         }
00263     }
00264 
00266     template <typename ValTp>
00267     inline void put(unsigned int i, ValTp v)
00268     {
00269         alloc(i + sizeof(ValTp));
00270         *reinterpret_cast<ValTp*>(_data+i) = v;
00271     }
00272 
00274     inline void putString(unsigned int i, const std::string &s)
00275     {
00276         alloc(i + 1 + s.size());
00277         put<unsigned char>(i, static_cast<unsigned char>(s.size()));
00278         memcpy(_data+i+1, s.data(), s.size());
00279     }
00280 
00282     inline void putLongstring(unsigned int i, const std::string &s)
00283     {
00284         alloc(i + 4 + s.size());
00285         put<unsigned int>(i, static_cast<unsigned int>(s.size()));
00286         memcpy(_data+i+4, s.data(), s.size());
00287     }
00288 
00290     void putAnyType(unsigned int i, const AnyType &v);
00291 
00293     unsigned int getAttrChainLength(unsigned int chidx, const AttributePropertiesList &attrlist) const;
00294 
00296     class AnyType getAttrChainValue(unsigned int chidx, unsigned int attrid, const AttributePropertiesList &attrlist) const;
00297 
00299     bool putAttrChainValue(const AttributePropertiesList &attrlist,
00300                                   unsigned int attrid, const AnyType &value);
00301 
00302 };
00303 
00304 // *** Three Specializations of the Template Class
00305 
00309 class AttributeBigBlobPolicy
00310 {
00311 public:
00312     static unsigned int realloc_size(unsigned int cap, unsigned int minnewcap)
00313     {
00314         // place to adapt the buffer growing algorithm as need.
00315         while(cap < minnewcap)
00316         {
00317             if (cap < 256) cap = 512;
00318             else if (cap < 1024*1024) cap = 2*cap;
00319             else cap += 1024*1024;
00320         }
00321         return cap;
00322     }
00323 };
00324 
00325 typedef TpAttributeBlob<AttributeBigBlobPolicy> AttributeBigBlob;
00326 
00332 class AttributeVertexTinyBlobPolicy
00333 {
00334 public:
00335     static unsigned int realloc_size(unsigned int cap, unsigned int minnewcap)
00336     {
00337         // place to adapt the buffer growing algorithm as need.
00338         while(cap < minnewcap)
00339         {
00340             if (cap < 8) cap = 8;
00341             else if (cap < 1024) cap = 2*cap;
00342             else cap += 1024;
00343         }
00344         return cap;
00345     }
00346 };
00347 
00348 typedef TpAttributeBlob<AttributeVertexTinyBlobPolicy> AttributeVertexTinyBlob;
00349 
00355 struct AttributeEdgeTinyBlobPolicy
00356 {
00357     static unsigned int realloc_size(unsigned int cap, unsigned int minnewcap)
00358     {
00359         // place to adapt the buffer growing algorithm as need.
00360         while(cap < minnewcap)
00361         {
00362             if (cap < 8) cap = 8;
00363             else if (cap < 1024) cap = 2*cap;
00364             else cap += 1024;
00365         }
00366         return cap;
00367     }
00368 };
00369 
00370 typedef TpAttributeBlob<AttributeEdgeTinyBlobPolicy> AttributeEdgeTinyBlob;
00371 
00372 } // namespace VGServer
00373 
00374 #endif // VGS_ByteOutBuffer_H

Generated on Wed Sep 27 14:34:00 2006 for VGServer by  doxygen 1.4.7