MPD  0.20.15
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 #elif defined(__BYTE_ORDER__)
56 /* GCC-specific macros */
57 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
58 # define IS_LITTLE_ENDIAN true
59 # define IS_BIG_ENDIAN false
60 # else
61 # define IS_LITTLE_ENDIAN false
62 # define IS_BIG_ENDIAN true
63 # endif
64 #else
65 /* generic compile-time check */
66 # include <endian.h>
67 # if __BYTE_ORDER == __LITTLE_ENDIAN
68 # define IS_LITTLE_ENDIAN true
69 # define IS_BIG_ENDIAN false
70 # else
71 # define IS_LITTLE_ENDIAN false
72 # define IS_BIG_ENDIAN true
73 # endif
74 #endif
75 
76 static inline constexpr bool
78 {
79  return IS_LITTLE_ENDIAN;
80 }
81 
82 static inline constexpr bool
84 {
85  return IS_BIG_ENDIAN;
86 }
87 
88 static inline constexpr uint16_t
89 GenericByteSwap16(uint16_t value)
90 {
91  return (value >> 8) | (value << 8);
92 }
93 
94 static inline constexpr uint32_t
95 GenericByteSwap32(uint32_t value)
96 {
97  return (value >> 24) | ((value >> 8) & 0x0000ff00) |
98  ((value << 8) & 0x00ff0000) | (value << 24);
99 }
100 
101 static inline constexpr uint64_t
102 GenericByteSwap64(uint64_t value)
103 {
104  return uint64_t(GenericByteSwap32(uint32_t(value >> 32)))
105  | (uint64_t(GenericByteSwap32(value)) << 32);
106 }
107 
108 static inline constexpr uint16_t
109 ByteSwap16(uint16_t value)
110 {
111 #if CLANG_OR_GCC_VERSION(4,8)
112  return __builtin_bswap16(value);
113 #else
114  return GenericByteSwap16(value);
115 #endif
116 }
117 
118 static inline constexpr uint32_t
119 ByteSwap32(uint32_t value)
120 {
121 #if CLANG_OR_GCC_VERSION(4,3)
122  return __builtin_bswap32(value);
123 #else
124  return GenericByteSwap32(value);
125 #endif
126 }
127 
128 static inline constexpr uint64_t
129 ByteSwap64(uint64_t value)
130 {
131 #if CLANG_OR_GCC_VERSION(4,3)
132  return __builtin_bswap64(value);
133 #else
134  return GenericByteSwap64(value);
135 #endif
136 }
137 
141 static inline constexpr uint16_t
142 FromBE16(uint16_t value)
143 {
144  return IsBigEndian() ? value : ByteSwap16(value);
145 }
146 
150 static inline constexpr uint32_t
151 FromBE32(uint32_t value)
152 {
153  return IsBigEndian() ? value : ByteSwap32(value);
154 }
155 
159 static inline constexpr uint64_t
160 FromBE64(uint64_t value)
161 {
162  return IsBigEndian() ? value : ByteSwap64(value);
163 }
164 
168 static inline constexpr uint16_t
169 FromLE16(uint16_t value)
170 {
171  return IsLittleEndian() ? value : ByteSwap16(value);
172 }
173 
177 static inline constexpr uint32_t
178 FromLE32(uint32_t value)
179 {
180  return IsLittleEndian() ? value : ByteSwap32(value);
181 }
182 
186 static inline constexpr uint64_t
187 FromLE64(uint64_t value)
188 {
189  return IsLittleEndian() ? value : ByteSwap64(value);
190 }
191 
195 static inline constexpr uint16_t
196 ToBE16(uint16_t value)
197 {
198  return IsBigEndian() ? value : ByteSwap16(value);
199 }
200 
204 static inline constexpr uint32_t
205 ToBE32(uint32_t value)
206 {
207  return IsBigEndian() ? value : ByteSwap32(value);
208 }
209 
213 static inline constexpr uint64_t
214 ToBE64(uint64_t value)
215 {
216  return IsBigEndian() ? value : ByteSwap64(value);
217 }
218 
222 static inline constexpr uint16_t
223 ToLE16(uint16_t value)
224 {
225  return IsLittleEndian() ? value : ByteSwap16(value);
226 }
227 
231 static inline constexpr uint32_t
232 ToLE32(uint32_t value)
233 {
234  return IsLittleEndian() ? value : ByteSwap32(value);
235 }
236 
240 static inline constexpr uint64_t
241 ToLE64(uint64_t value)
242 {
243  return IsLittleEndian() ? value : ByteSwap64(value);
244 }
245 
246 #endif
static constexpr uint32_t GenericByteSwap32(uint32_t value)
Definition: ByteOrder.hxx:95
static constexpr uint32_t ToBE32(uint32_t value)
Converts a 32bit value from the system&#39;s byte order to big endian.
Definition: ByteOrder.hxx:205
static constexpr uint32_t FromLE32(uint32_t value)
Converts a 32bit value from little endian to the system&#39;s byte order.
Definition: ByteOrder.hxx:178
static constexpr uint16_t ByteSwap16(uint16_t value)
Definition: ByteOrder.hxx:109
static constexpr uint64_t FromLE64(uint64_t value)
Converts a 64bit value from little endian to the system&#39;s byte order.
Definition: ByteOrder.hxx:187
static constexpr bool IsLittleEndian()
Definition: ByteOrder.hxx:77
static constexpr uint16_t ToBE16(uint16_t value)
Converts a 16bit value from the system&#39;s byte order to big endian.
Definition: ByteOrder.hxx:196
static constexpr uint32_t ToLE32(uint32_t value)
Converts a 32bit value from the system&#39;s byte order to little endian.
Definition: ByteOrder.hxx:232
static constexpr uint16_t ToLE16(uint16_t value)
Converts a 16bit value from the system&#39;s byte order to little endian.
Definition: ByteOrder.hxx:223
static constexpr uint32_t ByteSwap32(uint32_t value)
Definition: ByteOrder.hxx:119
static constexpr uint64_t ToLE64(uint64_t value)
Converts a 64bit value from the system&#39;s byte order to little endian.
Definition: ByteOrder.hxx:241
static constexpr uint64_t ToBE64(uint64_t value)
Converts a 64bit value from the system&#39;s byte order to big endian.
Definition: ByteOrder.hxx:214
static constexpr uint64_t GenericByteSwap64(uint64_t value)
Definition: ByteOrder.hxx:102
static constexpr bool IsBigEndian()
Definition: ByteOrder.hxx:83
static constexpr uint16_t FromLE16(uint16_t value)
Converts a 16bit value from little endian to the system&#39;s byte order.
Definition: ByteOrder.hxx:169
static constexpr uint16_t GenericByteSwap16(uint16_t value)
Definition: ByteOrder.hxx:89
static constexpr uint16_t FromBE16(uint16_t value)
Converts a 16bit value from big endian to the system&#39;s byte order.
Definition: ByteOrder.hxx:142
#define IS_BIG_ENDIAN
Definition: ByteOrder.hxx:69
static constexpr uint32_t FromBE32(uint32_t value)
Converts a 32bit value from big endian to the system&#39;s byte order.
Definition: ByteOrder.hxx:151
static constexpr uint64_t ByteSwap64(uint64_t value)
Definition: ByteOrder.hxx:129
static constexpr uint64_t FromBE64(uint64_t value)
Converts a 64bit value from big endian to the system&#39;s byte order.
Definition: ByteOrder.hxx:160
#define IS_LITTLE_ENDIAN
Definition: ByteOrder.hxx:68