MPD  0.20.6
ByteOrder.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2015 Max Kellermann <max.kellermann@gmail.com>,
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef BYTE_ORDER_HXX
31 #define BYTE_ORDER_HXX
32 
33 #include "Compiler.h"
34 
35 #include <stdint.h>
36 
37 #if defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
38 /* well-known little-endian */
39 # define IS_LITTLE_ENDIAN true
40 # define IS_BIG_ENDIAN false
41 #elif defined(__MIPSEB__)
42 /* well-known big-endian */
43 # define IS_LITTLE_ENDIAN false
44 # define IS_BIG_ENDIAN true
45 #elif defined(__APPLE__) || defined(__NetBSD__)
46 /* compile-time check for MacOS */
47 # include <machine/endian.h>
48 # if BYTE_ORDER == LITTLE_ENDIAN
49 # define IS_LITTLE_ENDIAN true
50 # define IS_BIG_ENDIAN false
51 # else
52 # define IS_LITTLE_ENDIAN false
53 # define IS_BIG_ENDIAN true
54 # endif
55 #else
56 /* generic compile-time check */
57 # include <endian.h>
58 # if __BYTE_ORDER == __LITTLE_ENDIAN
59 # define IS_LITTLE_ENDIAN true
60 # define IS_BIG_ENDIAN false
61 # else
62 # define IS_LITTLE_ENDIAN false
63 # define IS_BIG_ENDIAN true
64 # endif
65 #endif
66 
67 static inline constexpr bool
69 {
70  return IS_LITTLE_ENDIAN;
71 }
72 
73 static inline constexpr bool
75 {
76  return IS_BIG_ENDIAN;
77 }
78 
79 static inline constexpr uint16_t
80 GenericByteSwap16(uint16_t value)
81 {
82  return (value >> 8) | (value << 8);
83 }
84 
85 static inline constexpr uint32_t
86 GenericByteSwap32(uint32_t value)
87 {
88  return (value >> 24) | ((value >> 8) & 0x0000ff00) |
89  ((value << 8) & 0x00ff0000) | (value << 24);
90 }
91 
92 static inline constexpr uint64_t
93 GenericByteSwap64(uint64_t value)
94 {
95  return uint64_t(GenericByteSwap32(uint32_t(value >> 32)))
96  | (uint64_t(GenericByteSwap32(value)) << 32);
97 }
98 
99 static inline constexpr uint16_t
100 ByteSwap16(uint16_t value)
101 {
102 #if CLANG_OR_GCC_VERSION(4,8)
103  return __builtin_bswap16(value);
104 #else
105  return GenericByteSwap16(value);
106 #endif
107 }
108 
109 static inline constexpr uint32_t
110 ByteSwap32(uint32_t value)
111 {
112 #if CLANG_OR_GCC_VERSION(4,3)
113  return __builtin_bswap32(value);
114 #else
115  return GenericByteSwap32(value);
116 #endif
117 }
118 
119 static inline constexpr uint64_t
120 ByteSwap64(uint64_t value)
121 {
122 #if CLANG_OR_GCC_VERSION(4,3)
123  return __builtin_bswap64(value);
124 #else
125  return GenericByteSwap64(value);
126 #endif
127 }
128 
132 static inline constexpr uint16_t
133 FromBE16(uint16_t value)
134 {
135  return IsBigEndian() ? value : ByteSwap16(value);
136 }
137 
141 static inline constexpr uint32_t
142 FromBE32(uint32_t value)
143 {
144  return IsBigEndian() ? value : ByteSwap32(value);
145 }
146 
150 static inline constexpr uint64_t
151 FromBE64(uint64_t value)
152 {
153  return IsBigEndian() ? value : ByteSwap64(value);
154 }
155 
159 static inline constexpr uint16_t
160 FromLE16(uint16_t value)
161 {
162  return IsLittleEndian() ? value : ByteSwap16(value);
163 }
164 
168 static inline constexpr uint32_t
169 FromLE32(uint32_t value)
170 {
171  return IsLittleEndian() ? value : ByteSwap32(value);
172 }
173 
177 static inline constexpr uint64_t
178 FromLE64(uint64_t value)
179 {
180  return IsLittleEndian() ? value : ByteSwap64(value);
181 }
182 
186 static inline constexpr uint16_t
187 ToBE16(uint16_t value)
188 {
189  return IsBigEndian() ? value : ByteSwap16(value);
190 }
191 
195 static inline constexpr uint32_t
196 ToBE32(uint32_t value)
197 {
198  return IsBigEndian() ? value : ByteSwap32(value);
199 }
200 
204 static inline constexpr uint64_t
205 ToBE64(uint64_t value)
206 {
207  return IsBigEndian() ? value : ByteSwap64(value);
208 }
209 
213 static inline constexpr uint16_t
214 ToLE16(uint16_t value)
215 {
216  return IsLittleEndian() ? value : ByteSwap16(value);
217 }
218 
222 static inline constexpr uint32_t
223 ToLE32(uint32_t value)
224 {
225  return IsLittleEndian() ? value : ByteSwap32(value);
226 }
227 
231 static inline constexpr uint64_t
232 ToLE64(uint64_t value)
233 {
234  return IsLittleEndian() ? value : ByteSwap64(value);
235 }
236 
237 #endif
static constexpr uint32_t GenericByteSwap32(uint32_t value)
Definition: ByteOrder.hxx:86
static constexpr uint32_t ToBE32(uint32_t value)
Converts a 32bit value from the system's byte order to big endian.
Definition: ByteOrder.hxx:196
static constexpr uint32_t FromLE32(uint32_t value)
Converts a 32bit value from little endian to the system's byte order.
Definition: ByteOrder.hxx:169
static constexpr uint16_t ByteSwap16(uint16_t value)
Definition: ByteOrder.hxx:100
static constexpr uint64_t FromLE64(uint64_t value)
Converts a 64bit value from little endian to the system's byte order.
Definition: ByteOrder.hxx:178
static constexpr bool IsLittleEndian()
Definition: ByteOrder.hxx:68
static constexpr uint16_t ToBE16(uint16_t value)
Converts a 16bit value from the system's byte order to big endian.
Definition: ByteOrder.hxx:187
static constexpr uint32_t ToLE32(uint32_t value)
Converts a 32bit value from the system's byte order to little endian.
Definition: ByteOrder.hxx:223
static constexpr uint16_t ToLE16(uint16_t value)
Converts a 16bit value from the system's byte order to little endian.
Definition: ByteOrder.hxx:214
static constexpr uint32_t ByteSwap32(uint32_t value)
Definition: ByteOrder.hxx:110
static constexpr uint64_t ToLE64(uint64_t value)
Converts a 64bit value from the system's byte order to little endian.
Definition: ByteOrder.hxx:232
static constexpr uint64_t ToBE64(uint64_t value)
Converts a 64bit value from the system's byte order to big endian.
Definition: ByteOrder.hxx:205
static constexpr uint64_t GenericByteSwap64(uint64_t value)
Definition: ByteOrder.hxx:93
static constexpr bool IsBigEndian()
Definition: ByteOrder.hxx:74
static constexpr uint16_t FromLE16(uint16_t value)
Converts a 16bit value from little endian to the system's byte order.
Definition: ByteOrder.hxx:160
static constexpr uint16_t GenericByteSwap16(uint16_t value)
Definition: ByteOrder.hxx:80
static constexpr uint16_t FromBE16(uint16_t value)
Converts a 16bit value from big endian to the system's byte order.
Definition: ByteOrder.hxx:133
#define IS_BIG_ENDIAN
Definition: ByteOrder.hxx:60
static constexpr uint32_t FromBE32(uint32_t value)
Converts a 32bit value from big endian to the system's byte order.
Definition: ByteOrder.hxx:142
static constexpr uint64_t ByteSwap64(uint64_t value)
Definition: ByteOrder.hxx:120
static constexpr uint64_t FromBE64(uint64_t value)
Converts a 64bit value from big endian to the system's byte order.
Definition: ByteOrder.hxx:151
#define IS_LITTLE_ENDIAN
Definition: ByteOrder.hxx:59