MRPT  1.9.9
reverse_bytes.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "core-precomp.h" // Precompiled headers
11 
13 #include <cstring>
14 #include <cstdlib>
15 
16 // These #defines from:
17 // https://github.com/boostorg/endian/blob/master/include/boost/endian/detail/intrinsic.hpp
18 #ifndef __has_builtin
19 #define __has_builtin(x) 0 // Compatibility with non-clang compilers
20 #endif
21 #if ( \
22  defined(__clang__) && __has_builtin(__builtin_bswap32) && \
23  __has_builtin(__builtin_bswap64)) || \
24  (defined(__GNUC__) && \
25  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
26 #define HAVE_BSWAP_INTRINSICS
27 #endif
28 
29 template <typename T>
30 void reverseBytesInPlace_2b(T& v_in_out)
31 {
32  uint16_t org;
33  ::memcpy(
34  &org, &v_in_out,
35  sizeof(T)); // Was: = *reinterpret_cast<uint16_t*>(&v_in_out); but
36  // caused SIGBUS in some archs
37  const uint16_t val_rev = ((org & 0xff00) >> 8) | ((org & 0x00ff) << 8);
38  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned
39  // pointer warning with:
40  // *reinterpret_cast<const
41  // T*>(&val_rev);
42 }
43 
44 template <typename T>
45 void reverseBytesInPlace_4b(T& v_in_out)
46 {
47  uint32_t org;
48  ::memcpy(
49  &org, &v_in_out,
50  sizeof(T)); // Was: = = *reinterpret_cast<uint32_t*>(&v_in_out); but
51  // caused SIGBUS in some archs
52  const uint32_t val_rev =
53 #if defined(_MSC_VER)
54  _byteswap_ulong(org);
55 #elif defined(HAVE_BSWAP_INTRINSICS)
56  __builtin_bswap32(org);
57 #else
58  ((org & 0xff000000) >> (3 * 8)) | ((org & 0x00ff0000) >> (1 * 8)) |
59  ((org & 0x0000ff00) << (1 * 8)) | ((org & 0x000000ff) << (3 * 8));
60 #endif
61  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned
62  // pointer warning with:
63  // *reinterpret_cast<const
64  // T*>(&val_rev);
65 }
66 
67 template <typename T>
68 void reverseBytesInPlace_8b(T& v_in_out)
69 {
70  uint64_t org;
71  ::memcpy(
72  &org, &v_in_out,
73  sizeof(T)); // Was: = *reinterpret_cast<uint64_t*>(&v_in_out); but
74 // caused SIGBUS in some archs
75 #if defined(_MSC_VER)
76  uint64_t val_rev = _byteswap_uint64(org);
77 #elif defined(HAVE_BSWAP_INTRINSICS)
78  uint64_t val_rev = __builtin_bswap64(org);
79 #else
80  uint64_t val_rev = 0;
81  int i, j;
82  for (i = 7, j = 7; i >= 4; i--, j -= 2)
83  val_rev |= ((org & (UINT64_C(0xff) << (i * 8))) >> (j * 8));
84  for (i = 3, j = 1; i >= 0; i--, j += 2)
85  val_rev |= ((org & (UINT64_C(0xff) << (i * 8))) << (j * 8));
86 #endif
87  ::memcpy(&v_in_out, &val_rev, sizeof(T)); // This avoid deref. puned
88  // pointer warning with:
89  // *reinterpret_cast<const
90  // T*>(&val_rev);
91 }
92 
94 {
95  // Nothing to do.
96 }
97 
99 {
100  // Nothing to do.
101 }
103 {
104  // Nothing to do.
105 }
106 
108 {
109  reverseBytesInPlace_2b(v_in_out);
110 }
111 
113 {
114  reverseBytesInPlace_2b(v_in_out);
115 }
116 
118 {
119  reverseBytesInPlace_4b(v_in_out);
120 }
121 
123 {
124  reverseBytesInPlace_4b(v_in_out);
125 }
126 
128 {
129  reverseBytesInPlace_8b(v_in_out);
130 }
131 
133 {
134  reverseBytesInPlace_8b(v_in_out);
135 }
136 
137 void mrpt::reverseBytesInPlace(float& v_in_out)
138 {
139  reverseBytesInPlace_4b(v_in_out);
140 }
141 
142 void mrpt::reverseBytesInPlace(double& v_in_out)
143 {
144  reverseBytesInPlace_8b(v_in_out);
145 }
146 
147 #ifdef HAVE_LONG_DOUBLE
148 void mrpt::reverseBytesInPlace(long double& v_in_out)
149 {
150  uint64_t dat[2];
151  ::memcpy(
152  &dat[0], &v_in_out, sizeof(long double)); // This avoid deref. puned
153  // pointer warning with:
154  // *reinterpret_cast<const
155  // T*>(&val_rev);
156  std::swap(dat[0], dat[1]);
157  reverseBytesInPlace(dat[0]);
158  reverseBytesInPlace(dat[1]);
159  ::memcpy(&v_in_out, &dat[0], sizeof(long double));
160 }
161 #endif
unsigned __int16 uint16_t
Definition: rptypes.h:44
void reverseBytesInPlace_4b(T &v_in_out)
signed char int8_t
Definition: rptypes.h:40
void reverseBytesInPlace_8b(T &v_in_out)
void reverseBytesInPlace(bool &v_in_out)
Reverse the order of the bytes of a given type (useful for transforming btw little/big endian) ...
unsigned char uint8_t
Definition: rptypes.h:41
__int16 int16_t
Definition: rptypes.h:43
__int64 int64_t
Definition: rptypes.h:49
void reverseBytesInPlace_2b(T &v_in_out)
__int32 int32_t
Definition: rptypes.h:46
unsigned __int64 uint64_t
Definition: rptypes.h:50
unsigned __int32 uint32_t
Definition: rptypes.h:47
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:356



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020