xref: /aosp_15_r20/external/libtextclassifier/native/utils/base/endian.h (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
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 Worker static 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 Worker static 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 Worker static 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