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