• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_UTIL_BASE_ENDIAN_H_
18 #define LIBTEXTCLASSIFIER_UTIL_BASE_ENDIAN_H_
19 
20 #include "util/base/integral_types.h"
21 
22 namespace libtextclassifier2 {
23 
24 #if defined OS_LINUX || defined OS_CYGWIN || defined OS_ANDROID || \
25     defined(__ANDROID__)
26 #include <endian.h>
27 #elif defined(__APPLE__)
28 #include <machine/endian.h>
29 // Add linux style defines.
30 #ifndef __BYTE_ORDER
31 #define __BYTE_ORDER BYTE_ORDER
32 #endif  // __BYTE_ORDER
33 #ifndef __LITTLE_ENDIAN
34 #define __LITTLE_ENDIAN LITTLE_ENDIAN
35 #endif  // __LITTLE_ENDIAN
36 #ifndef __BIG_ENDIAN
37 #define __BIG_ENDIAN BIG_ENDIAN
38 #endif  // __BIG_ENDIAN
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(__BIONIC__) || defined(__CYGWIN__)
44 #include <byteswap.h>  // IWYU pragma: export
45 // The following section defines the byte swap functions for OS X / iOS,
46 // which does not ship with byteswap.h.
47 #elif defined(__APPLE__)
48 // Make sure that byte swap functions are not already defined.
49 #if !defined(bswap_16)
50 #include <libkern/OSByteOrder.h>
51 #define bswap_16(x) OSSwapInt16(x)
52 #define bswap_32(x) OSSwapInt32(x)
53 #define bswap_64(x) OSSwapInt64(x)
54 #endif  // !defined(bswap_16)
55 #else
56 #define GG_LONGLONG(x) x##LL
57 #define GG_ULONGLONG(x) x##ULL
58 static inline uint16 bswap_16(uint16 x) {
59   return (uint16)(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));  // NOLINT
60 }
61 #define bswap_16(x) bswap_16(x)
62 static inline uint32 bswap_32(uint32 x) {
63   return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) |
64           ((x & 0xFF000000) >> 24));
65 }
66 #define bswap_32(x) bswap_32(x)
67 static inline uint64 bswap_64(uint64 x) {
68   return (((x & GG_ULONGLONG(0xFF)) << 56) |
69           ((x & GG_ULONGLONG(0xFF00)) << 40) |
70           ((x & GG_ULONGLONG(0xFF0000)) << 24) |
71           ((x & GG_ULONGLONG(0xFF000000)) << 8) |
72           ((x & GG_ULONGLONG(0xFF00000000)) >> 8) |
73           ((x & GG_ULONGLONG(0xFF0000000000)) >> 24) |
74           ((x & GG_ULONGLONG(0xFF000000000000)) >> 40) |
75           ((x & GG_ULONGLONG(0xFF00000000000000)) >> 56));
76 }
77 #define bswap_64(x) bswap_64(x)
78 #endif
79 
80 // define the macros IS_LITTLE_ENDIAN or IS_BIG_ENDIAN
81 // using the above endian definitions from endian.h if
82 // endian.h was included
83 #ifdef __BYTE_ORDER
84 #if __BYTE_ORDER == __LITTLE_ENDIAN
85 #define IS_LITTLE_ENDIAN
86 #endif
87 
88 #if __BYTE_ORDER == __BIG_ENDIAN
89 #define IS_BIG_ENDIAN
90 #endif
91 
92 #else
93 
94 #if defined(__LITTLE_ENDIAN__)
95 #define IS_LITTLE_ENDIAN
96 #elif defined(__BIG_ENDIAN__)
97 #define IS_BIG_ENDIAN
98 #endif
99 
100 // there is also PDP endian ...
101 
102 #endif  // __BYTE_ORDER
103 
104 class LittleEndian {
105  public:
106 // Conversion functions.
107 #ifdef IS_LITTLE_ENDIAN
108 
FromHost16(uint16 x)109   static uint16 FromHost16(uint16 x) { return x; }
ToHost16(uint16 x)110   static uint16 ToHost16(uint16 x) { return x; }
111 
FromHost32(uint32 x)112   static uint32 FromHost32(uint32 x) { return x; }
ToHost32(uint32 x)113   static uint32 ToHost32(uint32 x) { return x; }
114 
FromHost64(uint64 x)115   static uint64 FromHost64(uint64 x) { return x; }
ToHost64(uint64 x)116   static uint64 ToHost64(uint64 x) { return x; }
117 
IsLittleEndian()118   static bool IsLittleEndian() { return true; }
119 
120 #elif defined IS_BIG_ENDIAN
121 
122   static uint16 FromHost16(uint16 x) { return gbswap_16(x); }
123   static uint16 ToHost16(uint16 x) { return gbswap_16(x); }
124 
125   static uint32 FromHost32(uint32 x) { return gbswap_32(x); }
126   static uint32 ToHost32(uint32 x) { return gbswap_32(x); }
127 
128   static uint64 FromHost64(uint64 x) { return gbswap_64(x); }
129   static uint64 ToHost64(uint64 x) { return gbswap_64(x); }
130 
131   static bool IsLittleEndian() { return false; }
132 
133 #endif /* ENDIAN */
134 };
135 
136 }  // namespace libtextclassifier2
137 
138 #endif  // LIBTEXTCLASSIFIER_UTIL_BASE_ENDIAN_H_
139