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