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__) || defined(__DragonFly__)
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  */
ByteSwap(void * data,size_t elem_bytes,size_t num_elems)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