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