Sese Framework  x.y.z
A cross-platform framework
载入中...
搜索中...
未找到
Endian.h
浏览该文件的文档.
1// Copyright 2024 libsese
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
22#pragma once
23
24#include <type_traits>
25#include <cstring>
26#include <cstdint>
27
28enum class EndianType {
29 LITTLE,
30 BIG
31};
32
33#define ByteSwap16(i16) ((i16 & 0x00FF) << 8 | (i16 & 0xFF00) >> 8)
34#define ByteSwap32(i32) ((i32 & 0x000000FF) << 24 | (i32 & 0x0000FF00) << 8 | (i32 & 0x00FF0000) >> 8 | (i32 & 0xFF000000) >> 24)
35#define ByteSwap64(i64) \
36 ((i64 & 0x00000000000000FF) << 56 | \
37 (i64 & 0x000000000000FF00) << 40 | \
38 (i64 & 0x0000000000FF0000) << 24 | \
39 (i64 & 0x00000000FF000000) << 8 | \
40 (i64 & 0x000000FF00000000) >> 8 | \
41 (i64 & 0x0000FF0000000000) >> 24 | \
42 (i64 & 0x00FF000000000000) >> 40 | \
43 (i64 & 0xFF00000000000000) >> 56)
44
45extern "C++" {
46#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(_WIN32)
47#define SESE_LITTLE_ENDIAN
48template<typename T>
49inline T ToBigEndian16(T t) {
50 return ByteSwap16(t);
51}
52
53template<typename T>
54inline T ToBigEndian32(T t) {
55 return ByteSwap32(t);
56}
57
58template<typename T>
59inline T ToBigEndian64(T t) {
60 return ByteSwap64(t);
61}
62
63template<typename T>
64inline T ToLittleEndian16(T t) {
65 return t;
66}
67
68template<typename T>
69inline T ToLittleEndian32(T t) {
70 return t;
71}
72
73template<typename T>
74inline T ToLittleEndian64(T t) {
75 return t;
76}
77
78template<typename T>
79inline T FromBigEndian16(T t) {
80 return ByteSwap16(t);
81}
82
83template<typename T>
84inline T FromBigEndian32(T t) {
85 return ByteSwap32(t);
86}
87
88template<typename T>
89inline T FromBigEndian64(T t) {
90 return ByteSwap64(t);
91}
92
93template<typename T>
94inline T FromLittleEndian16(T t) {
95 return t;
96}
97
98template<typename T>
99inline T FromLittleEndian32(T t) {
100 return t;
101}
102
103template<typename T>
104inline T FromLittleEndian64(T t) {
105 return t;
106}
107
108template<typename T>
109inline
110 typename std::enable_if<sizeof(T) == 2, T>::t
112 return ByteSwap16(t);
113}
114
115template<typename T>
116inline
117 typename std::enable_if<sizeof(T) == 4, T>::t
119 return ByteSwap32(t);
120}
121
122template<typename T>
123inline
124 typename std::enable_if<sizeof(T) == 8, T>::t
126 return ByteSwap64(t);
127}
128
129template<typename T>
130inline T ToLittleEndian(T t) {
131 return t;
132}
133
134template<typename T>
135inline
136 typename std::enable_if<sizeof(T) == 2, T>::t
138 return ByteSwap16(t);
139}
140
141template<typename T>
142inline
143 typename std::enable_if<sizeof(T) == 4, T>::t
145 return ByteSwap32(t);
146}
147
148template<typename T>
149inline
150 typename std::enable_if<sizeof(T) == 8, T>::t
152 return ByteSwap64(t);
153}
154
155template<typename T>
156inline T FromLittleEndian(T t) {
157 return t;
158}
159
160#else
161#define SESE_BIG_ENDIAN
162template<typename T>
163inline T ToBigEndian16(T t) {
164 return t;
165}
166
167template<typename T>
168inline T ToBigEndian32(T t) {
169 return t;
170}
171
172template<typename T>
173inline T ToBigEndian64(T t) {
174 return t;
175}
176
177template<typename T>
178inline T ToLittleEndian16(T t) {
179 return ByteSwap16(t);
180}
181
182template<typename T>
183inline T ToLittleEndian32(T t) {
184 return ByteSwap32(t);
185}
186
187template<typename T>
188inline T ToLittleEndian64(T t) {
189 return ByteSwap64(t);
190}
191
192template<typename T>
193inline T FromBigEndian16(T t) {
194 return t;
195}
196
197template<typename T>
198inline T FromBigEndian32(T t) {
199 return t;
200}
201
202template<typename T>
203inline T FromBigEndian64(T t) {
204 return t;
205}
206
207template<typename T>
208inline T FromLittleEndian16(T t) {
209 return ByteSwap16(t);
210}
211
212template<typename T>
213inline T FromLittleEndian32(T t) {
214 return ByteSwap32(t);
215}
216
217template<typename T>
218inline T FromLittleEndian64(T t) {
219 return ByteSwap64(t);
220}
221
222
223template<typename T>
224inline
225 typename std::enable_if<sizeof(T) == 2, T>::t
226 ToLittleEndian(T t) {
227 return ByteSwap16(t);
228}
229
230template<typename T>
231inline
232 typename std::enable_if<sizeof(T) == 4, T>::t
233 ToLittleEndian(T t) {
234 return ByteSwap32(t);
235}
236
237template<typename T>
238inline
239 typename std::enable_if<sizeof(T) == 8, T>::t
240 ToLittleEndian(T t) {
241 return ByteSwap64(t);
242}
243
244template<typename T>
245inline T ToBigEndian(T t) {
246 return t;
247}
248
249template<typename T>
250inline
251 typename std::enable_if<sizeof(T) == 2, T>::t
252 FromLittleEndian(T t) {
253 return ByteSwap16(t);
254}
255
256template<typename T>
257inline
258 typename std::enable_if<sizeof(T) == 4, T>::t
259 FromLittleEndian(T t) {
260 return ByteSwap32(t);
261}
262
263template<typename T>
264inline
265 typename std::enable_if<sizeof(T) == 8, T>::t
266 FromLittleEndian(T t) {
267 return ByteSwap64(t);
268}
269
270template<typename T>
271inline T FromBigEndian(T t) {
272 return t;
273}
274#endif
275
276#define ASSERT_FLOAT_SIZE static_assert(sizeof(float) == 4, "Float size is not 4 bytes")
277#define ASSERT_DOUBLE_SIZE static_assert(sizeof(double) == 8, "Double size is not 8 bytes")
278
279template<>
280inline float ToBigEndian32(float t) {
282#ifdef SESE_LITTLE_ENDIAN
283 int32_t tmp;
284 memcpy(&tmp, &t, sizeof(float));
286 memcpy(&t, &tmp, sizeof(float));
287#endif
288 return t;
289}
290
291template<>
292inline double ToBigEndian64(double t) {
294#ifdef SESE_LITTLE_ENDIAN
295 int64_t tmp;
296 memcpy(&tmp, &t, sizeof(double));
298 memcpy(&t, &tmp, sizeof(double));
299#endif
300 return t;
301}
302
303template<>
304inline float ToLittleEndian32(float t) {
306#ifdef SESE_BIG_ENDIAN
307 int32_t tmp;
308 memcpy(&tmp, &t, sizeof(float));
310 memcpy(&t, &tmp, sizeof(float));
311#endif
312 return t;
313}
314
315template<>
316inline double ToLittleEndian64(double t) {
318#ifdef SESE_BIG_ENDIAN
319 int64_t tmp;
320 memcpy(&tmp, &t, sizeof(double));
322 memcpy(&t, &tmp, sizeof(double));
323#endif
324 return t;
325}
326
327template<>
328inline float FromBigEndian32(float t) {
330#ifdef SESE_LITTLE_ENDIAN
331 int32_t tmp;
332 memcpy(&tmp, &t, sizeof(float));
334 memcpy(&t, &tmp, sizeof(float));
335#endif
336 return t;
337}
338
339template<>
340inline double FromBigEndian64(double t) {
342#ifdef SESE_LITTLE_ENDIAN
343 int64_t tmp;
344 memcpy(&tmp, &t, sizeof(double));
346 memcpy(&t, &tmp, sizeof(double));
347#endif
348 return t;
349}
350
351template<>
352inline float FromLittleEndian32(float t) {
354#ifdef SESE_BIG_ENDIAN
355 int32_t tmp;
356 memcpy(&tmp, &t, sizeof(float));
358 memcpy(&t, &tmp, sizeof(float));
359#endif
360 return t;
361}
362
363template<>
364inline double FromLittleEndian64(double t) {
366#ifdef SESE_BIG_ENDIAN
367 int64_t tmp;
368 memcpy(&tmp, &t, sizeof(double));
370 memcpy(&t, &tmp, sizeof(double));
371#endif
372 return t;
373}
374
375#undef ASSERT_FLOAT_SIZE
376#undef ASSERT_DOUBLE_SIZE
377}