/src/LPM/external.protobuf/include/absl/base/internal/endian.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2017 The Abseil Authors. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | // |
15 | | |
16 | | #ifndef ABSL_BASE_INTERNAL_ENDIAN_H_ |
17 | | #define ABSL_BASE_INTERNAL_ENDIAN_H_ |
18 | | |
19 | | #include <cstdint> |
20 | | #include <cstdlib> |
21 | | |
22 | | #include "absl/base/casts.h" |
23 | | #include "absl/base/config.h" |
24 | | #include "absl/base/internal/unaligned_access.h" |
25 | | #include "absl/base/port.h" |
26 | | |
27 | | namespace absl { |
28 | | ABSL_NAMESPACE_BEGIN |
29 | | |
30 | 0 | inline uint64_t gbswap_64(uint64_t host_int) { |
31 | 0 | #if ABSL_HAVE_BUILTIN(__builtin_bswap64) || defined(__GNUC__) |
32 | 0 | return __builtin_bswap64(host_int); |
33 | 0 | #elif defined(_MSC_VER) |
34 | 0 | return _byteswap_uint64(host_int); |
35 | 0 | #else |
36 | 0 | return (((host_int & uint64_t{0xFF}) << 56) | |
37 | 0 | ((host_int & uint64_t{0xFF00}) << 40) | |
38 | 0 | ((host_int & uint64_t{0xFF0000}) << 24) | |
39 | 0 | ((host_int & uint64_t{0xFF000000}) << 8) | |
40 | 0 | ((host_int & uint64_t{0xFF00000000}) >> 8) | |
41 | 0 | ((host_int & uint64_t{0xFF0000000000}) >> 24) | |
42 | 0 | ((host_int & uint64_t{0xFF000000000000}) >> 40) | |
43 | 0 | ((host_int & uint64_t{0xFF00000000000000}) >> 56)); |
44 | 0 | #endif |
45 | 0 | } |
46 | | |
47 | 0 | inline uint32_t gbswap_32(uint32_t host_int) { |
48 | 0 | #if ABSL_HAVE_BUILTIN(__builtin_bswap32) || defined(__GNUC__) |
49 | 0 | return __builtin_bswap32(host_int); |
50 | 0 | #elif defined(_MSC_VER) |
51 | 0 | return _byteswap_ulong(host_int); |
52 | 0 | #else |
53 | 0 | return (((host_int & uint32_t{0xFF}) << 24) | |
54 | 0 | ((host_int & uint32_t{0xFF00}) << 8) | |
55 | 0 | ((host_int & uint32_t{0xFF0000}) >> 8) | |
56 | 0 | ((host_int & uint32_t{0xFF000000}) >> 24)); |
57 | 0 | #endif |
58 | 0 | } |
59 | | |
60 | 0 | inline uint16_t gbswap_16(uint16_t host_int) { |
61 | 0 | #if ABSL_HAVE_BUILTIN(__builtin_bswap16) || defined(__GNUC__) |
62 | 0 | return __builtin_bswap16(host_int); |
63 | 0 | #elif defined(_MSC_VER) |
64 | 0 | return _byteswap_ushort(host_int); |
65 | 0 | #else |
66 | 0 | return (((host_int & uint16_t{0xFF}) << 8) | |
67 | 0 | ((host_int & uint16_t{0xFF00}) >> 8)); |
68 | 0 | #endif |
69 | 0 | } |
70 | | |
71 | | #ifdef ABSL_IS_LITTLE_ENDIAN |
72 | | |
73 | | // Portable definitions for htonl (host-to-network) and friends on little-endian |
74 | | // architectures. |
75 | 0 | inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); } |
76 | 0 | inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); } |
77 | 0 | inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); } |
78 | | |
79 | | #elif defined ABSL_IS_BIG_ENDIAN |
80 | | |
81 | | // Portable definitions for htonl (host-to-network) etc on big-endian |
82 | | // architectures. These definitions are simpler since the host byte order is the |
83 | | // same as network byte order. |
84 | | inline uint16_t ghtons(uint16_t x) { return x; } |
85 | | inline uint32_t ghtonl(uint32_t x) { return x; } |
86 | | inline uint64_t ghtonll(uint64_t x) { return x; } |
87 | | |
88 | | #else |
89 | | #error \ |
90 | | "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \ |
91 | | "ABSL_IS_LITTLE_ENDIAN must be defined" |
92 | | #endif // byte order |
93 | | |
94 | 0 | inline uint16_t gntohs(uint16_t x) { return ghtons(x); } |
95 | 0 | inline uint32_t gntohl(uint32_t x) { return ghtonl(x); } |
96 | 0 | inline uint64_t gntohll(uint64_t x) { return ghtonll(x); } |
97 | | |
98 | | // Utilities to convert numbers between the current hosts's native byte |
99 | | // order and little-endian byte order |
100 | | // |
101 | | // Load/Store methods are alignment safe |
102 | | namespace little_endian { |
103 | | // Conversion functions. |
104 | | #ifdef ABSL_IS_LITTLE_ENDIAN |
105 | | |
106 | 0 | inline uint16_t FromHost16(uint16_t x) { return x; } |
107 | 0 | inline uint16_t ToHost16(uint16_t x) { return x; } |
108 | | |
109 | 0 | inline uint32_t FromHost32(uint32_t x) { return x; } |
110 | 0 | inline uint32_t ToHost32(uint32_t x) { return x; } |
111 | | |
112 | 0 | inline uint64_t FromHost64(uint64_t x) { return x; } |
113 | 0 | inline uint64_t ToHost64(uint64_t x) { return x; } |
114 | | |
115 | 0 | inline constexpr bool IsLittleEndian() { return true; } |
116 | | |
117 | | #elif defined ABSL_IS_BIG_ENDIAN |
118 | | |
119 | | inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } |
120 | | inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } |
121 | | |
122 | | inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } |
123 | | inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } |
124 | | |
125 | | inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } |
126 | | inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } |
127 | | |
128 | | inline constexpr bool IsLittleEndian() { return false; } |
129 | | |
130 | | #endif /* ENDIAN */ |
131 | | |
132 | 0 | inline uint8_t FromHost(uint8_t x) { return x; } |
133 | 0 | inline uint16_t FromHost(uint16_t x) { return FromHost16(x); } |
134 | 0 | inline uint32_t FromHost(uint32_t x) { return FromHost32(x); } |
135 | 0 | inline uint64_t FromHost(uint64_t x) { return FromHost64(x); } |
136 | 0 | inline uint8_t ToHost(uint8_t x) { return x; } |
137 | 0 | inline uint16_t ToHost(uint16_t x) { return ToHost16(x); } |
138 | 0 | inline uint32_t ToHost(uint32_t x) { return ToHost32(x); } |
139 | 0 | inline uint64_t ToHost(uint64_t x) { return ToHost64(x); } |
140 | | |
141 | 0 | inline int8_t FromHost(int8_t x) { return x; } |
142 | 0 | inline int16_t FromHost(int16_t x) { |
143 | 0 | return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x))); |
144 | 0 | } |
145 | 0 | inline int32_t FromHost(int32_t x) { |
146 | 0 | return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x))); |
147 | 0 | } |
148 | 0 | inline int64_t FromHost(int64_t x) { |
149 | 0 | return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x))); |
150 | 0 | } |
151 | 0 | inline int8_t ToHost(int8_t x) { return x; } |
152 | 0 | inline int16_t ToHost(int16_t x) { |
153 | 0 | return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x))); |
154 | 0 | } |
155 | 0 | inline int32_t ToHost(int32_t x) { |
156 | 0 | return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x))); |
157 | 0 | } |
158 | 0 | inline int64_t ToHost(int64_t x) { |
159 | 0 | return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x))); |
160 | 0 | } |
161 | | |
162 | | // Functions to do unaligned loads and stores in little-endian order. |
163 | 0 | inline uint16_t Load16(const void *p) { |
164 | 0 | return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); |
165 | 0 | } |
166 | | |
167 | 0 | inline void Store16(void *p, uint16_t v) { |
168 | 0 | ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); |
169 | 0 | } |
170 | | |
171 | 0 | inline uint32_t Load32(const void *p) { |
172 | 0 | return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); |
173 | 0 | } |
174 | | |
175 | 0 | inline void Store32(void *p, uint32_t v) { |
176 | 0 | ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); |
177 | 0 | } |
178 | | |
179 | 0 | inline uint64_t Load64(const void *p) { |
180 | 0 | return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); |
181 | 0 | } |
182 | | |
183 | 0 | inline void Store64(void *p, uint64_t v) { |
184 | 0 | ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); |
185 | 0 | } |
186 | | |
187 | | } // namespace little_endian |
188 | | |
189 | | // Utilities to convert numbers between the current hosts's native byte |
190 | | // order and big-endian byte order (same as network byte order) |
191 | | // |
192 | | // Load/Store methods are alignment safe |
193 | | namespace big_endian { |
194 | | #ifdef ABSL_IS_LITTLE_ENDIAN |
195 | | |
196 | 0 | inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } |
197 | 0 | inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } |
198 | | |
199 | 0 | inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } |
200 | 0 | inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } |
201 | | |
202 | 0 | inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } |
203 | 0 | inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } |
204 | | |
205 | 0 | inline constexpr bool IsLittleEndian() { return true; } |
206 | | |
207 | | #elif defined ABSL_IS_BIG_ENDIAN |
208 | | |
209 | | inline uint16_t FromHost16(uint16_t x) { return x; } |
210 | | inline uint16_t ToHost16(uint16_t x) { return x; } |
211 | | |
212 | | inline uint32_t FromHost32(uint32_t x) { return x; } |
213 | | inline uint32_t ToHost32(uint32_t x) { return x; } |
214 | | |
215 | | inline uint64_t FromHost64(uint64_t x) { return x; } |
216 | | inline uint64_t ToHost64(uint64_t x) { return x; } |
217 | | |
218 | | inline constexpr bool IsLittleEndian() { return false; } |
219 | | |
220 | | #endif /* ENDIAN */ |
221 | | |
222 | 0 | inline uint8_t FromHost(uint8_t x) { return x; } |
223 | 0 | inline uint16_t FromHost(uint16_t x) { return FromHost16(x); } |
224 | 0 | inline uint32_t FromHost(uint32_t x) { return FromHost32(x); } |
225 | 0 | inline uint64_t FromHost(uint64_t x) { return FromHost64(x); } |
226 | 0 | inline uint8_t ToHost(uint8_t x) { return x; } |
227 | 0 | inline uint16_t ToHost(uint16_t x) { return ToHost16(x); } |
228 | 0 | inline uint32_t ToHost(uint32_t x) { return ToHost32(x); } |
229 | 0 | inline uint64_t ToHost(uint64_t x) { return ToHost64(x); } |
230 | | |
231 | 0 | inline int8_t FromHost(int8_t x) { return x; } |
232 | 0 | inline int16_t FromHost(int16_t x) { |
233 | 0 | return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x))); |
234 | 0 | } |
235 | 0 | inline int32_t FromHost(int32_t x) { |
236 | 0 | return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x))); |
237 | 0 | } |
238 | 0 | inline int64_t FromHost(int64_t x) { |
239 | 0 | return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x))); |
240 | 0 | } |
241 | 0 | inline int8_t ToHost(int8_t x) { return x; } |
242 | 0 | inline int16_t ToHost(int16_t x) { |
243 | 0 | return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x))); |
244 | 0 | } |
245 | 0 | inline int32_t ToHost(int32_t x) { |
246 | 0 | return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x))); |
247 | 0 | } |
248 | 0 | inline int64_t ToHost(int64_t x) { |
249 | 0 | return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x))); |
250 | 0 | } |
251 | | |
252 | | // Functions to do unaligned loads and stores in big-endian order. |
253 | 0 | inline uint16_t Load16(const void *p) { |
254 | 0 | return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); |
255 | 0 | } |
256 | | |
257 | 0 | inline void Store16(void *p, uint16_t v) { |
258 | 0 | ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); |
259 | 0 | } |
260 | | |
261 | 0 | inline uint32_t Load32(const void *p) { |
262 | 0 | return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); |
263 | 0 | } |
264 | | |
265 | 0 | inline void Store32(void *p, uint32_t v) { |
266 | 0 | ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); |
267 | 0 | } |
268 | | |
269 | 0 | inline uint64_t Load64(const void *p) { |
270 | 0 | return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); |
271 | 0 | } |
272 | | |
273 | 0 | inline void Store64(void *p, uint64_t v) { |
274 | 0 | ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); |
275 | 0 | } |
276 | | |
277 | | } // namespace big_endian |
278 | | |
279 | | ABSL_NAMESPACE_END |
280 | | } // namespace absl |
281 | | |
282 | | #endif // ABSL_BASE_INTERNAL_ENDIAN_H_ |