00001
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
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
00119
00120
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
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
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
00305
00309 class AttributeBigBlobPolicy
00310 {
00311 public:
00312 static unsigned int realloc_size(unsigned int cap, unsigned int minnewcap)
00313 {
00314
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
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
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 }
00373
00374 #endif // VGS_ByteOutBuffer_H