VisionaryEndian.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2023 SICK AG, Waldkirch
3 //
4 // SPDX-License-Identifier: Unlicense
5 
6 #pragma once
7 
8 #include <algorithm> // min, max
9 #include <cstdint>
10 #include <cstring> // for memcpy
11 #include <stdexcept>
12 #include <vector>
13 
14 #if __cplusplus >= 202002L
15 # include <bit> // for endian
16 #endif
17 
18 namespace visionary {
19 
20 #if __cplusplus >= 202002L
21 using endian = std::endian;
22 #else
23 # if defined(_WIN32)
24 enum class endian
25 {
26  little = 1,
27  big = 2,
28  native = 1
29 };
30 # else
31 // gcc or clang
32 enum class endian
33 {
34  little = __ORDER_LITTLE_ENDIAN__,
35  big = __ORDER_BIG_ENDIAN__,
36  native = __BYTE_ORDER__
37 };
38 # endif
39 #endif
40 
41 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42 
43 template <class T>
44 void writeUnaligned(void* ptr, std::size_t nBytes, const T& val)
45 {
46  if (sizeof(T) > nBytes)
47  {
48  throw std::out_of_range("buffer too small");
49  }
50 
51  std::memcpy(ptr, &val, sizeof(T));
52 }
53 
54 template <class T>
55 T readUnaligned(const void* ptr)
56 {
57  T r;
58  std::memcpy(&r, ptr, sizeof(T));
59  return r;
60 }
61 
62 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
63 
64 template <typename TAlias, typename T>
65 inline T byteswapAlias(const T& val);
66 
67 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
68 
69 inline std::uint8_t byteswap(std::uint8_t val)
70 {
71  return val;
72 }
73 
74 inline std::int8_t byteswap(std::int8_t val)
75 {
76  return byteswapAlias<std::uint8_t>(val);
77 }
78 
79 inline char byteswap(char val)
80 {
81  return byteswapAlias<std::uint8_t>(val);
82 }
83 
84 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
85 
86 inline std::uint16_t byteswap(std::uint16_t val)
87 {
88  return (static_cast<std::uint16_t>(val << 8) & 0xFF00u) | (static_cast<std::uint16_t>(val >> 8) & 0x00FFu);
89 }
90 
91 inline std::int16_t byteswap(std::int16_t val)
92 {
93  return byteswapAlias<std::uint16_t>(val);
94 }
95 
96 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97 
98 inline std::uint32_t byteswap(std::uint32_t val)
99 {
100  val = ((val << 8) & 0xFF00FF00u) | ((val >> 8) & 0x00FF00FFu);
101  return ((val << 16) & 0xFFFF0000u) | ((val >> 16) & 0x0000FFFFu);
102 }
103 
104 inline std::int32_t byteswap(std::int32_t val)
105 {
106  return byteswapAlias<std::uint32_t>(val);
107 }
108 
109 inline float byteswap(float val)
110 {
111  union
112  {
113  float f32;
114  std::uint32_t u32;
115  } v;
116  v.f32 = val;
117  v.u32 = byteswap(v.u32);
118 
119  return v.f32;
120 }
121 
122 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
123 
124 inline std::uint64_t byteswap(std::uint64_t val)
125 {
126  val = ((val << 8) & 0xFF00FF00FF00FF00ull) | ((val >> 8) & 0x00FF00FF00FF00FFull);
127  val = ((val << 16) & 0xFFFF0000FFFF0000ull) | ((val >> 16) & 0x0000FFFF0000FFFFull);
128  return ((val << 32) & 0xFFFFFFFF00000000ull) | ((val >> 32) & 0x00000000FFFFFFFFull);
129 }
130 
131 inline std::int64_t byteswap(std::int64_t val)
132 {
133  return byteswapAlias<std::uint64_t>(val);
134 }
135 
136 inline double byteswap(double val)
137 {
138  union
139  {
140  double f64;
141  std::uint64_t u64;
142  } v;
143  v.f64 = val;
144  v.u64 = byteswap(v.u64);
145 
146  return v.f64;
147 }
148 
149 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
150 
151 template <typename TAlias, typename T>
152 inline T byteswapAlias(const T& val)
153 {
154  return static_cast<T>(byteswap(static_cast<TAlias>(val)));
155 }
156 
157 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158 
159 // Endianness convert: byte swap if `frompar` and `topar` endian values are different;
160 // just return identity if they are the same
161 template <endian frompar, endian topar>
162 struct Endian
163 {
164  static constexpr auto from = frompar;
165  static constexpr auto to = topar;
166 
167  using ByteVector = std::vector<std::uint8_t>;
168 
169  template <typename T>
170  static T convert(const T& val)
171  {
172  return byteswap(val);
173  }
174 
175  template <typename T>
176  static void convertTo(void* pDest, size_t nSize, const T& val)
177  {
178  writeUnaligned<T>(pDest, nSize, convert(val));
179  }
180 
181  template <typename T>
182  static T convertFrom(const void* pSrc)
183  {
184  return convert<T>(readUnaligned<T>(pSrc));
185  }
186 
187  template <typename T>
188  static ByteVector convertToVector(const T& val, size_t capacity = 0u)
189  {
190  ByteVector vec;
191  vec.reserve(std::max(sizeof(T), capacity));
192  vec.resize(sizeof(T));
193  convertTo<T>(vec.data(), vec.size(), val);
194 
195  return vec;
196  }
197 
198  template <typename T, class TInputIt>
199  static bool convertFrom(T& rval, TInputIt& first, const TInputIt& last)
200  {
201  uint8_t buf[sizeof(T)];
202  size_t idx = 0u;
203  while (idx < sizeof(T))
204  {
205  if (first == last)
206  {
207  // iterator hit the end prematurely
208  return false;
209  }
210  buf[idx++] = *first;
211  ++first;
212  }
213 
214  rval = convertFrom<T>(buf);
215 
216  return true;
217  }
218 };
219 
220 template <endian frompar>
221 struct Endian<frompar, frompar>
222 {
223  static constexpr auto from = frompar;
224  static constexpr auto to = frompar;
225 
226  using ByteVector = std::vector<std::uint8_t>;
227 
228  template <typename T>
229  static T convert(const T& val)
230  {
231  return val;
232  }
233 
234  template <typename T>
235  static void convertTo(void* pDest, size_t nSize, const T& val)
236  {
237  writeUnaligned(pDest, nSize, val);
238  }
239 
240  template <typename T>
241  static T convertFrom(const void* pSrc)
242  {
243  return readUnaligned<T>(pSrc);
244  }
245 
246  template <typename T>
247  static ByteVector convertToVector(const T& val, size_t capacity = 0u)
248  {
249  ByteVector vec;
250  vec.reserve(std::max(sizeof(T), capacity));
251  vec.resize(sizeof(T));
252  convertTo<T>(vec.data(), vec.size(), val);
253 
254  return vec;
255  }
256 
257  template <typename T, class TInputIt>
258  static T convertFrom(T& rval, TInputIt& first, const TInputIt& last)
259  {
260  uint8_t buf[sizeof(T)] = {0};
261 
262  size_t idx = 0u;
263 
264  while ((idx < sizeof(T)) && (first < last))
265  {
266  if (first == last)
267  {
268  // iterator hit the end prematurely
269  return false;
270  }
271  buf[idx++] = *first;
272  ++first;
273  }
274 
275  rval = convertFrom<T>(buf);
276 
277  return true;
278  }
279 };
280 
281 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
282 
283 template <typename T>
284 inline T nativeToLittleEndian(const T& val)
285 {
287 }
288 
289 template <typename T>
291 {
293 }
294 
295 template <typename T>
296 inline T nativeToBigEndian(const T& val)
297 {
299 }
300 
301 template <typename T>
302 inline T bigEndianToNative(T val)
303 {
305 }
306 
307 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
308 
309 template <typename T>
310 inline void writeUnalignBigEndian(void* ptr, std::size_t nBytes, const T& value)
311 {
313 }
314 
315 template <typename T>
316 inline void writeUnalignLittleEndian(void* ptr, std::size_t nBytes, const T& value)
317 {
319 }
320 
321 template <typename T>
322 inline T readUnalignBigEndian(const void* ptr)
323 {
324  const std::uint8_t* ptr8 = static_cast<const std::uint8_t*>(ptr);
325 
327 }
328 
329 template <typename T>
330 inline T readUnalignLittleEndian(const void* ptr)
331 {
332  const std::uint8_t* ptr8 = static_cast<const std::uint8_t*>(ptr);
334 }
335 
336 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
337 
338 } // namespace visionary
visionary::Endian::ByteVector
std::vector< std::uint8_t > ByteVector
Definition: VisionaryEndian.h:167
visionary::bigEndianToNative
T bigEndianToNative(T val)
Definition: VisionaryEndian.h:302
visionary::littleEndianToNative
T littleEndianToNative(T val)
Definition: VisionaryEndian.h:290
visionary::nativeToLittleEndian
T nativeToLittleEndian(const T &val)
Definition: VisionaryEndian.h:284
T
T
Definition: mem_fn_cc.hpp:25
visionary::Endian::convertFrom
static T convertFrom(const void *pSrc)
Definition: VisionaryEndian.h:182
visionary
Definition: MD5.cpp:44
visionary::Endian< frompar, frompar >::convertToVector
static ByteVector convertToVector(const T &val, size_t capacity=0u)
Definition: VisionaryEndian.h:247
visionary::Endian::convert
static T convert(const T &val)
Definition: VisionaryEndian.h:170
visionary::endian
endian
Definition: VisionaryEndian.h:32
visionary::readUnaligned
T readUnaligned(const void *ptr)
Definition: VisionaryEndian.h:55
visionary::Endian< frompar, frompar >::convertFrom
static T convertFrom(T &rval, TInputIt &first, const TInputIt &last)
Definition: VisionaryEndian.h:258
visionary::readUnalignLittleEndian
T readUnalignLittleEndian(const void *ptr)
Definition: VisionaryEndian.h:330
visionary::nativeToBigEndian
T nativeToBigEndian(const T &val)
Definition: VisionaryEndian.h:296
visionary::Endian< frompar, frompar >::ByteVector
std::vector< std::uint8_t > ByteVector
Definition: VisionaryEndian.h:226
visionary::endian::big
@ big
visionary::Endian::convertToVector
static ByteVector convertToVector(const T &val, size_t capacity=0u)
Definition: VisionaryEndian.h:188
visionary::Endian< frompar, frompar >::convert
static T convert(const T &val)
Definition: VisionaryEndian.h:229
visionary::Endian
Definition: VisionaryEndian.h:162
visionary::endian::little
@ little
visionary::Endian< frompar, frompar >::convertFrom
static T convertFrom(const void *pSrc)
Definition: VisionaryEndian.h:241
visionary::writeUnaligned
void writeUnaligned(void *ptr, std::size_t nBytes, const T &val)
Definition: VisionaryEndian.h:44
visionary::Endian::convertFrom
static bool convertFrom(T &rval, TInputIt &first, const TInputIt &last)
Definition: VisionaryEndian.h:199
visionary::Endian< frompar, frompar >::convertTo
static void convertTo(void *pDest, size_t nSize, const T &val)
Definition: VisionaryEndian.h:235
visionary::writeUnalignLittleEndian
void writeUnalignLittleEndian(void *ptr, std::size_t nBytes, const T &value)
Definition: VisionaryEndian.h:316
visionary::byteswap
std::uint8_t byteswap(std::uint8_t val)
Definition: VisionaryEndian.h:69
visionary::byteswapAlias
T byteswapAlias(const T &val)
Definition: VisionaryEndian.h:152
visionary::Endian::from
static constexpr auto from
Definition: VisionaryEndian.h:164
visionary::Endian::convertTo
static void convertTo(void *pDest, size_t nSize, const T &val)
Definition: VisionaryEndian.h:176
visionary::writeUnalignBigEndian
void writeUnalignBigEndian(void *ptr, std::size_t nBytes, const T &value)
Definition: VisionaryEndian.h:310
visionary::endian::native
@ native
visionary::readUnalignBigEndian
T readUnalignBigEndian(const void *ptr)
Definition: VisionaryEndian.h:322
visionary::Endian::to
static constexpr auto to
Definition: VisionaryEndian.h:165


sick_visionary_ros
Author(s): SICK AG TechSupport 3D Snapshot
autogenerated on Thu Feb 8 2024 03:56:19