ByteOrderConversion.h
Go to the documentation of this file.
1 //
3 // © Copyright 2022 SCHUNK Mobile Greifsysteme GmbH, Lauffen/Neckar Germany
4 // © Copyright 2022 FZI Forschungszentrum Informatik, Karlsruhe, Germany
5 //
6 // This file is part of the Schunk SVH Library.
7 //
8 // The Schunk SVH Library is free software: you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or (at your
11 // option) any later version.
12 //
13 // The Schunk SVH Library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 // Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // the Schunk SVH Library. If not, see <https://www.gnu.org/licenses/>.
20 //
22 
23 //----------------------------------------------------------------------
31 //----------------------------------------------------------------------
32 #ifndef DRIVER_SVH_BYTE_ORDER_CONVERISON_H_INCLUDED
33 #define DRIVER_SVH_BYTE_ORDER_CONVERISON_H_INCLUDED
34 
36 
37 #include <assert.h>
38 #include <iomanip>
39 #include <iostream>
40 #include <vector>
41 
42 
43 namespace driver_svh {
44 
46 template <typename T>
47 size_t toLittleEndian(const T& data, std::vector<uint8_t>& array, size_t& write_pos)
48 {
49  // Resize the target array in case it it to small to avoid out of bounds acces
50  if (write_pos + sizeof(T) > array.size())
51  {
52  // TODO: Remove Debug
53  // std::cout << "To Little Endian has to extend the Array. Current array Size: "<<
54  // (int)array.size() << " Pos: " << (int)pos << " Size_T: "<< sizeof(T) << " New array Size: "<<
55  // (int)(pos + sizeof(T)) << std::endl;
56  array.resize(write_pos + sizeof(T));
57  }
58 
59  // Endianess Conversion
60  for (size_t i = 0; i < sizeof(T); ++i)
61  {
62  // Copy each byte into the bytearray, always convert byte order to little endian regardles of
63  // source architecture
64  array[write_pos + i] = static_cast<uint8_t>((data >> (i * 8)) & 0xFF);
65  }
66 
67  return write_pos + sizeof(T);
68 }
69 
71 template <>
72 DRIVER_SVH_IMPORT_EXPORT size_t toLittleEndian<float>(const float& data,
73  std::vector<uint8_t>& array,
74  size_t& write_pos);
75 
77 template <>
78 DRIVER_SVH_IMPORT_EXPORT size_t toLittleEndian<double>(const double& data,
79  std::vector<uint8_t>& array,
80  size_t& write_pos);
81 
82 
85 template <typename T>
86 size_t fromLittleEndian(T& data, std::vector<uint8_t>& array, size_t& read_pos)
87 {
88  // TODO: Remove once everything is tested :)
89  // std::cout << "From Little Endian Called with: "<<" Size_T: "<< sizeof(T) << " Pos: " <<
90  // (int)read_pos << "Current Array Size: "<< (int)array.size() << std::endl;
91 
92  // Reset data as we only write with or
93  data = 0;
94 
95  // Check if ArrayBuilder has enough data
96  if (read_pos + sizeof(T) > array.size())
97  {
98  // TODO: better error handling?
99  return read_pos;
100  }
101 
102 
103  // Endianess Conversion
104  for (size_t i = 0; i < sizeof(T); ++i)
105  {
106  // Copy each byte into the bytearray, always convert byte order back from little endian
107  data |= (array[read_pos + i] & 0xFF) << (i * 8);
108  // std::cout << "Converting Value: 0x" << std::setw(2) << std::setfill('0') << std::hex <<
109  // static_cast<int>((array[read_pos+i]& 0xFF) <<(i*8)) << " At the position
110  // i="<<static_cast<int>(i) << "resulting in the variable data: " << static_cast<int>(data) <<
111  // std::dec <<" Or on DEC :" << static_cast<int>(data) << std::endl;
112  }
113 
114  // Note: The Vector still contains the elements at this point maybe we would like to delete that?
115  // But its expensive
116  return read_pos + sizeof(T);
117 }
118 
120 template <>
122  std::vector<uint8_t>& array,
123  size_t& read_pos);
124 
126 template <>
128  std::vector<uint8_t>& array,
129  size_t& read_pos);
130 
147 {
148 public:
149  ArrayBuilder(size_t array_size = 1)
150  : write_pos(0)
151  , read_pos(0)
152  , array(array_size, 0)
153  {
154  }
155 
157  size_t write_pos;
158 
160  size_t read_pos;
161 
163  std::vector<uint8_t> array;
164 
165 
169  void reset(size_t array_size = 1);
170 
172  template <typename T>
173  void appendWithoutConversion(const T& data)
174  {
175  // Resize the target array in case it it to small to avoid out of bounds acces
176  if (write_pos + sizeof(T) > array.size())
177  {
178  array.resize(write_pos + sizeof(T));
179  }
180 
181  // write data to array without conversion
182  *(reinterpret_cast<T*>(&array[write_pos])) = data;
183  write_pos += sizeof(T);
184  }
185 
187  template <typename T>
188  void appendWithoutConversion(const std::vector<T>& data)
189  {
190  // Just insert every element of the Vector individually
191  for (typename std::vector<T>::const_iterator it = data.begin(); it != data.end(); ++it)
192  {
194  }
195  }
196 
198  template <typename T>
199  ArrayBuilder& operator<<(const T& data);
200 
203  template <typename T>
204  ArrayBuilder& operator<<(const std::vector<T>& data);
205 
206 
208  template <typename T>
209  ArrayBuilder& operator>>(T& data);
210 
212  template <typename T>
213  ArrayBuilder& operator>>(std::vector<T>& data);
214 
217  template <typename T>
218  T readBack();
219 };
220 
221 
223 template <typename T>
225 {
226  // Convert the type to correct encoding and poit it into the Array
227  write_pos = toLittleEndian<T>(data, array, write_pos);
228 
229  // TODO: Remove debug output
230  // std::cout << "Arraybuilder got a generic type of length: "<< sizeof(data) << " and With data
231  // Packet: "<< (int)data << std::endl;
232 
233  return *this;
234 }
235 
236 
239 template <typename T>
240 ArrayBuilder& ArrayBuilder::operator<<(const std::vector<T>& data)
241 {
242  // Just insert every element of the Vector individually
243  for (typename std::vector<T>::const_iterator it = data.begin(); it != data.end(); ++it)
244  {
245  *this << *it;
246  }
247 
248  // TODO: Remove Debug output
249  // std::cout << "ArrayBuilder got a vector of length: "<< data.size() << std::endl;
250 
251  return *this;
252 }
253 
254 
256 template <typename T>
258 {
259  read_pos = fromLittleEndian<T>(data, array, read_pos);
260  return *this;
261 }
262 
265 template <typename T>
267 {
268  // Todo: For u_int8 Vectors this could also just be handled by an insert -> faster :)
269  // Just insert every element of the Vector individually --> Do it in reverse order as we read from
270  // the end of the list :)
271  for (typename std::vector<T>::iterator it = data.begin(); it != data.end(); ++it)
272  {
273  *this >> *it;
274  }
275 
276  return *this;
277 }
278 
279 
280 template <typename T>
282 {
283  T data;
284  size_t read_back_pos = write_pos - sizeof(T);
285  fromLittleEndian<T>(data, array, read_back_pos);
286  return data;
287 }
288 
289 
291 std::ostream& operator<<(std::ostream& o, const ArrayBuilder& ab);
292 
293 } // namespace driver_svh
294 
295 #endif
DRIVER_SVH_IMPORT_EXPORT size_t fromLittleEndian< double >(double &data, std::vector< uint8_t > &array, size_t &read_pos)
Template specialization for float as these have to be handled seperately.
DRIVER_SVH_IMPORT_EXPORT size_t toLittleEndian< float >(const float &data, std::vector< uint8_t > &array, size_t &write_pos)
Template specialization for float as these have to be handled seperately.
#define DRIVER_SVH_IMPORT_EXPORT
Definition: ImportExport.h:50
ArrayBuilder(size_t array_size=1)
size_t write_pos
current write position in array
std::vector< uint8_t > array
array of template type TArray
DRIVER_SVH_IMPORT_EXPORT size_t toLittleEndian< double >(const double &data, std::vector< uint8_t > &array, size_t &write_pos)
Template specialization for float as these have to be handled seperately.
DRIVER_SVH_IMPORT_EXPORT size_t fromLittleEndian< float >(float &data, std::vector< uint8_t > &array, size_t &read_pos)
Template specialization for float as these have to be handled seperately.
size_t fromLittleEndian(T &data, std::vector< uint8_t > &array, size_t &read_pos)
void appendWithoutConversion(const T &data)
add data without any byte conversion
size_t read_pos
current read position in array
ArrayBuilder & operator>>(T &data)
Read a generic data type from the array builder, Endianess is converted to system architecture...
void reset(size_t array_size=1)
Resets the Arraybuilder to initial state, all values will be deleted.
ArrayBuilder & operator<<(const T &data)
Write any type into ArrayBuilder, convert to LittleEndian in process.
size_t toLittleEndian(const T &data, std::vector< uint8_t > &array, size_t &write_pos)
template function for adding data to an array while converting everything into correct endianess ...
void appendWithoutConversion(const std::vector< T > &data)
add data in vectors without any byte conversion


schunk_svh_library
Author(s): Georg Heppner, Lars Pfotzer, Felix Exner, Johannes Mangler, Stefan Scherzinger, Pascal Becker
autogenerated on Fri Apr 14 2023 02:26:23