GNU libmicrohttpd  0.9.72
mhd_bithelpers.h
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2019 Karlson2k (Evgeny Grin)
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library.
17  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
26 #ifndef MHD_BITHELPERS_H
27 #define MHD_BITHELPERS_H 1
28 
29 #include "mhd_byteorder.h"
30 #include <stdint.h>
31 #if defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
32  defined(__OPTIMIZE__)))
33 /* Declarations for VC & Clang/C2 built-ins */
34 #include <intrin.h>
35 #endif /* _MSC_FULL_VER */
36 
37 #ifndef __has_builtin
38 /* Avoid precompiler errors with non-clang */
39 # define __has_builtin(x) 0
40 #endif
41 
42 
43 #ifdef MHD_HAVE___BUILTIN_BSWAP32
44 #define _MHD_BYTES_SWAP32(value32) \
45  ((uint32_t) __builtin_bswap32 ((uint32_t) value32))
46 #elif defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
47  defined(__OPTIMIZE__)))
48 /* Clang/C2 may not inline this function if optimizations are turned off. */
49 #ifndef __clang__
50 #pragma intrinsic(_byteswap_ulong)
51 #endif /* ! __clang__ */
52 #define _MHD_BYTES_SWAP32(value32) \
53  ((uint32_t) _byteswap_ulong ((uint32_t) value32))
54 #elif __has_builtin (__builtin_bswap32)
55 #define _MHD_BYTES_SWAP32(value32) \
56  ((uint32_t) __builtin_bswap32 ((uint32_t) value32))
57 #else /* ! __has_builtin(__builtin_bswap32) */
58 #define _MHD_BYTES_SWAP32(value32) \
59  ( (((uint32_t) (value32)) << 24) \
60  | ((((uint32_t) (value32)) & ((uint32_t) 0x0000FF00)) << 8) \
61  | ((((uint32_t) (value32)) & ((uint32_t) 0x00FF0000)) >> 8) \
62  | (((uint32_t) (value32)) >> 24) )
63 #endif /* ! __has_builtin(__builtin_bswap32) */
64 
65 #ifdef MHD_HAVE___BUILTIN_BSWAP64
66 #define _MHD_BYTES_SWAP64(value64) \
67  ((uint64_t) __builtin_bswap64 ((uint64_t) value64))
68 #elif defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
69  defined(__OPTIMIZE__)))
70 /* Clang/C2 may not inline this function if optimizations are turned off. */
71 #ifndef __clang__
72 #pragma intrinsic(_byteswap_uint64)
73 #endif /* ! __clang__ */
74 #define _MHD_BYTES_SWAP64(value64) \
75  ((uint64_t) _byteswap_uint64 ((uint64_t) value64))
76 #elif __has_builtin (__builtin_bswap64)
77 #define _MHD_BYTES_SWAP64(value64) \
78  ((uint64_t) __builtin_bswap64 ((uint64_t) value64))
79 #else /* ! __has_builtin(__builtin_bswap64) */
80 #define _MHD_BYTES_SWAP64(value64) \
81  ( (((uint64_t) (value64)) << 56) \
82  | ((((uint64_t) (value64)) & ((uint64_t) 0x000000000000FF00)) << 40) \
83  | ((((uint64_t) (value64)) & ((uint64_t) 0x0000000000FF0000)) << 24) \
84  | ((((uint64_t) (value64)) & ((uint64_t) 0x00000000FF000000)) << 8) \
85  | ((((uint64_t) (value64)) & ((uint64_t) 0x000000FF00000000)) >> 8) \
86  | ((((uint64_t) (value64)) & ((uint64_t) 0x0000FF0000000000)) >> 24) \
87  | ((((uint64_t) (value64)) & ((uint64_t) 0x00FF000000000000)) >> 40) \
88  | (((uint64_t) (value64)) >> 56) )
89 #endif /* ! __has_builtin(__builtin_bswap64) */
90 
91 
92 /* _MHD_PUT_64BIT_LE (addr, value64)
93  * put native-endian 64-bit value64 to addr
94  * in little-endian mode.
95  */
96 #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
97 #define _MHD_PUT_64BIT_LE(addr, value64) \
98  ((*(uint64_t*) (addr)) = (uint64_t) (value64))
99 #elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
100 #define _MHD_PUT_64BIT_LE(addr, value64) \
101  ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
102 #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
103 /* Endianness was not detected or non-standard like PDP-endian */
104 #define _MHD_PUT_64BIT_LE(addr, value64) do { \
105  ((uint8_t*) (addr))[0] = (uint8_t) ((uint64_t) (value64)); \
106  ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 8); \
107  ((uint8_t*) (addr))[2] = (uint8_t) (((uint64_t) (value64)) >> 16); \
108  ((uint8_t*) (addr))[3] = (uint8_t) (((uint64_t) (value64)) >> 24); \
109  ((uint8_t*) (addr))[4] = (uint8_t) (((uint64_t) (value64)) >> 32); \
110  ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 40); \
111  ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 48); \
112  ((uint8_t*) (addr))[7] = (uint8_t) (((uint64_t) (value64)) >> 56); \
113 } while (0)
114 #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
115 
116 /* _MHD_PUT_32BIT_LE (addr, value32)
117  * put native-endian 32-bit value32 to addr
118  * in little-endian mode.
119  */
120 #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
121 #define _MHD_PUT_32BIT_LE(addr,value32) \
122  ((*(uint32_t*) (addr)) = (uint32_t) (value32))
123 #elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
124 #define _MHD_PUT_32BIT_LE(addr, value32) \
125  ((*(uint32_t*) (addr)) = _MHD_BYTES_SWAP32 (value32))
126 #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
127 /* Endianness was not detected or non-standard like PDP-endian */
128 #define _MHD_PUT_32BIT_LE(addr, value32) do { \
129  ((uint8_t*) (addr))[0] = (uint8_t) ((uint32_t) (value32)); \
130  ((uint8_t*) (addr))[1] = (uint8_t) (((uint32_t) (value32)) >> 8); \
131  ((uint8_t*) (addr))[2] = (uint8_t) (((uint32_t) (value32)) >> 16); \
132  ((uint8_t*) (addr))[3] = (uint8_t) (((uint32_t) (value32)) >> 24); \
133 } while (0)
134 #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
135 
136 /* _MHD_GET_32BIT_LE (addr)
137  * get little-endian 32-bit value storied at addr
138  * and return it in native-endian mode.
139  */
140 #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
141 #define _MHD_GET_32BIT_LE(addr) \
142  (*(const uint32_t*) (addr))
143 #elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
144 #define _MHD_GET_32BIT_LE(addr) \
145  _MHD_BYTES_SWAP32 (*(const uint32_t*) (addr))
146 #else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
147 /* Endianness was not detected or non-standard like PDP-endian */
148 #define _MHD_GET_32BIT_LE(addr) \
149  ( ( (uint32_t) (((const uint8_t*) addr)[0])) \
150  | (((uint32_t) (((const uint8_t*) addr)[1])) << 8) \
151  | (((uint32_t) (((const uint8_t*) addr)[2])) << 16) \
152  | (((uint32_t) (((const uint8_t*) addr)[3])) << 24) )
153 #endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */
154 
155 
156 /* _MHD_PUT_64BIT_BE (addr, value64)
157  * put native-endian 64-bit value64 to addr
158  * in big-endian mode.
159  */
160 #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
161 #define _MHD_PUT_64BIT_BE(addr, value64) \
162  ((*(uint64_t*) (addr)) = (uint64_t) (value64))
163 #elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
164 #define _MHD_PUT_64BIT_BE(addr, value64) \
165  ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
166 #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
167 /* Endianness was not detected or non-standard like PDP-endian */
168 #define _MHD_PUT_64BIT_BE(addr, value64) do { \
169  ((uint8_t*) (addr))[7] = (uint8_t) ((uint64_t) (value64)); \
170  ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 8); \
171  ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 16); \
172  ((uint8_t*) (addr))[4] = (uint8_t) (((uint64_t) (value64)) >> 24); \
173  ((uint8_t*) (addr))[3] = (uint8_t) (((uint64_t) (value64)) >> 32); \
174  ((uint8_t*) (addr))[2] = (uint8_t) (((uint64_t) (value64)) >> 40); \
175  ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 48); \
176  ((uint8_t*) (addr))[0] = (uint8_t) (((uint64_t) (value64)) >> 56); \
177 } while (0)
178 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
179 
180 /* _MHD_PUT_32BIT_BE (addr, value32)
181  * put native-endian 32-bit value32 to addr
182  * in big-endian mode.
183  */
184 #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
185 #define _MHD_PUT_32BIT_BE(addr, value32) \
186  ((*(uint32_t*) (addr)) = (uint32_t) (value32))
187 #elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
188 #define _MHD_PUT_32BIT_BE(addr, value32) \
189  ((*(uint32_t*) (addr)) = _MHD_BYTES_SWAP32 (value32))
190 #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
191 /* Endianness was not detected or non-standard like PDP-endian */
192 #define _MHD_PUT_32BIT_BE(addr, value32) do { \
193  ((uint8_t*) (addr))[3] = (uint8_t) ((uint32_t) (value32)); \
194  ((uint8_t*) (addr))[2] = (uint8_t) (((uint32_t) (value32)) >> 8); \
195  ((uint8_t*) (addr))[1] = (uint8_t) (((uint32_t) (value32)) >> 16); \
196  ((uint8_t*) (addr))[0] = (uint8_t) (((uint32_t) (value32)) >> 24); \
197 } while (0)
198 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
199 
200 /* _MHD_GET_32BIT_BE (addr)
201  * get big-endian 32-bit value storied at addr
202  * and return it in native-endian mode.
203  */
204 #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
205 #define _MHD_GET_32BIT_BE(addr) \
206  (*(const uint32_t*) (addr))
207 #elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
208 #define _MHD_GET_32BIT_BE(addr) \
209  _MHD_BYTES_SWAP32 (*(const uint32_t*) (addr))
210 #else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
211 /* Endianness was not detected or non-standard like PDP-endian */
212 #define _MHD_GET_32BIT_BE(addr) \
213  ( (((uint32_t) (((const uint8_t*) addr)[0])) << 24) \
214  | (((uint32_t) (((const uint8_t*) addr)[1])) << 16) \
215  | (((uint32_t) (((const uint8_t*) addr)[2])) << 8) \
216  | ((uint32_t) (((const uint8_t*) addr)[3])) )
217 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
218 
219 
224 #if defined(_MSC_FULL_VER) && (! defined(__clang__) || (defined(__c2__) && \
225  defined(__OPTIMIZE__)))
226 /* Clang/C2 do not inline this function if optimizations are turned off. */
227 #ifndef __clang__
228 #pragma intrinsic(_rotr)
229 #endif /* ! __clang__ */
230 #define _MHD_ROTR32(value32, bits) \
231  ((uint32_t) _rotr ((uint32_t) (value32),(bits)))
232 #else /* ! _MSC_FULL_VER */
233 /* Defined in form which modern compiler could optimize. */
234 #define _MHD_ROTR32(value32, bits) \
235  (((uint32_t) (value32)) >> (bits) | ((uint32_t) (value32)) << (32 - bits))
236 #endif /* ! _MSC_FULL_VER */
237 
238 
239 #endif /* ! MHD_BITHELPERS_H */
macro definitions for host byte order