1 | /*! |
2 | * Copyright (c) 2017 by Contributors |
3 | * \file endian.h |
4 | * \brief Endian testing, need c++11 |
5 | */ |
6 | #ifndef DMLC_ENDIAN_H_ |
7 | #define DMLC_ENDIAN_H_ |
8 | |
9 | #include "./base.h" |
10 | |
11 | #ifdef DMLC_CMAKE_LITTLE_ENDIAN |
12 | // If compiled with CMake, use CMake's endian detection logic |
13 | #define DMLC_LITTLE_ENDIAN DMLC_CMAKE_LITTLE_ENDIAN |
14 | #else |
15 | #if defined(__APPLE__) || defined(_WIN32) |
16 | #define DMLC_LITTLE_ENDIAN 1 |
17 | #elif defined(__GLIBC__) || defined(__GNU_LIBRARY__) \ |
18 | || defined(__ANDROID__) || defined(__RISCV__) |
19 | #include <endian.h> |
20 | #define DMLC_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN) |
21 | #elif defined(__FreeBSD__) || defined(__OpenBSD__) |
22 | #include <sys/endian.h> |
23 | #define DMLC_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) |
24 | #elif defined(__EMSCRIPTEN__) || defined(__hexagon__) |
25 | #define DMLC_LITTLE_ENDIAN 1 |
26 | #elif defined(__sun) || defined(sun) |
27 | #include <sys/isa_defs.h> |
28 | #if defined(_LITTLE_ENDIAN) |
29 | #define DMLC_LITTLE_ENDIAN 1 |
30 | #else |
31 | #define DMLC_LITTLE_ENDIAN 0 |
32 | #endif |
33 | #else |
34 | #error "Unable to determine endianness of your machine; use CMake to compile" |
35 | #endif |
36 | #endif |
37 | |
38 | /*! \brief whether serialize using little endian */ |
39 | #define DMLC_IO_NO_ENDIAN_SWAP (DMLC_LITTLE_ENDIAN == DMLC_IO_USE_LITTLE_ENDIAN) |
40 | |
41 | namespace dmlc { |
42 | |
43 | /*! |
44 | * \brief A generic inplace byte swapping function. |
45 | * \param data The data pointer. |
46 | * \param elem_bytes The number of bytes of the data elements |
47 | * \param num_elems Number of elements in the data. |
48 | * \note Always try pass in constant elem_bytes to enable |
49 | * compiler optimization |
50 | */ |
51 | inline void ByteSwap(void* data, size_t elem_bytes, size_t num_elems) { |
52 | for (size_t i = 0; i < num_elems; ++i) { |
53 | uint8_t* bptr = reinterpret_cast<uint8_t*>(data) + elem_bytes * i; |
54 | for (size_t j = 0; j < elem_bytes / 2; ++j) { |
55 | uint8_t v = bptr[elem_bytes - 1 - j]; |
56 | bptr[elem_bytes - 1 - j] = bptr[j]; |
57 | bptr[j] = v; |
58 | } |
59 | } |
60 | } |
61 | |
62 | } // namespace dmlc |
63 | #endif // DMLC_ENDIAN_H_ |
64 | |