/src/mcl/include/cybozu/endian.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | /** |
4 | | @file |
5 | | @brief deal with big and little endian |
6 | | |
7 | | @author MITSUNARI Shigeo(@herumi) |
8 | | */ |
9 | | #include <cybozu/inttype.hpp> |
10 | | #include <string.h> |
11 | | |
12 | | namespace cybozu { |
13 | | |
14 | | #ifdef _MSC_VER |
15 | | inline uint16_t byteSwap(uint16_t x) { return _byteswap_ushort(x); } |
16 | | inline uint32_t byteSwap(uint32_t x) { return _byteswap_ulong(x); } |
17 | | inline uint64_t byteSwap(uint64_t x) { return _byteswap_uint64(x); } |
18 | | #else |
19 | | #if (((__GNUC__) << 16) + (__GNUC_MINOR__)) >= ((4 << 16) + 8) |
20 | | inline uint16_t byteSwap(uint16_t x) { return __builtin_bswap16(x); } |
21 | | #else |
22 | 748 | inline uint16_t byteSwap(uint16_t x) { return (x >> 8) | (x << 8); } |
23 | | #endif |
24 | 304k | inline uint32_t byteSwap(uint32_t x) { return __builtin_bswap32(x); } |
25 | 6.25k | inline uint64_t byteSwap(uint64_t x) { return __builtin_bswap64(x); } |
26 | | #endif |
27 | | |
28 | | /** |
29 | | get 16bit integer as little endian |
30 | | @param src [in] pointer |
31 | | */ |
32 | | inline uint16_t Get16bitAsLE(const void *src) |
33 | 0 | { |
34 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
35 | 0 | uint16_t x; |
36 | 0 | memcpy(&x, src, sizeof(x)); |
37 | 0 | return x; |
38 | 0 | #else |
39 | 0 | const uint8_t *p = static_cast<const uint8_t *>(src); |
40 | 0 | return p[0] | (p[1] << 8); |
41 | 0 | #endif |
42 | 0 | } |
43 | | |
44 | | /** |
45 | | get 32bit integer as little endian |
46 | | @param src [in] pointer |
47 | | */ |
48 | | inline uint32_t Get32bitAsLE(const void *src) |
49 | 0 | { |
50 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
51 | 0 | uint32_t x; |
52 | 0 | memcpy(&x, src, sizeof(x)); |
53 | 0 | return x; |
54 | 0 | #else |
55 | 0 | const uint8_t *p = static_cast<const uint8_t *>(src); |
56 | 0 | return Get16bitAsLE(p) | (static_cast<uint32_t>(Get16bitAsLE(p + 2)) << 16); |
57 | 0 | #endif |
58 | 0 | } |
59 | | |
60 | | /** |
61 | | get 64bit integer as little endian |
62 | | @param src [in] pointer |
63 | | */ |
64 | | inline uint64_t Get64bitAsLE(const void *src) |
65 | 0 | { |
66 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
67 | 0 | uint64_t x; |
68 | 0 | memcpy(&x, src, sizeof(x)); |
69 | 0 | return x; |
70 | 0 | #else |
71 | 0 | const uint8_t *p = static_cast<const uint8_t *>(src); |
72 | 0 | return Get32bitAsLE(p) | (static_cast<uint64_t>(Get32bitAsLE(p + 4)) << 32); |
73 | 0 | #endif |
74 | 0 | } |
75 | | |
76 | | /** |
77 | | get 16bit integer as bit endian |
78 | | @param src [in] pointer |
79 | | */ |
80 | | inline uint16_t Get16bitAsBE(const void *src) |
81 | 0 | { |
82 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
83 | 0 | uint16_t x; |
84 | 0 | memcpy(&x, src, sizeof(x)); |
85 | 0 | return byteSwap(x); |
86 | 0 | #else |
87 | 0 | const uint8_t *p = static_cast<const uint8_t *>(src); |
88 | 0 | return p[1] | (p[0] << 8); |
89 | 0 | #endif |
90 | 0 | } |
91 | | |
92 | | /** |
93 | | get 32bit integer as bit endian |
94 | | @param src [in] pointer |
95 | | */ |
96 | | inline uint32_t Get32bitAsBE(const void *src) |
97 | 254k | { |
98 | 254k | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
99 | 254k | uint32_t x; |
100 | 254k | memcpy(&x, src, sizeof(x)); |
101 | 254k | return byteSwap(x); |
102 | | #else |
103 | | const uint8_t *p = static_cast<const uint8_t *>(src); |
104 | | return Get16bitAsBE(p + 2) | (static_cast<uint32_t>(Get16bitAsBE(p)) << 16); |
105 | | #endif |
106 | 254k | } |
107 | | |
108 | | /** |
109 | | get 64bit integer as big endian |
110 | | @param src [in] pointer |
111 | | */ |
112 | | inline uint64_t Get64bitAsBE(const void *src) |
113 | 0 | { |
114 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
115 | 0 | uint64_t x; |
116 | 0 | memcpy(&x, src, sizeof(x)); |
117 | 0 | return byteSwap(x); |
118 | | #else |
119 | | const uint8_t *p = static_cast<const uint8_t *>(src); |
120 | | return Get32bitAsBE(p + 4) | (static_cast<uint64_t>(Get32bitAsBE(p)) << 32); |
121 | | #endif |
122 | 0 | } |
123 | | |
124 | | /** |
125 | | set 16bit integer as little endian |
126 | | @param src [out] pointer |
127 | | @param x [in] integer |
128 | | */ |
129 | | inline void Set16bitAsLE(void *src, uint16_t x) |
130 | 0 | { |
131 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
132 | 0 | memcpy(src, &x, sizeof(x)); |
133 | 0 | #else |
134 | 0 | uint8_t *p = static_cast<uint8_t *>(src); |
135 | 0 | p[0] = static_cast<uint8_t>(x); |
136 | 0 | p[1] = static_cast<uint8_t>(x >> 8); |
137 | 0 | #endif |
138 | 0 | } |
139 | | /** |
140 | | set 32bit integer as little endian |
141 | | @param src [out] pointer |
142 | | @param x [in] integer |
143 | | */ |
144 | | inline void Set32bitAsLE(void *src, uint32_t x) |
145 | 0 | { |
146 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
147 | 0 | memcpy(src, &x, sizeof(x)); |
148 | 0 | #else |
149 | 0 | uint8_t *p = static_cast<uint8_t *>(src); |
150 | 0 | p[0] = static_cast<uint8_t>(x); |
151 | 0 | p[1] = static_cast<uint8_t>(x >> 8); |
152 | 0 | p[2] = static_cast<uint8_t>(x >> 16); |
153 | 0 | p[3] = static_cast<uint8_t>(x >> 24); |
154 | 0 | #endif |
155 | 0 | } |
156 | | /** |
157 | | set 64bit integer as little endian |
158 | | @param src [out] pointer |
159 | | @param x [in] integer |
160 | | */ |
161 | | inline void Set64bitAsLE(void *src, uint64_t x) |
162 | 0 | { |
163 | 0 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
164 | 0 | memcpy(src, &x, sizeof(x)); |
165 | 0 | #else |
166 | 0 | uint8_t *p = static_cast<uint8_t *>(src); |
167 | 0 | Set32bitAsLE(p, static_cast<uint32_t>(x)); |
168 | 0 | Set32bitAsLE(p + 4, static_cast<uint32_t>(x >> 32)); |
169 | 0 | #endif |
170 | 0 | } |
171 | | /** |
172 | | set 16bit integer as big endian |
173 | | @param src [out] pointer |
174 | | @param x [in] integer |
175 | | */ |
176 | | inline void Set16bitAsBE(void *src, uint16_t x) |
177 | 748 | { |
178 | 748 | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
179 | 748 | x = byteSwap(x); |
180 | 748 | memcpy(src, &x, sizeof(x)); |
181 | | #else |
182 | | uint8_t *p = static_cast<uint8_t *>(src); |
183 | | p[0] = static_cast<uint8_t>(x >> 8); |
184 | | p[1] = static_cast<uint8_t>(x); |
185 | | #endif |
186 | 748 | } |
187 | | /** |
188 | | set 32bit integer as big endian |
189 | | @param src [out] pointer |
190 | | @param x [in] integer |
191 | | */ |
192 | | inline void Set32bitAsBE(void *src, uint32_t x) |
193 | 50.0k | { |
194 | 50.0k | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
195 | 50.0k | x = byteSwap(x); |
196 | 50.0k | memcpy(src, &x, sizeof(x)); |
197 | | #else |
198 | | uint8_t *p = static_cast<uint8_t *>(src); |
199 | | p[0] = static_cast<uint8_t>(x >> 24); |
200 | | p[1] = static_cast<uint8_t>(x >> 16); |
201 | | p[2] = static_cast<uint8_t>(x >> 8); |
202 | | p[3] = static_cast<uint8_t>(x); |
203 | | #endif |
204 | 50.0k | } |
205 | | /** |
206 | | set 64bit integer as big endian |
207 | | @param src [out] pointer |
208 | | @param x [in] integer |
209 | | */ |
210 | | inline void Set64bitAsBE(void *src, uint64_t x) |
211 | 6.25k | { |
212 | 6.25k | #if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE |
213 | 6.25k | x = byteSwap(x); |
214 | 6.25k | memcpy(src, &x, sizeof(x)); |
215 | | #else |
216 | | uint8_t *p = static_cast<uint8_t *>(src); |
217 | | Set32bitAsBE(p, static_cast<uint32_t>(x >> 32)); |
218 | | Set32bitAsBE(p + 4, static_cast<uint32_t>(x)); |
219 | | #endif |
220 | 6.25k | } |
221 | | |
222 | | } // cybozu |