1  // [License]


2  // The AribaUnderlay Copyright


3  //


4  // Copyright (c) 20082009, Institute of Telematics, UniversitÃ€t Karlsruhe (TH)


5  //


6  // Institute of Telematics


7  // UniversitÃ€t Karlsruhe (TH)


8  // Zirkel 2, 76128 Karlsruhe


9  // Germany


10  //


11  // Redistribution and use in source and binary forms, with or without


12  // modification, are permitted provided that the following conditions are


13  // met:


14  //


15  // 1. Redistributions of source code must retain the above copyright


16  // notice, this list of conditions and the following disclaimer.


17  // 2. Redistributions in binary form must reproduce the above copyright


18  // notice, this list of conditions and the following disclaimer in the


19  // documentation and/or other materials provided with the distribution.


20  //


21  // THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND


22  // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE


23  // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR


24  // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR


25  // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,


26  // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,


27  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR


28  // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF


29  // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING


30  // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS


31  // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


32  //


33  // The views and conclusions contained in the software and documentation


34  // are those of the authors and should not be interpreted as representing


35  // official policies, either expressed or implied, of the Institute of


36  // Telematics.


37  // [License]


38 


39  #ifndef DATA_HPP_


40  #define DATA_HPP_


41 


42  //== library includes ==


43  #include <stdlib.h>


44  #include <iostream>


45  #include <boost/cstdint.hpp>


46 


47  // forward declaration


48  template<typename T> class DefaultDataModel;


49  template<typename T = uint8_t, typename DataModel = DefaultDataModel<uint8_t> > class DataTpl;


50  typedef DataTpl<> Data;


51  template<typename T, typename DataModel> std::ostream& operator<<(std::ostream& stream, DataTpl<T, DataModel>& data);


52 


53  //== internal includes ==


54  #include "../internal/Utilities.hpp"


55 


56  //== local includes ==


57  #include "DataUtilities.hpp"


58  #include "Serialization.hpp"


59 


60  /**


61  * This class implements a wrapper for binary data. And this time, when the


62  * word binary is used  it really means binary! Length and manipulation


63  * are specified and operate in bit precision. Most of the operations are


64  * highly effective using inline functions and compiler optimizations.


65  *


66  * Two versions of binaries are supported: static, nonresizeable binaries


67  * and dynamic, resizeable ones. Please note, this class does not manage


68  * memory, reference counting etc. you have to take care about memory


69  * management yourself! However you can use the <code>release()</code>


70  * to delete the underlaying array.


71  *


72  * @author Sebastian Mies


73  */


74  template<typename T, typename DataModel>


