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 NLP_SAFT_COMPONENTS_COMMON_MOBILE_LITE_BASE_ENDIAN_H_ 18 #define NLP_SAFT_COMPONENTS_COMMON_MOBILE_LITE_BASE_ENDIAN_H_ 19 20 #include "lang_id/common/lite_base/integral-types.h" 21 22 namespace libtextclassifier3 { 23 namespace mobile { 24 25 #if defined OS_LINUX || defined OS_CYGWIN || defined OS_ANDROID || \ 26 defined(__ANDROID__) 27 #include <endian.h> 28 #endif 29 30 // The following guarantees declaration of the byte swap functions, and 31 // defines __BYTE_ORDER for MSVC 32 #if defined(__GLIBC__) || defined(__CYGWIN__) 33 #include <byteswap.h> // IWYU pragma: export 34 35 #else 36 #ifndef bswap_16 37 static inline uint16 bswap_16(uint16 x) { 38 return (uint16)(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); // NOLINT 39 } 40 #define bswap_16(x) bswap_16(x) 41 #endif // bswap_16 42 43 #ifndef bswap_32 44 static inline uint32 bswap_32(uint32 x) { 45 return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | 46 ((x & 0xFF000000) >> 24)); 47 } 48 #define bswap_32(x) bswap_32(x) 49 #endif // bswap_32 50 51 #ifndef bswap_64 52 #define SAFTM_GG_ULONGLONG(x) x##ULL 53 static inline uint64 bswap_64(uint64 x) { 54 return (((x & SAFTM_GG_ULONGLONG(0xFF)) << 56) | 55 ((x & SAFTM_GG_ULONGLONG(0xFF00)) << 40) | 56 ((x & SAFTM_GG_ULONGLONG(0xFF0000)) << 24) | 57 ((x & SAFTM_GG_ULONGLONG(0xFF000000)) << 8) | 58 ((x & SAFTM_GG_ULONGLONG(0xFF00000000)) >> 8) | 59 ((x & SAFTM_GG_ULONGLONG(0xFF0000000000)) >> 24) | 60 ((x & SAFTM_GG_ULONGLONG(0xFF000000000000)) >> 40) | 61 ((x & SAFTM_GG_ULONGLONG(0xFF00000000000000)) >> 56)); 62 } 63 #define bswap_64(x) bswap_64(x) 64 #endif // bswap_64 65 66 #endif 67 68 // define the macros SAFTM_IS_LITTLE_ENDIAN or SAFTM_IS_BIG_ENDIAN using the 69 // above endian definitions from endian.h if endian.h was included 70 #ifdef __BYTE_ORDER 71 #if __BYTE_ORDER == __LITTLE_ENDIAN 72 #define SAFTM_IS_LITTLE_ENDIAN 73 #endif 74 75 #if __BYTE_ORDER == __BIG_ENDIAN 76 #define SAFTM_IS_BIG_ENDIAN 77 #endif 78 79 #else // __BYTE_ORDER 80 81 #if defined(__LITTLE_ENDIAN__) 82 #define SAFTM_IS_LITTLE_ENDIAN 83 #elif defined(__BIG_ENDIAN__) 84 #define SAFTM_IS_BIG_ENDIAN 85 #endif 86 87 // there is also PDP endian ... 88 89 #endif // __BYTE_ORDER 90 91 class LittleEndian { 92 public: 93 // Conversion functions. 94 #ifdef SAFTM_IS_LITTLE_ENDIAN 95 IsLittleEndian()96 static bool IsLittleEndian() { return true; } 97 98 #elif defined SAFTM_IS_BIG_ENDIAN 99 100 static uint16 FromHost16(uint16 x) { return gbswap_16(x); } 101 static uint16 ToHost16(uint16 x) { return gbswap_16(x); } 102 103 static uint32 FromHost32(uint32 x) { return gbswap_32(x); } 104 static uint32 ToHost32(uint32 x) { return gbswap_32(x); } 105 106 static uint64 FromHost64(uint64 x) { return gbswap_64(x); } 107 static uint64 ToHost64(uint64 x) { return gbswap_64(x); } 108 109 static bool IsLittleEndian() { return false; } 110 111 #endif /* ENDIAN */ 112 }; 113 114 } // namespace mobile 115 } // namespace nlp_saft 116 117 #endif // NLP_SAFT_COMPONENTS_COMMON_MOBILE_LITE_BASE_ENDIAN_H_ 118