1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LIBTEXTCLASSIFIER_UTILS_BASE_ENDIAN_H_ 18 #define LIBTEXTCLASSIFIER_UTILS_BASE_ENDIAN_H_ 19 20 #include "utils/base/integral_types.h" 21 22 #if defined OS_LINUX || defined OS_CYGWIN || defined OS_ANDROID || \ 23 defined(__ANDROID__) 24 #include <endian.h> 25 #elif defined(__APPLE__) 26 #include <machine/endian.h> 27 // Add linux style defines. 28 #ifndef __BYTE_ORDER 29 #define __BYTE_ORDER BYTE_ORDER 30 #endif // __BYTE_ORDER 31 #ifndef __LITTLE_ENDIAN 32 #define __LITTLE_ENDIAN LITTLE_ENDIAN 33 #endif // __LITTLE_ENDIAN 34 #ifndef __BIG_ENDIAN 35 #define __BIG_ENDIAN BIG_ENDIAN 36 #endif // __BIG_ENDIAN 37 #endif 38 39 // The following guarantees declaration of the byte swap functions, and 40 // defines __BYTE_ORDER for MSVC 41 #if defined(__GLIBC__) || defined(__BIONIC__) || defined(__CYGWIN__) 42 #include <byteswap.h> // IWYU pragma: export 43 // The following section defines the byte swap functions for OS X / iOS, 44 // which does not ship with byteswap.h. 45 #elif defined(__APPLE__) 46 // Make sure that byte swap functions are not already defined. 47 #if !defined(bswap_16) 48 #include <libkern/OSByteOrder.h> 49 #define bswap_16(x) OSSwapInt16(x) 50 #define bswap_32(x) OSSwapInt32(x) 51 #define bswap_64(x) OSSwapInt64(x) 52 #endif // !defined(bswap_16) 53 #else 54 #define int64_t {x} x##LL 55 #define uint64_t {x} x##ULL bswap_16(uint16 x)56static inline uint16 bswap_16(uint16 x) { 57 return (uint16)(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); // NOLINT 58 } 59 #define bswap_16(x) bswap_16(x) bswap_32(uint32 x)60static inline uint32 bswap_32(uint32 x) { 61 return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | 62 ((x & 0xFF000000) >> 24)); 63 } 64 #define bswap_32(x) bswap_32(x) bswap_64(uint64 x)65static inline uint64 bswap_64(uint64 x) { 66 return (((x & uint64_t{0xFF}) << 56) | ((x & uint64_t{0xFF00}) << 40) | 67 ((x & uint64_t{0xFF0000}) << 24) | ((x & uint64_t{0xFF000000}) << 8) | 68 ((x & uint64_t{0xFF00000000}) >> 8) | 69 ((x & uint64_t{0xFF0000000000}) >> 24) | 70 ((x & uint64_t{0xFF000000000000}) >> 40) | 71 ((x & uint64_t{0xFF00000000000000}) >> 56)); 72 } 73 #define bswap_64(x) bswap_64(x) 74 #endif 75 76 // define the macros IS_LITTLE_ENDIAN or IS_BIG_ENDIAN 77 // using the above endian definitions from endian.h if 78 // endian.h was included 79 #ifdef __BYTE_ORDER 80 #if __BYTE_ORDER == __LITTLE_ENDIAN 81 #define IS_LITTLE_ENDIAN 82 #endif 83 84 #if __BYTE_ORDER == __BIG_ENDIAN 85 #define IS_BIG_ENDIAN 86 #endif 87 88 #else 89 90 #if defined(__LITTLE_ENDIAN__) 91 #define IS_LITTLE_ENDIAN 92 #elif defined(__BIG_ENDIAN__) 93 #define IS_BIG_ENDIAN 94 #endif 95 96 // there is also PDP endian ... 97 98 #endif // __BYTE_ORDER 99 100 namespace libtextclassifier3 { 101 102 class LittleEndian { 103 public: 104 // Conversion functions. 105 #ifdef IS_LITTLE_ENDIAN 106 FromHost16(uint16 x)107 static uint16 FromHost16(uint16 x) { return x; } ToHost16(uint16 x)108 static uint16 ToHost16(uint16 x) { return x; } 109 FromHost32(uint32 x)110 static uint32 FromHost32(uint32 x) { return x; } ToHost32(uint32 x)111 static uint32 ToHost32(uint32 x) { return x; } 112 FromHost64(uint64 x)113 static uint64 FromHost64(uint64 x) { return x; } ToHost64(uint64 x)114 static uint64 ToHost64(uint64 x) { return x; } 115 IsLittleEndian()116 static bool IsLittleEndian() { return true; } 117 118 #elif defined IS_BIG_ENDIAN 119 120 static uint16 FromHost16(uint16 x) { return gbswap_16(x); } 121 static uint16 ToHost16(uint16 x) { return gbswap_16(x); } 122 123 static uint32 FromHost32(uint32 x) { return gbswap_32(x); } 124 static uint32 ToHost32(uint32 x) { return gbswap_32(x); } 125 126 static uint64 FromHost64(uint64 x) { return gbswap_64(x); } 127 static uint64 ToHost64(uint64 x) { return gbswap_64(x); } 128 129 static bool IsLittleEndian() { return false; } 130 131 #endif /* ENDIAN */ 132 }; 133 134 } // namespace libtextclassifier3 135 136 #endif // LIBTEXTCLASSIFIER_UTILS_BASE_ENDIAN_H_ 137