/src/poco/Foundation/include/Poco/ByteOrder.h
Line | Count | Source (jump to first uncovered line) |
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 Int16 flipBytes(Int16 value); |
36 | | static UInt16 flipBytes(UInt16 value); |
37 | | static Int32 flipBytes(Int32 value); |
38 | | static UInt32 flipBytes(UInt32 value); |
39 | | static float flipBytes(float value); |
40 | | static double flipBytes(double value); |
41 | | #if defined(POCO_HAVE_INT64) |
42 | | static Int64 flipBytes(Int64 value); |
43 | | static UInt64 flipBytes(UInt64 value); |
44 | | #endif |
45 | | |
46 | | static Int16 toBigEndian(Int16 value); |
47 | | static UInt16 toBigEndian (UInt16 value); |
48 | | static Int32 toBigEndian(Int32 value); |
49 | | static UInt32 toBigEndian (UInt32 value); |
50 | | #if defined(POCO_HAVE_INT64) |
51 | | static Int64 toBigEndian(Int64 value); |
52 | | static UInt64 toBigEndian (UInt64 value); |
53 | | #endif |
54 | | |
55 | | static Int16 fromBigEndian(Int16 value); |
56 | | static UInt16 fromBigEndian (UInt16 value); |
57 | | static Int32 fromBigEndian(Int32 value); |
58 | | static UInt32 fromBigEndian (UInt32 value); |
59 | | #if defined(POCO_HAVE_INT64) |
60 | | static Int64 fromBigEndian(Int64 value); |
61 | | static UInt64 fromBigEndian (UInt64 value); |
62 | | #endif |
63 | | |
64 | | static Int16 toLittleEndian(Int16 value); |
65 | | static UInt16 toLittleEndian (UInt16 value); |
66 | | static Int32 toLittleEndian(Int32 value); |
67 | | static UInt32 toLittleEndian (UInt32 value); |
68 | | #if defined(POCO_HAVE_INT64) |
69 | | static Int64 toLittleEndian(Int64 value); |
70 | | static UInt64 toLittleEndian (UInt64 value); |
71 | | #endif |
72 | | |
73 | | static Int16 fromLittleEndian(Int16 value); |
74 | | static UInt16 fromLittleEndian (UInt16 value); |
75 | | static Int32 fromLittleEndian(Int32 value); |
76 | | static UInt32 fromLittleEndian (UInt32 value); |
77 | | #if defined(POCO_HAVE_INT64) |
78 | | static Int64 fromLittleEndian(Int64 value); |
79 | | static UInt64 fromLittleEndian (UInt64 value); |
80 | | #endif |
81 | | |
82 | | static Int16 toNetwork(Int16 value); |
83 | | static UInt16 toNetwork (UInt16 value); |
84 | | static Int32 toNetwork(Int32 value); |
85 | | static UInt32 toNetwork (UInt32 value); |
86 | | #if defined(POCO_HAVE_INT64) |
87 | | static Int64 toNetwork(Int64 value); |
88 | | static UInt64 toNetwork (UInt64 value); |
89 | | #endif |
90 | | |
91 | | static Int16 fromNetwork(Int16 value); |
92 | | static UInt16 fromNetwork (UInt16 value); |
93 | | static Int32 fromNetwork(Int32 value); |
94 | | static UInt32 fromNetwork (UInt32 value); |
95 | | #if defined(POCO_HAVE_INT64) |
96 | | static Int64 fromNetwork(Int64 value); |
97 | | static UInt64 fromNetwork (UInt64 value); |
98 | | #endif |
99 | | |
100 | | private: |
101 | | template<typename T> |
102 | | static T flip(T value) |
103 | 0 | { |
104 | 0 | T flip = value; |
105 | 0 | std::size_t halfSize = sizeof(T) / 2; |
106 | 0 | char* flipP = reinterpret_cast<char*>(&flip); |
107 | 0 |
|
108 | 0 | for (std::size_t i = 0; i < halfSize; i++) |
109 | 0 | { |
110 | 0 | std::swap(flipP[i], flipP[sizeof(T) - i - 1]); |
111 | 0 | } |
112 | 0 | return flip; |
113 | 0 | } Unexecuted instantiation: float Poco::ByteOrder::flip<float>(float) Unexecuted instantiation: double Poco::ByteOrder::flip<double>(double) |
114 | | }; |
115 | | |
116 | | |
117 | | #if !defined(POCO_NO_BYTESWAP_BUILTINS) |
118 | | #if defined(_MSC_VER) |
119 | | #if (POCO_MSVC_VERSION > 71) |
120 | | #define POCO_HAVE_MSC_BYTESWAP 1 |
121 | | #endif |
122 | | #elif defined(__clang__) |
123 | | #if __has_builtin(__builtin_bswap32) |
124 | | #define POCO_HAVE_GCC_BYTESWAP 1 |
125 | | #endif |
126 | | #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) |
127 | | #define POCO_HAVE_GCC_BYTESWAP 1 |
128 | | #endif |
129 | | #endif |
130 | | |
131 | | |
132 | | // |
133 | | // inlines |
134 | | // |
135 | | inline UInt16 ByteOrder::flipBytes(UInt16 value) |
136 | 0 | { |
137 | | #if defined(POCO_HAVE_MSC_BYTESWAP) |
138 | | return _byteswap_ushort(value); |
139 | | #else |
140 | 0 | return ((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00); |
141 | 0 | #endif |
142 | 0 | } |
143 | | |
144 | | |
145 | | inline Int16 ByteOrder::flipBytes(Int16 value) |
146 | 0 | { |
147 | 0 | return Int16(flipBytes(UInt16(value))); |
148 | 0 | } |
149 | | |
150 | | |
151 | | inline UInt32 ByteOrder::flipBytes(UInt32 value) |
152 | 0 | { |
153 | | #if defined(POCO_HAVE_MSC_BYTESWAP) |
154 | | return _byteswap_ulong(value); |
155 | | #elif defined(POCO_HAVE_GCC_BYTESWAP) |
156 | 0 | return __builtin_bswap32(value); |
157 | | #else |
158 | | return ((value >> 24) & 0x000000FF) | ((value >> 8) & 0x0000FF00) |
159 | | | ((value << 8) & 0x00FF0000) | ((value << 24) & 0xFF000000); |
160 | | #endif |
161 | 0 | } |
162 | | |
163 | | |
164 | | inline Int32 ByteOrder::flipBytes(Int32 value) |
165 | 0 | { |
166 | 0 | return Int32(flipBytes(UInt32(value))); |
167 | 0 | } |
168 | | |
169 | | |
170 | | inline float ByteOrder::flipBytes(float value) |
171 | 0 | { |
172 | 0 | return flip(value); |
173 | 0 | } |
174 | | |
175 | | |
176 | | inline double ByteOrder::flipBytes(double value) |
177 | 0 | { |
178 | 0 | return flip(value); |
179 | 0 | } |
180 | | |
181 | | |
182 | | #if defined(POCO_HAVE_INT64) |
183 | | inline UInt64 ByteOrder::flipBytes(UInt64 value) |
184 | 0 | { |
185 | 0 | #if defined(POCO_HAVE_MSC_BYTESWAP) |
186 | 0 | return _byteswap_uint64(value); |
187 | 0 | #elif defined(POCO_HAVE_GCC_BYTESWAP) |
188 | 0 | return __builtin_bswap64(value); |
189 | 0 | #else |
190 | 0 | UInt32 hi = UInt32(value >> 32); |
191 | 0 | UInt32 lo = UInt32(value & 0xFFFFFFFF); |
192 | 0 | return UInt64(flipBytes(hi)) | (UInt64(flipBytes(lo)) << 32); |
193 | 0 | #endif |
194 | 0 | } |
195 | | |
196 | | |
197 | | inline Int64 ByteOrder::flipBytes(Int64 value) |
198 | 0 | { |
199 | 0 | return Int64(flipBytes(UInt64(value))); |
200 | 0 | } |
201 | | #endif // POCO_HAVE_INT64 |
202 | | |
203 | | |
204 | | // |
205 | | // some macro trickery to automate the method implementation |
206 | | // |
207 | | #define POCO_IMPLEMENT_BYTEORDER_NOOP_(op, type) \ |
208 | | inline type ByteOrder::op(type value) \ |
209 | 0 | { \ |
210 | 0 | return value; \ |
211 | 0 | } 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(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) |
212 | | #define POCO_IMPLEMENT_BYTEORDER_FLIP_(op, type) \ |
213 | | inline type ByteOrder::op(type value) \ |
214 | 0 | { \ |
215 | 0 | return flipBytes(value); \ |
216 | 0 | } Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned int) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned short) Unexecuted instantiation: Poco::ByteOrder::toNetwork(unsigned int) Unexecuted instantiation: Poco::ByteOrder::toNetwork(unsigned short) 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(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(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(short) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(int) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(long) Unexecuted instantiation: Poco::ByteOrder::fromNetwork(unsigned long) |
217 | | |
218 | | |
219 | | #if defined(POCO_HAVE_INT64) |
220 | | #define POCO_IMPLEMENT_BYTEORDER_NOOP(op) \ |
221 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int16) \ |
222 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt16) \ |
223 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int32) \ |
224 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt32) \ |
225 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int64) \ |
226 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt64) |
227 | | #define POCO_IMPLEMENT_BYTEORDER_FLIP(op) \ |
228 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int16) \ |
229 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt16) \ |
230 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int32) \ |
231 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt32) \ |
232 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int64) \ |
233 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt64) |
234 | | #else |
235 | | #define POCO_IMPLEMENT_BYTEORDER_NOOP(op) \ |
236 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int16) \ |
237 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt16) \ |
238 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, Int32) \ |
239 | | POCO_IMPLEMENT_BYTEORDER_NOOP_(op, UInt32) |
240 | | #define POCO_IMPLEMENT_BYTEORDER_FLIP(op) \ |
241 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int16) \ |
242 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt16) \ |
243 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, Int32) \ |
244 | | POCO_IMPLEMENT_BYTEORDER_FLIP_(op, UInt32) |
245 | | #endif |
246 | | |
247 | | |
248 | | #if defined(POCO_ARCH_BIG_ENDIAN) |
249 | | #define POCO_IMPLEMENT_BYTEORDER_BIG POCO_IMPLEMENT_BYTEORDER_NOOP |
250 | | #define POCO_IMPLEMENT_BYTEORDER_LIT POCO_IMPLEMENT_BYTEORDER_FLIP |
251 | | #else |
252 | | #define POCO_IMPLEMENT_BYTEORDER_BIG POCO_IMPLEMENT_BYTEORDER_FLIP |
253 | | #define POCO_IMPLEMENT_BYTEORDER_LIT POCO_IMPLEMENT_BYTEORDER_NOOP |
254 | | #endif |
255 | | |
256 | | |
257 | | POCO_IMPLEMENT_BYTEORDER_BIG(toBigEndian) |
258 | | POCO_IMPLEMENT_BYTEORDER_BIG(fromBigEndian) |
259 | | POCO_IMPLEMENT_BYTEORDER_BIG(toNetwork) |
260 | | POCO_IMPLEMENT_BYTEORDER_BIG(fromNetwork) |
261 | | POCO_IMPLEMENT_BYTEORDER_LIT(toLittleEndian) |
262 | | POCO_IMPLEMENT_BYTEORDER_LIT(fromLittleEndian) |
263 | | |
264 | | |
265 | | } // namespace Poco |
266 | | |
267 | | |
268 | | #endif // Foundation_ByteOrder_INCLUDED |