/src/poco/Foundation/include/Poco/ByteOrder.h
Line | Count | Source |
1 | | // |
2 | | // ByteOrder.h |
3 | | // |
4 | | // Library: Foundation |
5 | | // Package: Core |
6 | | // Module: ByteOrder |
7 | | // |
8 | | // Copyright (c) 2004-2014, Applied Informatics Software Engineering GmbH. |
9 | | // and Contributors. |
10 | | // |
11 | | // SPDX-License-Identifier: BSL-1.0 |
12 | | // |
13 | | |
14 | | |
15 | | #ifndef Foundation_ByteOrder_INCLUDED |
16 | | #define Foundation_ByteOrder_INCLUDED |
17 | | |
18 | | |
19 | | #include "Poco/Foundation.h" |
20 | | #include "Poco/Types.h" |
21 | | #if defined(_MSC_VER) |
22 | | #include <stdlib.h> // builtins |
23 | | #endif |
24 | | |
25 | | |
26 | | namespace Poco { |
27 | | |
28 | | |
29 | | class Foundation_API ByteOrder |
30 | | /// This class contains a number of static methods |
31 | | /// to convert between big-endian and little-endian |
32 | | /// integers of various sizes. |
33 | | { |
34 | | public: |
35 | | static Int8 flipBytes(Int8 value); |
36 | | static UInt8 flipBytes(UInt8 value); |
37 | | static Int16 flipBytes(Int16 value); |
38 | | static UInt16 flipBytes(UInt16 value); |
39 | | static Int32 flipBytes(Int32 value); |
40 | | static UInt32 flipBytes(UInt32 value); |
41 | | static float flipBytes(float value); |
42 | | static double flipBytes(double value); |
43 | | #if defined(POCO_HAVE_INT64) |
44 | | static Int64 flipBytes(Int64 value); |
45 | | static UInt64 flipBytes(UInt64 value); |
46 | | #endif |
47 | | |
48 | | static Int8 toBigEndian(Int8 value); |
49 | | static UInt8 toBigEndian(UInt8 value); |
50 | | static Int16 toBigEndian(Int16 value); |
51 | | static UInt16 toBigEndian (UInt16 value); |
52 | | static Int32 toBigEndian(Int32 value); |
53 | | static UInt32 toBigEndian (UInt32 value); |
54 | | #if defined(POCO_HAVE_INT64) |
55 | | static Int64 toBigEndian(Int64 value); |
56 | | static UInt64 toBigEndian (UInt64 value); |
57 | | #endif |
58 | | |
59 | | static Int8 fromBigEndian(Int8 value); |
60 | | static UInt8 fromBigEndian(UInt8 value); |
61 | | static Int16 fromBigEndian(Int16 value); |
62 | | static UInt16 fromBigEndian (UInt16 value); |
63 | | static Int32 fromBigEndian(Int32 value); |
64 | | static UInt32 fromBigEndian (UInt32 value); |
65 | | #if defined(POCO_HAVE_INT64) |
66 | | static Int64 fromBigEndian(Int64 value); |
67 | | static UInt64 fromBigEndian (UInt64 value); |
68 | | #endif |
69 | | |
70 | | static Int8 toLittleEndian(Int8 value); |
71 | | static UInt8 toLittleEndian(UInt8 value); |
72 | | static Int16 toLittleEndian(Int16 value); |
73 | | static UInt16 toLittleEndian (UInt16 value); |
74 | | static Int32 toLittleEndian(Int32 value); |
75 | | static UInt32 toLittleEndian (UInt32 value); |
76 | | #if defined(POCO_HAVE_INT64) |
77 | | static Int64 toLittleEndian(Int64 value); |
78 | | static UInt64 toLittleEndian (UInt64 value); |
79 | | #endif |
80 | | |
81 | | static Int8 fromLittleEndian(Int8 value); |
82 | | static UInt8 fromLittleEndian(UInt8 value); |
83 | | static Int16 fromLittleEndian(Int16 value); |
84 | | static UInt16 fromLittleEndian (UInt16 value); |
85 | | static Int32 fromLittleEndian(Int32 value); |
86 | | static UInt32 fromLittleEndian (UInt32 value); |
87 | | #if defined(POCO_HAVE_INT64) |
88 | | static Int64 fromLittleEndian(Int64 value); |
89 | | static UInt64 fromLittleEndian (UInt64 value); |
90 | | #endif |
91 | | |
92 | | static Int8 toNetwork(Int8 value); |
93 | | static UInt8 toNetwork(UInt8 value); |
94 | | static Int16 toNetwork(Int16 value); |
95 | | static UInt16 toNetwork (UInt16 value); |
96 | | static Int32 toNetwork(Int32 value); |
97 | | static UInt32 toNetwork (UInt32 value); |
98 | | #if defined(POCO_HAVE_INT64) |
99 | | static Int64 toNetwork(Int64 value); |
100 | | static UInt64 toNetwork (UInt64 value); |
101 | | #endif |
102 | | |
103 | | static Int8 fromNetwork(Int8 value); |
104 | | static UInt8 fromNetwork(UInt8 value); |
105 | | static Int16 fromNetwork(Int16 value); |
106 | | static UInt16 fromNetwork (UInt16 value); |
107 | | static Int32 fromNetwork(Int32 value); |
108 | | static UInt32 fromNetwork (UInt32 value); |
109 | | #if defined(POCO_HAVE_INT64) |
110 | | static Int64 fromNetwork(Int64 value); |
111 | | static UInt64 fromNetwork (UInt64 value); |
112 | | #endif |
113 | | |
114 | | private: |
115 | | template<typename T> |
116 | | static T flip(T value) |
117 | 0 | { |
118 | 0 | T flip = value; |
119 | 0 | std::size_t halfSize = sizeof(T) / 2; |
120 | 0 | char* flipP = reinterpret_cast<char*>(&flip); |
121 | 0 |
|
122 | 0 | for (std::size_t i = 0; i < halfSize; i++) |
123 | 0 | { |
124 | 0 | std::swap(flipP[i], flipP[sizeof(T) - i - 1]); |
125 | 0 | } |
126 | 0 | return flip; |
127 | 0 | } Unexecuted instantiation: float Poco::ByteOrder::flip<float>(float) Unexecuted instantiation: double Poco::ByteOrder::flip<double>(double) |
128 | | }; |
129 | | |
130 | | |
131 | | #if !defined(POCO_NO_BYTESWAP_BUILTINS) |
132 | | #if defined(_MSC_VER) |
133 | | #if (POCO_MSVC_VERSION > 71) |
134 | | #define POCO_HAVE_MSC_BYTESWAP 1 |
135 | | #endif |
136 | | #elif defined(__clang__) |
137 | | #if __has_builtin(__builtin_bswap32) |
138 | | #define POCO_HAVE_GCC_BYTESWAP 1 |
139 | | #endif |
140 | | #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) |
141 | | #define POCO_HAVE_GCC_BYTESWAP 1 |
142 | | #endif |
143 | | #endif |
144 | | |
145 | | |
146 | | // |
147 | | // inlines |
148 | | // |
149 | | inline UInt8 ByteOrder::flipBytes(UInt8 value) |
150 | 0 | { |
151 | 0 | return value; |
152 | 0 | } |
153 | | |
154 | | |
155 | | inline Int8 ByteOrder::flipBytes(Int8 value) |
156 | 0 | { |
157 | 0 | return value; |
158 | 0 | } |
159 | | |
160 | | |
161 | | inline UInt16 ByteOrder::flipBytes(UInt16 value) |
162 | 0 | { |
163 | | #if defined(POCO_HAVE_MSC_BYTESWAP) |
164 | | return _byteswap_ushort(value); |
165 | | #else |
166 | 0 | return ((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00); |
167 | 0 | #endif |
168 | 0 | } |
169 | | |
170 | | |
171 | | inline Int16 ByteOrder::flipBytes(Int16 value) |
172 | 0 | { |
173 | 0 | return Int16(flipBytes(UInt16(value))); |
174 | 0 | } |
175 | | |
176 | | |
177 | | inline UInt32 ByteOrder::flipBytes(UInt32 value) |
178 | 0 | { |
179 | | #if defined(POCO_HAVE_MSC_BYTESWAP) |
180 | | return _byteswap_ulong(value); |
181 | | #elif defined(POCO_HAVE_GCC_BYTESWAP) |
182 | | return __builtin_bswap32(value); |
183 | | #else |
184 | | return ((value >> 24) & 0x000000FF) | ((value >> 8) & 0x0000FF00) |
185 | | | ((value << 8) & 0x00FF0000) | ((value << 24) & 0xFF000000); |
186 | | #endif |
187 | 0 | } |
188 | | |
189 | | |
190 | | inline Int32 ByteOrder::flipBytes(Int32 value) |
191 | 0 | { |
192 | 0 | return Int32(flipBytes(UInt32(value))); |
193 | 0 | } |
194 | | |
195 | | |
196 | | inline float ByteOrder::flipBytes(float value) |
197 | 0 | { |
198 | 0 | return flip(value); |
199 | 0 | } |
200 | | |
201 | | |
202 | | inline double ByteOrder::flipBytes(double value) |
203 | 0 | { |
204 | 0 | return flip(value); |
205 | 0 | } |
206 | | |
207 | | |
208 | | #if defined(POCO_HAVE_INT64) |
209 | | inline UInt64 ByteOrder::flipBytes(UInt64 value) |
210 | 0 | { |
211 | | #if defined(POCO_HAVE_MSC_BYTESWAP) |
212 | | return _byteswap_uint64(value); |
213 | | #elif defined(POCO_HAVE_GCC_BYTESWAP) |
214 | | return __builtin_bswap64(value); |
215 | | #else |
216 | | UInt32 hi = UInt32(value >> 32); |
217 | | UInt32 lo = UInt32(value & 0xFFFFFFFF); |
218 | | return UInt64(flipBytes(hi)) | (UInt64(flipBytes(lo)) << 32); |
219 | | #endif |
220 | 0 | } |
221 | | |
222 | | |
223 | | inline Int64 ByteOrder::flipBytes(Int64 value) |
224 | 0 | { |
225 | 0 | return Int64(flipBytes(UInt64(value))); |
226 | 0 | } |
227 | | #endif // POCO_HAVE_INT64 |
228 | | |
229 | | |
230 | | // |
231 | | // some macro trickery to automate the method implementation |
232 | | // |
233 | | #define POCO_IMPLEMENT_BYTEORDER_NOOP_(op, type) \ |
234 | | inline type ByteOrder::op(type value) \ |
235 | 0 | { \ |
236 | 0 | return value; \ |
237 | 0 | } Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(signed char) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(unsigned char) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(short) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(unsigned short) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(int) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(unsigned int) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(long) Unexecuted instantiation: Poco::ByteOrder::toLittleEndian(unsigned long) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(signed char) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(unsigned char) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(short) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(unsigned short) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(int) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(unsigned int) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(long) Unexecuted instantiation: Poco::ByteOrder::fromLittleEndian(unsigned long) |
238 | | #define POCO_IMPLEMENT_BYTEORDER_FLIP_(op, type) \ |
239 | | inline type ByteOrder::op(type value) \ |
240 | 0 | { \ |
241 | 0 | return flipBytes(value); \ |
242 | 0 | } Unexecuted instantiation: Poco::ByteOrder::toNetwork(unsigned int) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned short) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned char) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(signed char) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(unsigned char) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(short) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(unsigned short) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(int) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(unsigned int) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(long) Unexecuted instantiation: Poco::ByteOrder::toBigEndian(unsigned long) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(signed char) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(unsigned char) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(short) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(unsigned short) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(int) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(unsigned int) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(long) Unexecuted instantiation: Poco::ByteOrder::fromBigEndian(unsigned long) Unexecuted instantiation: Poco::ByteOrder::toNetwork(signed char) Unexecuted instantiation: Poco::ByteOrder::toNetwork(unsigned char) Unexecuted instantiation: Poco::ByteOrder::toNetwork(short) Unexecuted instantiation: Poco::ByteOrder::toNetwork(unsigned short) Unexecuted instantiation: Poco::ByteOrder::toNetwork(int) Unexecuted instantiation: Poco::ByteOrder::toNetwork(long) Unexecuted instantiation: Poco::ByteOrder::toNetwork(unsigned long) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(signed char) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(short) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(int) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned int) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(long) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned long) |
243 | | |
244 | | |
245 | | #if defined(POCO_HAVE_INT64) |
246 | | #define POCO_IMPLEMENT_BYTEORDER_NOOP(op) \ |
247 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int8) \ |
248 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt8) \ |
249 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int16) \ |
250 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt16) \ |
251 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int32) \ |
252 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt32) \ |
253 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int64) \ |
254 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt64) |
255 | | #define POCO_IMPLEMENT_BYTEORDER_FLIP(op) \ |
256 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int8) \ |
257 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt8) \ |
258 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int16) \ |
259 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt16) \ |
260 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int32) \ |
261 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt32) \ |
262 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int64) \ |
263 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt64) |
264 | | #else |
265 | | #define POCO_IMPLEMENT_BYTEORDER_NOOP(op) \ |
266 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int8) \ |
267 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt8) \ |
268 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int16) \ |
269 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt16) \ |
270 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int32) \ |
271 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt32) |
272 | | #define POCO_IMPLEMENT_BYTEORDER_FLIP(op) \ |
273 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int8) \ |
274 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt8) \ |
275 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int16) \ |
276 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt16) \ |
277 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int32) \ |
278 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt32) |
279 | | #endif |
280 | | |
281 | | |
282 | | #if defined(POCO_ARCH_BIG_ENDIAN) |
283 | | #define POCO_IMPLEMENT_BYTEORDER_BIG POCO_IMPLEMENT_BYTEORDER_NOOP |
284 | | #define POCO_IMPLEMENT_BYTEORDER_LIT POCO_IMPLEMENT_BYTEORDER_FLIP |
285 | | #else |
286 | | #define POCO_IMPLEMENT_BYTEORDER_BIG POCO_IMPLEMENT_BYTEORDER_FLIP |
287 | | #define POCO_IMPLEMENT_BYTEORDER_LIT POCO_IMPLEMENT_BYTEORDER_NOOP |
288 | | #endif |
289 | | |
290 | | |
291 | | POCO_IMPLEMENT_BYTEORDER_BIG(toBigEndian) |
292 | | POCO_IMPLEMENT_BYTEORDER_BIG(fromBigEndian) |
293 | | POCO_IMPLEMENT_BYTEORDER_BIG(toNetwork) |
294 | | POCO_IMPLEMENT_BYTEORDER_BIG(fromNetwork) |
295 | | POCO_IMPLEMENT_BYTEORDER_LIT(toLittleEndian) |
296 | | POCO_IMPLEMENT_BYTEORDER_LIT(fromLittleEndian) |
297 | | |
298 | | |
299 | | } // namespace Poco |
300 | | |
301 | | |
302 | | #endif // Foundation_ByteOrder_INCLUDED |