00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef DATA_HPP_
00040 #define DATA_HPP_
00041
00042
00043 #include <stdlib.h>
00044 #include <iostream>
00045 #include <boost/cstdint.hpp>
00046 #include <boost/type_traits/make_unsigned.hpp>
00047
00048
00049 template<typename T> class DefaultDataModel;
00050 template<typename T = uint8_t, typename DataModel = DefaultDataModel<uint8_t> > class DataTpl;
00051 typedef DataTpl<> Data;
00052 template<typename T, typename DataModel> std::ostream& operator<<(std::ostream& stream, const DataTpl<T, DataModel>& data);
00053
00054
00055 #include "../internal/Utilities.hpp"
00056
00057
00058 #include "DataUtilities.hpp"
00059 #include "Serialization.hpp"
00060
00075 template<typename T, typename DataModel>
00076 class DataTpl: public Serializeable { SERIALIZEABLE
00077 protected:
00078 typedef DataTpl<T,DataModel> _Data;
00079 DataModel model;
00080
00081 public:
00082 static const size_t word_width = sizeof(T) * 8;
00083
00084 class DataManipulator {
00085 private:
00086 DataModel bits;
00087 size_t index;
00088
00089 public:
00090 finline DataManipulator( DataModel& _bits, size_t _index) :
00091 bits(_bits), index(_index) {
00092 }
00093
00094 template<typename X>
00095 finline operator X() const {
00096 return bitget<X>(bits.buffer(), index);
00097 }
00098
00099 template<typename X>
00100 finline DataManipulator& operator=(X value) {
00101 bitset(value, bits.buffer(), index );
00102 return *this;
00103 }
00104
00105 template<typename X>
00106 finline void set(X value, size_t length = sizeof(X) * 8, if_uint(X)) {
00107 bitcpy(value, 0, bits.buffer(), index, length);
00108 }
00109
00110 template<typename X>
00111 finline void set(X value, size_t length = sizeof(X) * 8, if_int(X)) {
00112 set(_unsigned(value),length);
00113 }
00114
00115 template<typename X>
00116 finline void get(X& value, size_t length = sizeof(X) * 8, if_uint(X)) const {
00117 value = bitget<X> (bits.buffer(), index, length);
00118 }
00119
00120 template<typename X>
00121 finline void get(X& value, size_t length = sizeof(X) * 8, if_int(X)) const {
00122 typedef typename boost::make_unsigned<X>::type unsigned_type;
00123 _unsigned(value) = bitget<unsigned_type> (bits.buffer(), index, length);
00124 }
00125
00126 finline void get(bool& value) const {
00127 value = bitget( bits.buffer(), index );
00128 }
00129 };
00130
00131 public:
00132 static const Data UNSPECIFIED;
00133
00137 finline DataTpl() : model() {
00138 }
00139
00143 finline DataTpl(const DataTpl<T, DataModel>& copy) {
00144 this->model = copy.model;
00145 }
00146
00147 finline DataTpl( const DataModel& _model ) : model( _model ) {
00148 }
00149
00153 finline DataTpl(const T* buffer, size_t length) {
00154 model.buffer() = buffer;
00155 model.length() = length;
00156 }
00157
00161 finline DataTpl( T* buffer, size_t length ) {
00162 model.buffer() = buffer;
00163 model.length() = length;
00164 }
00165
00170 finline DataTpl(size_t length) : model() {
00171 model.resize(length);
00172 }
00173
00174
00178 finline T* getBuffer() const {
00179 return model.buffer();
00180 }
00181
00185 finline size_t getLength() const {
00186 return model.length();
00187 }
00191 void setLength(size_t new_length) {
00192 model.resize(new_length);
00193 }
00194
00201 finline void ensureLength( size_t neededLength ) {
00202 if ((int) neededLength > model.length() ) model.resize(neededLength);
00203 }
00204
00211 finline DataManipulator operator[](size_t index) {
00212 return DataManipulator(model, index);
00213 }
00214
00221 finline const DataManipulator operator[](size_t index) const {
00222 return DataManipulator(model, index);
00223 }
00224
00225 _Data sub( size_t index, size_t length = ~0 ) {
00226 if (length == ~0) length = model.length()-index;
00227 return _Data(model.sub(index,length));
00228 }
00229
00237 _Data clone( size_t index, size_t length ) const {
00238 DataModel new_model = model.clone(index,length);
00239 return _Data(new_model);
00240 }
00241
00247 _Data clone() const {
00248 DataModel new_model = model.clone( 0, model.length() );
00249 return _Data(new_model);
00250 }
00251
00257 finline bool isEmpty() const {
00258 return (model.length() == 0);
00259 }
00260
00267 finline bool isUnspecified() const {
00268 return model.isUnspecified();
00269 }
00270
00276 finline void release() {
00277 model.release();
00278 }
00279
00280
00281
00285 template<typename X>
00286 _Data& operator= (const DataTpl<X>& source) {
00287 this->model = source.model;
00288 return *this;
00289 }
00290
00295 template<typename X>
00296 finline bool operator==( DataTpl<X>& data) {
00297 return (data.model.buffer() == model.buffer() &&
00298 data.model.length() == model.length() );
00299 }
00300
00301 finline _Data& operator&=(_Data& data) {
00302 return *this;
00303 }
00304
00305 finline _Data& operator|=(_Data& data) {
00306 return *this;
00307 }
00308
00309 finline _Data& operator^=(_Data& data) {
00310 return *this;
00311 }
00312
00313
00314
00315 finline _Data operator&(_Data& data) {
00316 return (this->clone() &= data);
00317 }
00318
00319 finline _Data operator|(_Data& data) {
00320 return (this->clone() |= data);
00321 }
00322
00323 finline _Data operator^(_Data& data) {
00324 return (this->clone() ^= data);
00325 }
00326 };
00327
00328
00329 template<typename T, typename DataModel>
00330 const Data DataTpl<T, DataModel>::UNSPECIFIED;
00331
00337 template<typename _T>
00338 class DefaultDataModel {
00339 public:
00340 typedef _T T;
00341 typedef DefaultDataModel<T> _Model;
00342
00343 private:
00344
00345 int32_t bufferLen;
00346 T* bufferPtr;
00347
00348 static finline int calcLength(int length) {
00349 if (length<0) return 0;
00350 return ((length/8)/sizeof(T)+1);
00351 }
00352 public:
00353 finline DefaultDataModel() {
00354 bufferPtr = NULL;
00355 bufferLen = -1;
00356 }
00357
00358 finline DefaultDataModel( void* buffer, size_t length ) {
00359 bufferPtr = (T*)buffer;
00360 bufferLen = length;
00361 }
00362
00363 finline DefaultDataModel( const _Model& source ) {
00364 this->bufferPtr = source.bufferPtr;
00365 this->bufferLen = source.bufferLen;
00366 }
00367
00368 finline _Model& operator=( const _Model& source ) {
00369 this->bufferPtr = source.bufferPtr;
00370 this->bufferLen = source.bufferLen;
00371 return *this;
00372 }
00373
00374 finline T*& buffer() {
00375 return bufferPtr;
00376 }
00377
00378 finline T* buffer() const {
00379 return bufferPtr;
00380 }
00381
00382 finline int32_t& length() {
00383 return bufferLen;
00384 }
00385
00386 finline int32_t length() const {
00387 return (bufferLen == -1) ? 0 : bufferLen;
00388 }
00389
00390 finline bool isUnspecified() const {
00391 return bufferLen < 0;
00392 }
00393
00394 finline void resize( size_t new_length ) {
00395 size_t old_length = calcLength(bufferLen);
00396 size_t res_length = calcLength(new_length);
00397 if (old_length != res_length) {
00398
00399 if(res_length <= 0){
00400 if (bufferPtr != NULL) delete [] bufferPtr;
00401 bufferPtr = NULL;
00402 bufferLen = 0;
00403 }else{
00404 T* new_buffer = new T[res_length];
00405 if (new_buffer != NULL) memset(new_buffer, 0, res_length*sizeof(T));
00406 if (bufferPtr != NULL) {
00407 size_t clength = res_length < old_length ? res_length : old_length;
00408 memcpy( new_buffer, bufferPtr, clength*sizeof(T) );
00409 delete [] bufferPtr;
00410 }
00411 bufferPtr = new_buffer;
00412 bufferLen = new_length;
00413 }
00414 }
00415 }
00416
00417 finline void release() {
00418 if (bufferPtr!=NULL && bufferLen>=0) delete [] bufferPtr;
00419 bufferPtr = NULL;
00420 bufferLen = -1;
00421 }
00422
00423 finline _Model sub( size_t index, size_t length ) {
00424 return _Model( bufferPtr + index/sizeof(T), length );
00425 }
00426
00427 finline _Model clone( size_t index, size_t length ) const {
00428 _Model new_model;
00429 new_model.resize( length );
00430 bitcpy( this->buffer(), index, new_model.buffer(), 0, length );
00431 return new_model;
00432 }
00433 };
00434
00435
00436 sznBeginDefault( Data, X ){
00437 for (size_t i = 0; i< getLength() / word_width; i++) X && getBuffer()[i];
00438 }sznEnd();
00439
00440
00441 template<typename T, typename DataModel>
00442 std::ostream& operator<<(std::ostream& stream, const DataTpl<T, DataModel>& data) {
00443 stream << "[" << bitstr(data.getBuffer(), data.getLength(), 4)
00444 << "|'";
00445 const char* buffer = (const char*) data.getBuffer();
00446 for (size_t i = 0; i < data.getLength() / 8; i++) {
00447 char c = buffer[i] < 32 ? '.' : buffer[i];
00448 stream << c;
00449 }
00450 stream << "']";
00451 return stream;
00452 }
00453 #endif