Coverage Report

Created: 2024-02-25 06:22

/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