Coverage Report

Created: 2025-10-14 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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