GNU libmicrohttpd
0.9.71
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 */
mhd_byteorder.h
macro definitions for host byte order
src
microhttpd
mhd_bithelpers.h
Generated by
1.8.18