libtins
4.5
Toggle main menu visibility
Loading...
Searching...
No Matches
include
tins
endianness.h
1
/*
2
* Copyright (c) 2017, Matias Fontanini
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are
7
* met:
8
*
9
* * Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* * Redistributions in binary form must reproduce the above
12
* copyright notice, this list of conditions and the following disclaimer
13
* in the 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 FOR
19
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
*
28
*/
29
30
#ifndef TINS_ENDIANNESS_H
31
#define TINS_ENDIANNESS_H
32
33
#include <stdint.h>
34
#include <tins/macros.h>
35
36
#if defined(__APPLE__)
37
#include <sys/types.h>
38
#define TINS_IS_LITTLE_ENDIAN (BYTE_ORDER == LITTLE_ENDIAN)
39
#define TINS_IS_BIG_ENDIAN (BYTE_ORDER == BIG_ENDIAN)
40
#elif defined(BSD)
41
#include <sys/endian.h>
42
#define TINS_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN)
43
#define TINS_IS_BIG_ENDIAN (_BYTE_ORDER == _BIG_ENDIAN)
44
#elif defined(_WIN32)
45
#include <cstdlib>
46
// Assume windows == little endian. fixme later
47
#define TINS_IS_LITTLE_ENDIAN 1
48
#define TINS_IS_BIG_ENDIAN 0
49
#else
50
#include <endian.h>
51
#define TINS_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
52
#define TINS_IS_BIG_ENDIAN (__BYTE_ORDER == __BIG_ENDIAN)
53
#endif
54
55
// Define macros to swap bytes using compiler intrinsics when possible
56
#if defined(_MSC_VER)
57
#define TINS_BYTE_SWAP_16(data) _byteswap_ushort(data)
58
#define TINS_BYTE_SWAP_32(data) _byteswap_ulong(data)
59
#define TINS_BYTE_SWAP_64(data) _byteswap_uint64(data)
60
#elif defined(TINS_HAVE_GCC_BUILTIN_SWAP)
61
#define TINS_BYTE_SWAP_16(data) __builtin_bswap16(data)
62
#define TINS_BYTE_SWAP_32(data) __builtin_bswap32(data)
63
#define TINS_BYTE_SWAP_64(data) __builtin_bswap64(data)
64
#else
65
#define TINS_NO_BYTE_SWAP_INTRINSICS
66
#endif
67
68
namespace
Tins
{
69
namespace
Endian {
70
77
inline
uint8_t do_change_endian(uint8_t data) {
78
return
data;
79
}
80
86
inline
uint16_t do_change_endian(uint16_t data) {
87
#ifdef TINS_NO_BYTE_SWAP_INTRINSICS
88
return
((data & 0xff00) >> 8) | ((data & 0x00ff) << 8);
89
#else
90
return
TINS_BYTE_SWAP_16(data);
91
#endif
92
}
93
99
inline
uint32_t do_change_endian(uint32_t data) {
100
#ifdef TINS_NO_BYTE_SWAP_INTRINSICS
101
return
(((data & 0xff000000) >> 24) | ((data & 0x00ff0000) >> 8) |
102
((data & 0x0000ff00) << 8) | ((data & 0x000000ff) << 24));
103
#else
104
return
TINS_BYTE_SWAP_32(data);
105
#endif
106
}
107
113
inline
uint64_t do_change_endian(uint64_t data) {
114
#ifdef TINS_NO_BYTE_SWAP_INTRINSICS
115
return
(((uint64_t)(do_change_endian((uint32_t)(data & 0xffffffff))) << 32) |
116
(do_change_endian(((uint32_t)(data >> 32)))));
117
#else
118
return
TINS_BYTE_SWAP_64(data);
119
#endif
120
}
121
125
126
// Helpers to convert
127
template
<
typename
T>
128
struct
conversion_dispatch_helper {
129
static
T dispatch(T data) {
130
return
do_change_endian(data);
131
}
132
};
133
134
135
template
<
size_t
>
136
struct
conversion_dispatcher;
137
138
template
<>
139
struct
conversion_dispatcher<sizeof(uint8_t)>
140
:
public
conversion_dispatch_helper<uint8_t> { };
141
142
template
<>
143
struct
conversion_dispatcher<sizeof(uint16_t)>
144
:
public
conversion_dispatch_helper<uint16_t> { };
145
146
template
<>
147
struct
conversion_dispatcher<sizeof(uint32_t)>
148
:
public
conversion_dispatch_helper<uint32_t> { };
149
150
template
<>
151
struct
conversion_dispatcher<sizeof(uint64_t)>
152
:
public
conversion_dispatch_helper<uint64_t> { };
153
157
165
template
<
typename
T>
166
inline
T change_endian(T data) {
167
return
conversion_dispatcher<
sizeof
(T)>::dispatch(data);
168
}
169
170
#if TINS_IS_LITTLE_ENDIAN
176
template
<
typename
T>
177
inline
T host_to_be(T data) {
178
return
change_endian(data);
179
}
180
188
template
<
typename
T>
189
inline
T host_to_le(T data) {
190
return
data;
191
}
192
198
template
<
typename
T>
199
inline
T be_to_host(T data) {
200
return
change_endian(data);
201
}
202
208
template
<
typename
T>
209
inline
T le_to_host(T data) {
210
return
data;
211
}
212
#elif TINS_IS_BIG_ENDIAN
218
template
<
typename
T>
219
inline
T host_to_be(T data) {
220
return
data;
221
}
222
230
template
<
typename
T>
231
inline
T host_to_le(T data) {
232
return
change_endian(data);
233
}
234
240
template
<
typename
T>
241
inline
T be_to_host(T data) {
242
return
data;
243
}
244
250
template
<
typename
T>
251
inline
T le_to_host(T data) {
252
return
change_endian(data);
253
}
254
#endif
255
256
}
// Endian
257
}
// Tins
258
259
#endif
// TINS_ENDIANNESS_H
Tins
The Tins namespace.
Definition
address_range.h:38
Generated on
for libtins by
1.17.0