75  class DataTpl: public Serializeable { SERIALIZEABLE


76  protected:


77  typedef DataTpl<T,DataModel> _Data;


78  DataModel model;


79 


80  public:


81  static const size_t word_width = sizeof(T) * 8;


82 


83  class DataManipulator {


84  private:


85  DataModel bits;


86  size_t index;


87 


88  public:


89  finline DataManipulator( DataModel& _bits, size_t _index) :


90  bits(_bits), index(_index) {


91  }


92 


93  template<typename X>


94  finline operator X() const {


95  return bitget<X>(bits.buffer(), index);


96  }


97 


98  template<typename X>


99  finline DataManipulator& operator=(X value) {


100  bitset(value, bits.buffer(), index );


101  return *this;


102  }


103 


104  template<typename X>


105  finline void set(X value, size_t length = sizeof(X) * 8, if_uint(X)) {


106  bitcpy(value, 0, bits.buffer(), index, length);


107  }


108 


109  template<typename X>


110  finline void set(X value, size_t length = sizeof(X) * 8, if_int(X)) {


111  set(_unsigned(value),length);


112  }


113 


114  template<typename X>


115  finline void get(X& value, size_t length = sizeof(X) * 8, if_uint(X)) const {


116  value = bitget<X> (bits.buffer(), index, length);


117  }


118 


119  template<typename X>


120  finline void get(X& value, size_t length = sizeof(X) * 8, if_int(X)) const {


121  _unsigned(value) = bitget<X> (bits.buffer(), index, length);


122  }


123 


124  finline void get(bool& value) const {


125  value = bitget( bits.buffer(), index );


126  }


127  };


128 


129  public:


130  static const Data UNSPECIFIED;


131 


132  /**


133  * Constructs a dynamic bitdata object of variable size.


134  */


135  finline DataTpl() : model() {


136  }


137 


138  /**


139  * Contructs a copy of an existing data buffer


140  */


141  finline DataTpl(const DataTpl<T, DataModel>& copy) {


142  this>model = copy.model;


143  }


144 


145  finline DataTpl( const DataModel& _model ) : model( _model ) {


146  }


147 


148  /**


149  * Constructs a static bitdata object with the given buffer.


150  */


151  finline DataTpl(const T* buffer, size_t length) {


152  model.buffer() = buffer;


153  model.length() = length;


154  }


155 


156  /**


157  * Constructs a dynamic bitdata object with the given buffer.


158  */


159  finline DataTpl( T* buffer, size_t length ) {


160  model.buffer() = buffer;


161  model.length() = length;


162  }


163 


164  /**


165  * Constructs a dynamic bitdata object of variable size with the given


166  * initial size.


167  */


168  finline DataTpl(size_t length) : model() {


169  model.resize(length);


170  }


171 


172 


173  /**


174  * Returns the internal buffer of the data.


175  */


176  finline T* getBuffer() const {


177  return model.buffer();


178  }


179 


180  /**


181  * Returns the length of the data in bits


182  */


183  finline size_t getLength() const {


184  return model.length();


185  }


186  /**


187  * Sets the length of the data in bits


188  */


189  void setLength(size_t new_length) {


190  model.resize(new_length);


191  }


192 


193  /**


194  * Ensures that the buffer pointer has the given


195  * number of bits of memory reserved.


196  *


197  * @param neededLength The minimum data length required.


198  */


199  finline void ensureLength( size_t neededLength ) {


200  if ((int) neededLength > model.length() ) model.resize(neededLength);


201  }


202 


203  /**


204  * Returns a manipulator object for a certain bit position.


205  *


206  * @param index The index in bits quantitites.


207  * @return A data manipulation object


208  */


209  finline DataManipulator operator[](size_t index) {


210  return DataManipulator(model, index);


211  }


212 


213  /**


214  * Returns a constant manipulator object for a certain bit position.


215  *


216  * @param index The index in bits quantitites.


217  * @return A constant data manipulation object


218  */


219  finline const DataManipulator operator[](size_t index) const {


220  return DataManipulator(model, index);


221  }


222 


223  _Data sub( size_t index, size_t length = ~0 ) {


224  if (length == ~0) length = model.length()index;


225  return _Data(model.sub(index,length));


226  }


227 


228  /**


229  * Returns a copy of the specified bit range.


230  *


231  * @param index The first bit to copy


232  * @param length The length of the bit range


233  * @return The cloned data object


234  */


235  _Data clone( size_t index, size_t length ) const {


236  DataModel new_model = model.clone(index,length);


237  return _Data(new_model);


238  }


239 


240  /**


241  * Returns a copy of the data.


242  *


243  * @return A cloned data object


244  */


245  _Data clone() const {


246  DataModel new_model = model.clone( 0, model.length() );


247  return _Data(new_model);


248  }


249 


250  /**


251  * Returns true, if the data is empty (zero length)


252  *


253  * @return True, if the data is empty (zero length)


254  */


255  finline bool isEmpty() const {


256  return (model.length() == 0);


257  }


258 


259  /**


260  * Returns true, if the data buffer is unspecified.


261  * In this case no memory is associated with this data object.


262  *


263  * @return True, if the data buffer is unspecified.


264  */


265  finline bool isUnspecified() const {


266  return model.isUnspecified();


267  }


268 


269  /**


270  * This method frees the memory associated with


271  * this data object and sets this object into an unspecified


272  * state.


273  */


274  finline void release() {


275  model.release();


276  }


277 


278  // operators


279 


280  /**


281  * Assigns another buffer


282  */


283  template<typename X>


284  _Data& operator= (const DataTpl<X>& source) {


285  this>model = source.model;


286  return *this;


287  }


288 


289  /**


290  * Returns true, if the datas buffer's pointer and length


291  * are the same.


292  */


293  template<typename X>


294  finline bool operator==( DataTpl<X>& data) {


295  return (data.model.buffer() == model.buffer() &&


296  data.model.length() == model.length() );


297  }


298 


299  finline _Data& operator&=(_Data& data) {


300  return *this;


301  }


302 


303  finline _Data& operator=(_Data& data) {


304  return *this;


305  }


306 


307  finline _Data& operator^=(_Data& data) {


308  return *this;


309  }


310 


311  /* implied operators */


312 


313  finline _Data operator&(_Data& data) {


314  return (this>clone() &= data);


315  }


316 


317  finline _Data operator(_Data& data) {


318  return (this>clone() = data);


319  }


320 


321  finline _Data operator^(_Data& data) {


322  return (this>clone() ^= data);


323  }


324  };


