MongoDB C++ Driver legacy-1.1.1
Loading...
Searching...
No Matches
endian.h
1/* Copyright 2014 MongoDB Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#pragma once
17
18#include "mongo/config.h"
19
20#include <climits>
21#include <cstring>
22#include <boost/static_assert.hpp>
23#include <boost/mpl/if.hpp>
24#include <boost/type_traits/is_signed.hpp>
25#include "mongo/platform/cstdint.h"
26
27#pragma push_macro("MONGO_UINT16_SWAB")
28#pragma push_macro("MONGO_UINT32_SWAB")
29#pragma push_macro("MONGO_UINT64_SWAB")
30#pragma push_macro("MONGO_LITTLE_ENDIAN")
31#pragma push_macro("MONGO_BIG_ENDIAN")
32#pragma push_macro("htobe16")
33#pragma push_macro("htobe32")
34#pragma push_macro("htobe64")
35#pragma push_macro("htole16")
36#pragma push_macro("htole32")
37#pragma push_macro("htole64")
38#pragma push_macro("be16toh")
39#pragma push_macro("be32toh")
40#pragma push_macro("be64toh")
41#pragma push_macro("le16toh")
42#pragma push_macro("le32toh")
43#pragma push_macro("le64toh")
44
45#undef MONGO_UINT16_SWAB
46#undef MONGO_UINT32_SWAB
47#undef MONGO_UINT64_SWAB
48#undef MONGO_LITTLE_ENDIAN
49#undef MONGO_BIG_ENDIAN
50#undef htobe16
51#undef htobe32
52#undef htobe64
53#undef htole16
54#undef htole32
55#undef htole64
56#undef be16toh
57#undef be32toh
58#undef be64toh
59#undef le16toh
60#undef le32toh
61#undef le64toh
62
63#define MONGO_LITTLE_ENDIAN 1234
64#define MONGO_BIG_ENDIAN 4321
65
66#if defined(_MSC_VER) && (_MSC_VER >= 1300)
67#include <cstdlib>
68#define MONGO_UINT16_SWAB(v) _byteswap_ushort(v)
69#define MONGO_UINT32_SWAB(v) _byteswap_ulong(v)
70#define MONGO_UINT64_SWAB(v) _byteswap_uint64(v)
71#elif defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) && \
72 (__clang_major__ >= 3) && (__clang_minor__ >= 1)
73#if __has_builtin(__builtin_bswap16)
74#define MONGO_UINT16_SWAB(v) __builtin_bswap16(v)
75#endif
76#if __has_builtin(__builtin_bswap32)
77#define MONGO_UINT32_SWAB(v) __builtin_bswap32(v)
78#endif
79#if __has_builtin(__builtin_bswap64)
80#define MONGO_UINT64_SWAB(v) __builtin_bswap64(v)
81#endif
82#elif defined(__GNUC__) && (__GNUC__ >= 4)
83#if __GNUC__ >= 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3
84#define MONGO_UINT32_SWAB(v) __builtin_bswap32(v)
85#define MONGO_UINT64_SWAB(v) __builtin_bswap64(v)
86#endif
87#if __GNUC__ >= 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 8
88#define MONGO_UINT16_SWAB(v) __builtin_bswap16(v)
89#endif
90#elif defined(__sun)
91#include <sys/byteorder.h>
92#define MONGO_UINT16_SWAB(v) BSWAP_16(v)
93#define MONGO_UINT32_SWAB(v) BSWAP_32(v)
94#define MONGO_UINT64_SWAB(v) BSWAP_64(v)
95#endif
96
97#ifndef MONGO_UINT16_SWAB
98#define MONGO_UINT16_SWAB(v) endian::bswap_slow16(v)
99#endif
100
101#ifndef MONGO_UINT32_SWAB
102#define MONGO_UINT32_SWAB(v) endian::bswap_slow32(v)
103#endif
104
105#ifndef MONGO_UINT64_SWAB
106#define MONGO_UINT64_SWAB(v) endian::bswap_slow64(v)
107#endif
108
109#if MONGO_BYTE_ORDER == MONGO_LITTLE_ENDIAN
110#define htobe16(v) MONGO_UINT16_SWAB(v)
111#define htobe32(v) MONGO_UINT32_SWAB(v)
112#define htobe64(v) MONGO_UINT64_SWAB(v)
113#define htole16(v) (v)
114#define htole32(v) (v)
115#define htole64(v) (v)
116#define be16toh(v) MONGO_UINT16_SWAB(v)
117#define be32toh(v) MONGO_UINT32_SWAB(v)
118#define be64toh(v) MONGO_UINT64_SWAB(v)
119#define le16toh(v) (v)
120#define le32toh(v) (v)
121#define le64toh(v) (v)
122#elif MONGO_BYTE_ORDER == MONGO_BIG_ENDIAN
123#define htobe16(v) (v)
124#define htobe32(v) (v)
125#define htobe64(v) (v)
126#define htole16(v) MONGO_UINT16_SWAB(v)
127#define htole32(v) MONGO_UINT32_SWAB(v)
128#define htole64(v) MONGO_UINT64_SWAB(v)
129#define be16toh(v) (v)
130#define be32toh(v) (v)
131#define be64toh(v) (v)
132#define le16toh(v) MONGO_UINT16_SWAB(v)
133#define le32toh(v) MONGO_UINT32_SWAB(v)
134#define le64toh(v) MONGO_UINT64_SWAB(v)
135#else
136#error \
137 "The endianness of target architecture is unknown. " \
138 "Please define MONGO_BYTE_ORDER"
139#endif
140
141namespace mongo {
142namespace endian {
143
144static inline uint16_t bswap_slow16(uint16_t v) {
145 return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
146}
147
148static inline uint32_t bswap_slow32(uint32_t v) {
149 return ((v & 0x000000FFUL) << 24) | ((v & 0x0000FF00UL) << 8) | ((v & 0x00FF0000UL) >> 8) |
150 ((v & 0xFF000000UL) >> 24);
151}
152
153static inline uint64_t bswap_slow64(uint64_t v) {
154 return ((v & 0x00000000000000FFULL) << 56) | ((v & 0x000000000000FF00ULL) << 40) |
155 ((v & 0x0000000000FF0000ULL) << 24) | ((v & 0x00000000FF000000ULL) << 8) |
156 ((v & 0x000000FF00000000ULL) >> 8) | ((v & 0x0000FF0000000000ULL) >> 24) |
157 ((v & 0x00FF000000000000ULL) >> 40) | ((v & 0xFF00000000000000ULL) >> 56);
158}
159
160template <typename T>
162
163template <>
164struct ByteOrderConverter<uint8_t> {
165 typedef uint8_t T;
166
167 inline static T nativeToBig(T t) {
168 return t;
169 }
170
171 inline static T bigToNative(T t) {
172 return t;
173 }
174
175 inline static T nativeToLittle(T t) {
176 return t;
177 }
178
179 inline static T littleToNative(T t) {
180 return t;
181 }
182};
183
184template <>
185struct ByteOrderConverter<uint16_t> {
186 typedef uint16_t T;
187
188 inline static T nativeToBig(T t) {
189 return htobe16(t);
190 }
191
192 inline static T bigToNative(T t) {
193 return be16toh(t);
194 }
195
196 inline static T nativeToLittle(T t) {
197 return htole16(t);
198 }
199
200 inline static T littleToNative(T t) {
201 return le16toh(t);
202 }
203};
204
205template <>
206struct ByteOrderConverter<uint32_t> {
207 typedef uint32_t T;
208
209 inline static T nativeToBig(T t) {
210 return htobe32(t);
211 }
212
213 inline static T bigToNative(T t) {
214 return be32toh(t);
215 }
216
217 inline static T nativeToLittle(T t) {
218 return htole32(t);
219 }
220
221 inline static T littleToNative(T t) {
222 return le32toh(t);
223 }
224};
225
226template <>
227struct ByteOrderConverter<uint64_t> {
228 typedef uint64_t T;
229
230 inline static T nativeToBig(T t) {
231 return htobe64(t);
232 }
233
234 inline static T bigToNative(T t) {
235 return be64toh(t);
236 }
237
238 inline static T nativeToLittle(T t) {
239 return htole64(t);
240 }
241
242 inline static T littleToNative(T t) {
243 return le64toh(t);
244 }
245};
246
247template <>
248struct ByteOrderConverter<int8_t> {
249 typedef int8_t T;
250
251 inline static T nativeToBig(T t) {
252 return t;
253 }
254
255 inline static T bigToNative(T t) {
256 return t;
257 }
258
259 inline static T nativeToLittle(T t) {
260 return t;
261 }
262
263 inline static T littleToNative(T t) {
264 return t;
265 }
266};
267
268template <>
269struct ByteOrderConverter<int16_t> {
270 typedef int16_t T;
271
272 inline static T nativeToBig(T t) {
273 return htobe16(static_cast<uint16_t>(t));
274 }
275
276 inline static T bigToNative(T t) {
277 return be16toh(static_cast<uint16_t>(t));
278 }
279
280 inline static T nativeToLittle(T t) {
281 return htole16(static_cast<uint16_t>(t));
282 }
283
284 inline static T littleToNative(T t) {
285 return le16toh(static_cast<uint16_t>(t));
286 }
287};
288
289template <>
290struct ByteOrderConverter<int32_t> {
291 typedef int32_t T;
292
293 inline static T nativeToBig(T t) {
294 return htobe32(static_cast<uint32_t>(t));
295 }
296
297 inline static T bigToNative(T t) {
298 return be32toh(static_cast<uint32_t>(t));
299 }
300
301 inline static T nativeToLittle(T t) {
302 return htole32(static_cast<uint32_t>(t));
303 }
304
305 inline static T littleToNative(T t) {
306 return le32toh(static_cast<uint32_t>(t));
307 }
308};
309
310template <>
311struct ByteOrderConverter<int64_t> {
312 typedef int64_t T;
313
314 inline static T nativeToBig(T t) {
315 return htobe64(static_cast<uint64_t>(t));
316 }
317
318 inline static T bigToNative(T t) {
319 return be64toh(static_cast<uint64_t>(t));
320 }
321
322 inline static T nativeToLittle(T t) {
323 return htole64(static_cast<uint64_t>(t));
324 }
325
326 inline static T littleToNative(T t) {
327 return le64toh(static_cast<uint64_t>(t));
328 }
329};
330
331template <>
332struct ByteOrderConverter<float> {
333 typedef float T;
334
335 inline static T nativeToBig(T t) {
336 BOOST_STATIC_ASSERT(sizeof(T) == sizeof(uint32_t));
337
338 uint32_t temp;
339 std::memcpy(&temp, &t, sizeof(t));
340 temp = htobe32(temp);
341 std::memcpy(&t, &temp, sizeof(t));
342 return t;
343 }
344
345 inline static T bigToNative(T t) {
346 uint32_t temp;
347 std::memcpy(&temp, &t, sizeof(t));
348 temp = be32toh(temp);
349 std::memcpy(&t, &temp, sizeof(t));
350 return t;
351 }
352
353 inline static T nativeToLittle(T t) {
354 uint32_t temp;
355 std::memcpy(&temp, &t, sizeof(t));
356 temp = htole32(temp);
357 std::memcpy(&t, &temp, sizeof(t));
358 return t;
359 }
360
361 inline static T littleToNative(T t) {
362 uint32_t temp;
363 std::memcpy(&temp, &t, sizeof(t));
364 temp = le32toh(temp);
365 std::memcpy(&t, &temp, sizeof(t));
366 return t;
367 }
368};
369
370template <>
371struct ByteOrderConverter<double> {
372 typedef double T;
373
374 inline static T nativeToBig(T t) {
375 BOOST_STATIC_ASSERT(sizeof(T) == sizeof(uint64_t));
376
377 uint64_t temp;
378 std::memcpy(&temp, &t, sizeof(t));
379 temp = htobe64(temp);
380 std::memcpy(&t, &temp, sizeof(t));
381 return t;
382 }
383
384 inline static T bigToNative(T t) {
385 uint64_t temp;
386 std::memcpy(&temp, &t, sizeof(t));
387 temp = be64toh(temp);
388 std::memcpy(&t, &temp, sizeof(t));
389 return t;
390 }
391
392 inline static T nativeToLittle(T t) {
393 uint64_t temp;
394 std::memcpy(&temp, &t, sizeof(t));
395 temp = htole64(temp);
396 std::memcpy(&t, &temp, sizeof(t));
397 return t;
398 }
399
400 inline static T littleToNative(T t) {
401 uint64_t temp;
402 std::memcpy(&temp, &t, sizeof(t));
403 temp = le64toh(temp);
404 std::memcpy(&t, &temp, sizeof(t));
405 return t;
406 }
407};
408
409// Use a typemape to normalize non-fixed-width integral types to the associated fixed width
410// types.
411
412template <typename T>
414 typedef T type;
415};
416
417template <>
418struct IntegralTypeMap<signed char> {
419 BOOST_STATIC_ASSERT(CHAR_BIT == 8);
420 typedef int8_t type;
421};
422
423template <>
424struct IntegralTypeMap<unsigned char> {
425 BOOST_STATIC_ASSERT(CHAR_BIT == 8);
426 typedef uint8_t type;
427};
428
429template <>
430struct IntegralTypeMap<char> {
431 BOOST_STATIC_ASSERT(CHAR_BIT == 8);
432 typedef boost::mpl::if_c<boost::is_signed<char>::value, int8_t, uint8_t>::type type;
433};
434
435template <>
436struct IntegralTypeMap<long long> {
437 BOOST_STATIC_ASSERT(sizeof(long long) == sizeof(int64_t));
438 typedef int64_t type;
439};
440
441template <>
442struct IntegralTypeMap<unsigned long long> {
443 BOOST_STATIC_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t));
444 typedef uint64_t type;
445};
446
447template <typename T>
448inline T nativeToBig(T t) {
450}
451
452template <typename T>
453inline T bigToNative(T t) {
454 return ByteOrderConverter<typename IntegralTypeMap<T>::type>::bigToNative(t);
455}
456
457template <typename T>
458inline T nativeToLittle(T t) {
459 return ByteOrderConverter<typename IntegralTypeMap<T>::type>::nativeToLittle(t);
460}
461
462template <typename T>
463inline T littleToNative(T t) {
464 return ByteOrderConverter<typename IntegralTypeMap<T>::type>::littleToNative(t);
465}
466
467} // namespace endian
468} // namespace mongo
469
470#undef MONGO_UINT16_SWAB
471#undef MONGO_UINT32_SWAB
472#undef MONGO_UINT64_SWAB
473#undef MONGO_LITTLE_ENDIAN
474#undef MONGO_BIG_ENDIAN
475#undef htobe16
476#undef htobe32
477#undef htobe64
478#undef htole16
479#undef htole32
480#undef htole64
481#undef be16toh
482#undef be32toh
483#undef be64toh
484#undef le16toh
485#undef le32toh
486#undef le64toh
487
488#pragma pop_macro("MONGO_UINT16_SWAB")
489#pragma pop_macro("MONGO_UINT32_SWAB")
490#pragma pop_macro("MONGO_UINT64_SWAB")
491#pragma pop_macro("MONGO_LITTLE_ENDIAN")
492#pragma pop_macro("MONGO_BIG_ENDIAN")
493#pragma pop_macro("htobe16")
494#pragma pop_macro("htobe32")
495#pragma pop_macro("htobe64")
496#pragma pop_macro("htole16")
497#pragma pop_macro("htole32")
498#pragma pop_macro("htole64")
499#pragma pop_macro("be16toh")
500#pragma pop_macro("be32toh")
501#pragma pop_macro("be64toh")
502#pragma pop_macro("le16toh")
503#pragma pop_macro("le32toh")
504#pragma pop_macro("le64toh")
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:32
Definition endian.h:161
Definition endian.h:413