Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00023 
00024 #ifndef ICL_COMM_BYTE_ORDER_CONVERISON_H_INCLUDED
00025 #define ICL_COMM_BYTE_ORDER_CONVERISON_H_INCLUDED
00026 
00027 #include <icl_core/BaseTypes.h>
00028 #include <icl_core/Vector.h>
00029 
00030 #include "icl_comm/ImportExport.h"
00031 
00032 #include <boost/detail/endian.hpp>
00033 #include <iostream>
00034 #include <iomanip>
00035 #include <assert.h>
00036 
00037 
00038 #include <boost/type_traits/is_arithmetic.hpp>
00039 
00040 namespace icl_comm {
00041 
00043 template <typename T>
00044 size_t toLittleEndian(const T& data, std::vector<uint8_t>& array, size_t& write_pos)
00045 {
00046   
00047   if (write_pos + sizeof(T) > array.size())
00048   {
00049     
00050     
00051     array.resize(write_pos + sizeof(T) );
00052   }
00053 
00054   
00055   for (size_t i= 0; i< sizeof(T);++i)
00056   {
00057     
00058     array[write_pos+i] = static_cast<uint8_t>((data>>(i*8)) & 0xFF);
00059   }
00060 
00061   return write_pos + sizeof(T);
00062 }
00063 
00065 template <>
00066 ICL_COMM_IMPORT_EXPORT
00067 size_t toLittleEndian<float>(const float& data, std::vector<uint8_t>& array, size_t& write_pos);
00068 
00070 template <>
00071 ICL_COMM_IMPORT_EXPORT
00072 size_t toLittleEndian<double>(const double& data, std::vector<uint8_t>& array, size_t& write_pos);
00073 
00074 
00076 template <typename T>
00077 size_t fromLittleEndian(T& data, std::vector<uint8_t>& array, size_t& read_pos)
00078 {
00079   
00080   
00081 
00082   
00083   data = 0;
00084 
00085   
00086   if (read_pos + sizeof(T) > array.size())
00087   {
00088     
00089     return read_pos;
00090   }
00091 
00092 
00093   
00094   for (size_t i= 0; i< sizeof(T);++i)
00095   {
00096     
00097     data |= (array[read_pos+i]& 0xFF) <<(i*8);
00098     
00099   }
00100 
00101   
00102   return read_pos + sizeof(T);
00103 }
00104 
00106 template <>
00107 ICL_COMM_IMPORT_EXPORT
00108 size_t fromLittleEndian<float>(float& data, std::vector<uint8_t>& array, size_t& read_pos);
00109 
00111 template <>
00112 ICL_COMM_IMPORT_EXPORT
00113 size_t fromLittleEndian<double>(double& data, std::vector<uint8_t>& array, size_t& read_pos);
00114 
00130 class ArrayBuilder
00131 {
00132 public:
00133   ArrayBuilder(size_t array_size = 1) :
00134     write_pos(0),
00135     read_pos(0),
00136     array(array_size, 0)
00137   { }
00138 
00140   size_t write_pos;
00141 
00143   size_t read_pos;
00144 
00146   std::vector<uint8_t>  array;
00147 
00148 
00152   void reset(size_t array_size = 1);
00153 
00155   template <typename T>
00156   void appendWithoutConversion(const T& data)
00157   {
00158     
00159     if (write_pos + sizeof(T) > array.size())
00160     {
00161       array.resize(write_pos + sizeof(T) );
00162     }
00163 
00164     
00165     *(reinterpret_cast<T*>(&array[write_pos])) = data;
00166     write_pos += sizeof(T);
00167   }
00168 
00170   template <typename T>
00171   void appendWithoutConversion(const std::vector<T>& data)
00172   {
00173     
00174     for (typename std::vector<T>::const_iterator it = data.begin() ; it != data.end(); ++it)
00175     {
00176       appendWithoutConversion(*it);
00177     }
00178   }
00179 
00181   template <typename T>
00182   ArrayBuilder& operator << (const T& data);
00183 
00185   template <typename T>
00186   ArrayBuilder& operator << (const std::vector<T>& data);
00187 
00188 
00190   template <typename T>
00191   ArrayBuilder& operator >> (T& data);
00192 
00194   template <typename T>
00195   ArrayBuilder& operator >> (std::vector<T>& data);
00196 
00199   template <typename T>
00200   T readBack();
00201 };
00202 
00203 
00205 template <typename T>
00206 ArrayBuilder& ArrayBuilder::operator << (const T& data)
00207 {
00208   
00209   write_pos = toLittleEndian<T>(data, array, write_pos);
00210 
00211   
00212   
00213 
00214   return *this;
00215 }
00216 
00217 
00219 template <typename T>
00220 ArrayBuilder& ArrayBuilder::operator << (const std::vector<T>& data)
00221 {
00222   
00223   for (typename std::vector<T>::const_iterator it = data.begin() ; it != data.end(); ++it)
00224   {
00225     *this << *it;
00226   }
00227 
00228   
00229   
00230 
00231   return *this;
00232 }
00233 
00234 
00236 template <typename T>
00237 ArrayBuilder& ArrayBuilder::operator >> (T& data)
00238 {
00239   read_pos = fromLittleEndian<T>(data, array, read_pos);
00240   return *this;
00241 }
00242 
00244 template <typename T>
00245 ArrayBuilder& ArrayBuilder::operator >> (std::vector<T>& data)
00246 {
00247   
00248   
00249   for (typename std::vector<T>::iterator it = data.begin() ; it != data.end(); ++it)
00250   {
00251     *this >> *it;
00252   }
00253 
00254  return *this;
00255 }
00256 
00257 
00258 template <typename T>
00259 T ArrayBuilder::readBack()
00260 {
00261   T data;
00262   size_t read_back_pos = write_pos-sizeof(T);
00263   fromLittleEndian<T>(data, array, read_back_pos);
00264   return data;
00265 }
00266 
00267 
00269 std::ostream& operator << (std::ostream& o, const ArrayBuilder& ab);
00270 
00271 }
00272 
00273 #endif