325 


326  /* default human readable text output */


327  template<typename T, typename DataModel>


328  std::ostream& operator<<(std::ostream& stream, DataTpl<T, DataModel>& data) {


329  stream << "[" << bitstr(data.getBuffer(), data.getLength(), 4)


330  << "'";


331  char* buffer = (char*) data.getBuffer();


332  for (size_t i = 0; i < data.getLength() / 8; i++) {


333  char c = buffer[i] < 32 ? '.' : buffer[i];


334  stream << c;


335  }


336  stream << "']";


337  return stream;


338  }


339 


340  /* unspecified type */


341  template<typename T, typename DataModel>


342  const Data DataTpl<T, DataModel>::UNSPECIFIED;


343 


344  /**


345  * This class implements the default data model


346  *


347  * @author Sebastian Mies


348  */


349  template<typename _T>


350  class DefaultDataModel {


351  public:


352  typedef _T T;


353  typedef DefaultDataModel<T> _Model;


354 


355  private:


356 


357  int32_t bufferLen;


358  T* bufferPtr;


359 


360  static finline int calcLength(int length) {


361  if (length<0) return 0;


362  return ((length/8)/sizeof(T)+1);


363  }


364  public:


365  finline DefaultDataModel() {


366  bufferPtr = NULL;


367  bufferLen = 1;


368  }


369 


370  finline DefaultDataModel( void* buffer, size_t length ) {


371  bufferPtr = (T*)buffer;


372  bufferLen = length;


373  }


374 


375  finline DefaultDataModel( const _Model& source ) {


376  this>bufferPtr = source.bufferPtr;


377  this>bufferLen = source.bufferLen;


378  }


379 


380  finline _Model& operator=( const _Model& source ) {


381  this>bufferPtr = source.bufferPtr;


382  this>bufferLen = source.bufferLen;


383  return *this;


384  }


385 


386  finline T*& buffer() {


387  return bufferPtr;


388  }


389 


390  finline T* buffer() const {


391  return bufferPtr;


392  }


393 


394  finline int32_t& length() {


395  return bufferLen;


396  }


397 


398  finline int32_t length() const {


399  return bufferLen;


400  }


401 


402  finline bool isUnspecified() const {


403  return bufferLen < 0;


404  }


405 


406  finline void resize( size_t new_length ) {


407  size_t old_length = calcLength(bufferLen);


408  size_t res_length = calcLength(new_length);


409  if (old_length != res_length) {


410  T* new_buffer = new T[res_length];


411  if (bufferPtr != NULL) {


412  size_t clength = res_length < old_length ? res_length : old_length;


413  memcpy( new_buffer, bufferPtr, clength*sizeof(T) );


414  delete [] bufferPtr;


415  }


416  bufferPtr = new_buffer;


417  bufferLen = new_length;


418  }


419  }


420 


421  finline void release() {


422  delete [] bufferPtr;


423  bufferPtr = NULL;


424  bufferLen = 1;


425  }


426 


427  finline _Model sub( size_t index, size_t length ) {


428  return _Model( bufferPtr + index/sizeof(T), length );


429  }


430 


431  finline _Model clone( size_t index, size_t length ) const {


432  _Model new_model;


433  new_model.resize( length );


434  bitcpy( this>buffer(), index, new_model.buffer(), 0, length );


435  return new_model;


436  }


437  };


438 


439  /* serialization */


440  sznBeginDefault( Data, X ){


441  for (size_t i = 0; i< getLength() / word_width; i++) X && getBuffer()[i];


442  }sznEnd();


443 


444  #endif /* DATA_HPP_ */

