android/GlueIOIOPort: fix spurious errors after IOIO baud rate change
[xcsoar.git] / src / OS / ByteOrder.hpp
blob415011e0a33907eb5b753e5be70c87b1de1aba93
1 /*
2 * Copyright (C) 2011 Max Kellermann <max@duempel.org>,
3 * Tobias Bieniek <Tobias.Bieniek@gmx.de>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef XCSOAR_BYTE_ORDER_HPP
32 #define XCSOAR_BYTE_ORDER_HPP
34 #include "Compiler.h"
36 #include <stdint.h>
38 #ifdef __linux__
39 #include <features.h>
41 #if defined(ANDROID) || (defined(__GLIBC__) && ((__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 9) || __GLIBC__ >= 3))
42 /* the byte swap macros were added in glibc 2.9 */
43 #define HAVE_BYTESWAP_H
44 #include <byteswap.h>
45 #include <endian.h>
46 #endif
47 #endif /* !__linux__ */
49 /* x86 always allows unaligned access */
50 #if defined(__i386__) || defined(__x86_64__) || \
51 /* ARM has it from ARMv6 on */ \
52 defined(__ARM_ARCH_6__) || \
53 defined(__ARM_ARCH_7__) || \
54 defined(__ARM_ARCH_7A__) || \
55 /* _M_ARM is the Microsoft way of checking the ARM generation \
56 (supported by mingw32ce) */ \
57 (defined(_M_ARM) && _M_ARM >= 6)
58 #ifndef FORCE_ALIGNED_READ_WRITE
59 #define CAN_READ_WRITE_UNALIGNED
60 #endif
61 #endif
63 gcc_const
64 static inline uint16_t
65 ByteSwap16(uint16_t value)
67 #ifdef HAVE_BYTESWAP_H
68 return bswap_16(value);
69 #else
70 return (value >> 8) | (value << 8);
71 #endif
74 gcc_const
75 static inline uint32_t
76 ByteSwap32(uint32_t value)
78 #ifdef HAVE_BYTESWAP_H
79 return bswap_32(value);
80 #else
81 return (value >> 24) | ((value >> 8) & 0x0000ff00) |
82 ((value << 8) & 0x00ff0000) | (value << 24);
83 #endif
86 gcc_const
87 static inline uint64_t
88 ByteSwap64(uint64_t value)
90 #ifdef HAVE_BYTESWAP_H
91 return bswap_64(value);
92 #else
93 return uint64_t(ByteSwap32(uint32_t(value >> 32)))
94 | (uint64_t(ByteSwap32(value)) << 32);
95 #endif
98 /**
99 * Converts a 16bit value from big endian to the system's byte order
101 gcc_const
102 static inline uint16_t
103 FromBE16(uint16_t value)
105 #ifdef HAVE_BYTESWAP_H
106 #ifdef __BIONIC__
107 return betoh16(value);
108 #else
109 return be16toh(value);
110 #endif
111 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
112 /* generic little-endian */
113 return ByteSwap16(value);
114 #else
115 /* generic big-endian */
116 return value;
117 #endif
121 * Converts a 32bit value from big endian to the system's byte order
123 gcc_const
124 static inline uint32_t
125 FromBE32(uint32_t value)
127 #ifdef HAVE_BYTESWAP_H
128 #ifdef __BIONIC__
129 return betoh32(value);
130 #else
131 return be32toh(value);
132 #endif
133 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
134 /* generic little-endian */
135 return ByteSwap32(value);
136 #else
137 /* generic big-endian */
138 return value;
139 #endif
143 * Converts a 64bit value from big endian to the system's byte order
145 gcc_const
146 static inline uint64_t
147 FromBE64(uint64_t value)
149 #ifdef HAVE_BYTESWAP_H
150 #ifdef __BIONIC__
151 return betoh64(value);
152 #else
153 return be64toh(value);
154 #endif
155 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
156 /* generic little-endian */
157 return ByteSwap64(value);
158 #else
159 /* generic big-endian */
160 return value;
161 #endif
165 * Converts a 16bit value from little endian to the system's byte order
167 gcc_const
168 static inline uint16_t
169 FromLE16(uint16_t value)
171 #ifdef HAVE_BYTESWAP_H
172 #ifdef __BIONIC__
173 return letoh16(value);
174 #else
175 return le16toh(value);
176 #endif
177 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
178 /* generic little-endian */
179 return value;
180 #else
181 /* generic big-endian */
182 return ByteSwap16(value);
183 #endif
187 * Converts a 32bit value from little endian to the system's byte order
189 gcc_const
190 static inline uint32_t
191 FromLE32(uint32_t value)
193 #ifdef HAVE_BYTESWAP_H
194 #ifdef __BIONIC__
195 return letoh32(value);
196 #else
197 return le32toh(value);
198 #endif
199 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
200 /* generic little-endian */
201 return value;
202 #else
203 /* generic big-endian */
204 return ByteSwap32(value);
205 #endif
209 * Converts a 64bit value from little endian to the system's byte order
211 gcc_const
212 static inline uint64_t
213 FromLE64(uint64_t value)
215 #ifdef HAVE_BYTESWAP_H
216 #ifdef __BIONIC__
217 return letoh64(value);
218 #else
219 return le64toh(value);
220 #endif
221 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
222 /* generic little-endian */
223 return value;
224 #else
225 /* generic big-endian */
226 return ByteSwap64(value);
227 #endif
231 * Converts a 16bit value from the system's byte order to big endian
233 gcc_const
234 static inline uint16_t
235 ToBE16(uint16_t value)
237 #ifdef HAVE_BYTESWAP_H
238 return htobe16(value);
239 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
240 /* generic little-endian */
241 return ByteSwap16(value);
242 #else
243 /* generic big-endian */
244 return value;
245 #endif
249 * Converts a 32bit value from the system's byte order to big endian
251 gcc_const
252 static inline uint32_t
253 ToBE32(uint32_t value)
255 #ifdef HAVE_BYTESWAP_H
256 return htobe32(value);
257 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
258 /* generic little-endian */
259 return ByteSwap32(value);
260 #else
261 /* generic big-endian */
262 return value;
263 #endif
267 * Converts a 64bit value from the system's byte order to big endian
269 gcc_const
270 static inline uint64_t
271 ToBE64(uint64_t value)
273 #ifdef HAVE_BYTESWAP_H
274 return htobe64(value);
275 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
276 /* generic little-endian */
277 return ByteSwap64(value);
278 #else
279 /* generic big-endian */
280 return value;
281 #endif
285 * Converts a 16bit value from the system's byte order to little endian
287 gcc_const
288 static inline uint16_t
289 ToLE16(uint16_t value)
291 #ifdef HAVE_BYTESWAP_H
292 return htole16(value);
293 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
294 /* generic little-endian */
295 return value;
296 #else
297 /* generic big-endian */
298 return ByteSwap16(value);
299 #endif
303 * Converts a 32bit value from the system's byte order to little endian
305 gcc_const
306 static inline uint32_t
307 ToLE32(uint32_t value)
309 #ifdef HAVE_BYTESWAP_H
310 return htole32(value);
311 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
312 /* generic little-endian */
313 return value;
314 #else
315 /* generic big-endian */
316 return ByteSwap32(value);
317 #endif
321 * Converts a 64bit value from the system's byte order to little endian
323 gcc_const
324 static inline uint64_t
325 ToLE64(uint64_t value)
327 #ifdef HAVE_BYTESWAP_H
328 return htole64(value);
329 #elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
330 /* generic little-endian */
331 return value;
332 #else
333 /* generic big-endian */
334 return ByteSwap64(value);
335 #endif
338 gcc_pure
339 static inline uint16_t
340 ReadUnalignedLE16(const uint16_t *p)
342 #ifdef CAN_READ_WRITE_UNALIGNED
343 return FromLE16(*p);
344 #else
345 const uint8_t *c = (const uint8_t *)p;
346 return c[0] | (c[1] << 8);
347 #endif
350 gcc_pure
351 static inline uint16_t
352 ReadUnalignedBE16(const uint16_t *p)
354 #ifdef CAN_READ_WRITE_UNALIGNED
355 return FromBE16(*p);
356 #else
357 const uint8_t *c = (const uint8_t *)p;
358 return c[1] | (c[0] << 8);
359 #endif
362 static inline void
363 WriteUnalignedLE16(uint16_t *p, uint16_t value)
365 #ifdef CAN_READ_WRITE_UNALIGNED
366 *p = ToLE16(value);
367 #else
368 uint8_t *c = (uint8_t *)p;
369 c[0] = value;
370 c[1] = value >> 8;
371 #endif
374 static inline void
375 WriteUnalignedBE16(uint16_t *p, uint16_t value)
377 #ifdef CAN_READ_WRITE_UNALIGNED
378 *p = ToBE16(value);
379 #else
380 uint8_t *c = (uint8_t *)p;
381 c[0] = value >> 8;
382 c[1] = value;
383 #endif
386 gcc_pure
387 static inline uint32_t
388 ReadUnalignedLE32(const uint32_t *p)
390 #ifdef CAN_READ_WRITE_UNALIGNED
391 return FromLE32(*p);
392 #else
393 const uint8_t *c = (const uint8_t *)p;
394 return c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
395 #endif
398 gcc_pure
399 static inline uint32_t
400 ReadUnalignedBE32(const uint32_t *p)
402 #ifdef CAN_READ_WRITE_UNALIGNED
403 return FromBE32(*p);
404 #else
405 const uint8_t *c = (const uint8_t *)p;
406 return c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
407 #endif
410 #endif