FreeRDP
endian.h
1 /*
2  * WinPR: Windows Portable Runtime
3  * Endianness Macros
4  *
5  * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2024 Armin Novak <anovak@thincast.com>
7  * Copyright 2024 Thincast Technologies GmbH
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef WINPR_ENDIAN_H
23 #define WINPR_ENDIAN_H
24 
25 #include <winpr/winpr.h>
26 #include <winpr/wtypes.h>
27 #include <winpr/platform.h>
28 #include <winpr/assert.h>
29 #include <winpr/cast.h>
30 
31 #define WINPR_ENDIAN_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
32 
33 #ifdef __cplusplus
34 extern "C"
35 {
36 #endif
37 
38  static INLINE UINT8 winpr_Data_Get_UINT8(const void* d)
39  {
40  WINPR_ASSERT(d);
41  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
42  return *ptr;
43  }
44 
45  static INLINE INT8 winpr_Data_Get_INT8(const void* d)
46  {
47  WINPR_ASSERT(d);
48  const INT8* ptr = WINPR_ENDIAN_CAST(const INT8*, d);
49  return *ptr;
50  }
51 
52  static INLINE UINT16 winpr_Data_Get_UINT16_NE(const void* d)
53  {
54  const UINT16* ptr = WINPR_ENDIAN_CAST(const UINT16*, d);
55  return *ptr;
56  }
57 
58  static INLINE UINT16 winpr_Data_Get_UINT16(const void* d)
59  {
60  WINPR_ASSERT(d);
61  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
62  const size_t typesize = sizeof(UINT16);
63  UINT16 v = 0;
64  for (size_t x = 0; x < typesize; x++)
65  {
66  v <<= 8;
67  v |= ptr[typesize - x - 1];
68  }
69  return v;
70  }
71 
72  static INLINE UINT16 winpr_Data_Get_UINT16_BE(const void* d)
73  {
74  WINPR_ASSERT(d);
75  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
76  const size_t typesize = sizeof(UINT16);
77  UINT16 v = 0;
78  for (size_t x = 0; x < typesize; x++)
79  {
80  v <<= 8;
81  v |= ptr[x];
82  }
83  return v;
84  }
85 
86  static INLINE INT16 winpr_Data_Get_INT16_NE(const void* d)
87  {
88  WINPR_ASSERT(d);
89  const INT16* ptr = WINPR_ENDIAN_CAST(const INT16*, d);
90  return *ptr;
91  }
92 
93  static INLINE INT16 winpr_Data_Get_INT16(const void* d)
94  {
95  const UINT16 u16 = winpr_Data_Get_UINT16(d);
96  return WINPR_ENDIAN_CAST(INT16, u16);
97  }
98 
99  static INLINE INT16 winpr_Data_Get_INT16_BE(const void* d)
100  {
101  const UINT16 u16 = winpr_Data_Get_UINT16_BE(d);
102  return WINPR_ENDIAN_CAST(INT16, u16);
103  }
104 
105  static INLINE UINT32 winpr_Data_Get_UINT32_NE(const void* d)
106  {
107  WINPR_ASSERT(d);
108  const UINT32* ptr = WINPR_ENDIAN_CAST(const UINT32*, d);
109  return *ptr;
110  }
111 
112  static INLINE UINT32 winpr_Data_Get_UINT32(const void* d)
113  {
114  WINPR_ASSERT(d);
115  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
116  const size_t typesize = sizeof(UINT32);
117  UINT32 v = 0;
118  for (size_t x = 0; x < typesize; x++)
119  {
120  v <<= 8;
121  v |= ptr[typesize - x - 1];
122  }
123  return v;
124  }
125 
126  static INLINE UINT32 winpr_Data_Get_UINT32_BE(const void* d)
127  {
128  WINPR_ASSERT(d);
129  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
130  const size_t typesize = sizeof(UINT32);
131  UINT32 v = 0;
132  for (size_t x = 0; x < typesize; x++)
133  {
134  v <<= 8;
135  v |= ptr[x];
136  }
137  return v;
138  }
139 
140  static INLINE INT32 winpr_Data_Get_INT32_NE(const void* d)
141  {
142  WINPR_ASSERT(d);
143  const INT32* ptr = WINPR_ENDIAN_CAST(const INT32*, d);
144  return *ptr;
145  }
146 
147  static INLINE INT32 winpr_Data_Get_INT32(const void* d)
148  {
149  const UINT32 u32 = winpr_Data_Get_UINT32(d);
150  return WINPR_ENDIAN_CAST(INT32, u32);
151  }
152 
153  static INLINE INT32 winpr_Data_Get_INT32_BE(const void* d)
154  {
155  const UINT32 u32 = winpr_Data_Get_UINT32_BE(d);
156  return WINPR_ENDIAN_CAST(INT32, u32);
157  }
158 
159  static INLINE UINT64 winpr_Data_Get_UINT64_NE(const void* d)
160  {
161  WINPR_ASSERT(d);
162  const UINT64* ptr = WINPR_ENDIAN_CAST(const UINT64*, d);
163  return *ptr;
164  }
165 
166  static INLINE UINT64 winpr_Data_Get_UINT64(const void* d)
167  {
168  WINPR_ASSERT(d);
169  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
170  const size_t typesize = sizeof(UINT64);
171  UINT64 v = 0;
172  for (size_t x = 0; x < typesize; x++)
173  {
174  v <<= 8;
175  v |= ptr[typesize - x - 1];
176  }
177  return v;
178  }
179 
180  static INLINE UINT64 winpr_Data_Get_UINT64_BE(const void* d)
181  {
182  WINPR_ASSERT(d);
183  const UINT8* ptr = WINPR_ENDIAN_CAST(const UINT8*, d);
184  const size_t typesize = sizeof(UINT64);
185  UINT64 v = 0;
186  for (size_t x = 0; x < typesize; x++)
187  {
188  v <<= 8;
189  v |= ptr[x];
190  }
191  return v;
192  }
193 
194  static INLINE INT64 winpr_Data_Get_INT64_NE(const void* d)
195  {
196  WINPR_ASSERT(d);
197  const INT64* b = WINPR_ENDIAN_CAST(const INT64*, d);
198  return *b;
199  }
200 
201  static INLINE INT64 winpr_Data_Get_INT64(const void* d)
202  {
203  const UINT64 u64 = winpr_Data_Get_UINT64(d);
204  return WINPR_ENDIAN_CAST(INT64, u64);
205  }
206 
207  static INLINE INT64 winpr_Data_Get_INT64_BE(const void* d)
208  {
209  const UINT64 u64 = winpr_Data_Get_UINT64_BE(d);
210  return WINPR_ENDIAN_CAST(INT64, u64);
211  }
212 
213  static INLINE void winpr_Data_Write_UINT8_NE(void* d, UINT8 v)
214  {
215  WINPR_ASSERT(d);
216  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
217  *b = v;
218  }
219 
220  static INLINE void winpr_Data_Write_UINT8(void* d, UINT8 v)
221  {
222  WINPR_ASSERT(d);
223  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
224  *b = v;
225  }
226 
227  static INLINE void winpr_Data_Write_UINT16_NE(void* d, UINT16 v)
228  {
229  WINPR_ASSERT(d);
230  UINT16* b = WINPR_ENDIAN_CAST(UINT16*, d);
231  *b = v;
232  }
233 
234  static INLINE void winpr_Data_Write_UINT16(void* d, UINT16 v)
235  {
236  WINPR_ASSERT(d);
237  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
238  b[0] = v & 0xFF;
239  b[1] = (v >> 8) & 0xFF;
240  }
241 
242  static INLINE void winpr_Data_Write_UINT16_BE(void* d, UINT16 v)
243  {
244  WINPR_ASSERT(d);
245  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
246  b[1] = v & 0xFF;
247  b[0] = (v >> 8) & 0xFF;
248  }
249 
250  static INLINE void winpr_Data_Write_UINT32_NE(void* d, UINT32 v)
251  {
252  WINPR_ASSERT(d);
253  UINT32* b = WINPR_ENDIAN_CAST(UINT32*, d);
254  *b = v;
255  }
256 
257  static INLINE void winpr_Data_Write_UINT32(void* d, UINT32 v)
258  {
259  WINPR_ASSERT(d);
260  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
261  winpr_Data_Write_UINT16(b, v & 0xFFFF);
262  winpr_Data_Write_UINT16(b + 2, (v >> 16) & 0xFFFF);
263  }
264 
265  static INLINE void winpr_Data_Write_UINT32_BE(void* d, UINT32 v)
266  {
267  WINPR_ASSERT(d);
268  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
269  winpr_Data_Write_UINT16_BE(b, (v >> 16) & 0xFFFF);
270  winpr_Data_Write_UINT16_BE(b + 2, v & 0xFFFF);
271  }
272 
273  static INLINE void winpr_Data_Write_UINT64_NE(void* d, UINT64 v)
274  {
275  WINPR_ASSERT(d);
276  UINT64* b = WINPR_ENDIAN_CAST(UINT64*, d);
277  *b = v;
278  }
279 
280  static INLINE void winpr_Data_Write_UINT64(void* d, UINT64 v)
281  {
282  WINPR_ASSERT(d);
283  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
284  winpr_Data_Write_UINT32(b, v & 0xFFFFFFFF);
285  winpr_Data_Write_UINT32(b + 4, (v >> 32) & 0xFFFFFFFF);
286  }
287 
288  static INLINE void winpr_Data_Write_UINT64_BE(void* d, UINT64 v)
289  {
290  WINPR_ASSERT(d);
291  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
292  winpr_Data_Write_UINT32_BE(b, (v >> 32) & 0xFFFFFFFF);
293  winpr_Data_Write_UINT32_BE(b + 4, v & 0xFFFFFFFF);
294  }
295 
296  static INLINE void winpr_Data_Write_INT8_NE(void* d, INT8 v)
297  {
298  WINPR_ASSERT(d);
299  INT8* b = WINPR_ENDIAN_CAST(INT8*, d);
300  *b = v;
301  }
302 
303  static INLINE void winpr_Data_Write_INT8(void* d, INT8 v)
304  {
305  WINPR_ASSERT(d);
306  INT8* b = WINPR_ENDIAN_CAST(INT8*, d);
307  *b = v;
308  }
309 
310  static INLINE void winpr_Data_Write_INT16_NE(void* d, INT16 v)
311  {
312  WINPR_ASSERT(d);
313  INT16* b = WINPR_ENDIAN_CAST(INT16*, d);
314  *b = v;
315  }
316 
317  static INLINE void winpr_Data_Write_INT16(void* d, INT16 v)
318  {
319  WINPR_ASSERT(d);
320  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
321  b[0] = v & 0xFF;
322  b[1] = (v >> 8) & 0xFF;
323  }
324 
325  static INLINE void winpr_Data_Write_INT16_BE(void* d, INT16 v)
326  {
327  WINPR_ASSERT(d);
328  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
329  b[1] = v & 0xFF;
330  b[0] = (v >> 8) & 0xFF;
331  }
332 
333  static INLINE void winpr_Data_Write_INT32_NE(void* d, INT32 v)
334  {
335  WINPR_ASSERT(d);
336  INT32* pu = WINPR_ENDIAN_CAST(INT32*, d);
337  *pu = v;
338  }
339 
340  static INLINE void winpr_Data_Write_INT32(void* d, INT32 v)
341  {
342  WINPR_ASSERT(d);
343  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
344  winpr_Data_Write_UINT16(b, v & 0xFFFF);
345  winpr_Data_Write_UINT16(b + 2, (v >> 16) & 0xFFFF);
346  }
347 
348  static INLINE void winpr_Data_Write_INT32_BE(void* d, INT32 v)
349  {
350  WINPR_ASSERT(d);
351  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
352  winpr_Data_Write_UINT16_BE(b, (v >> 16) & 0xFFFF);
353  winpr_Data_Write_UINT16_BE(b + 2, v & 0xFFFF);
354  }
355 
356  static INLINE void winpr_Data_Write_INT64_NE(void* d, INT64 v)
357  {
358  WINPR_ASSERT(d);
359  INT64* pu = WINPR_ENDIAN_CAST(INT64*, d);
360  *pu = v;
361  }
362 
363  static INLINE void winpr_Data_Write_INT64(void* d, INT64 v)
364  {
365  WINPR_ASSERT(d);
366  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
367  winpr_Data_Write_UINT32(b, v & 0xFFFFFFFF);
368  winpr_Data_Write_UINT32(b + 4, (v >> 32) & 0xFFFFFFFF);
369  }
370 
371  static INLINE void winpr_Data_Write_INT64_BE(void* d, INT64 v)
372  {
373  WINPR_ASSERT(d);
374  BYTE* b = WINPR_ENDIAN_CAST(BYTE*, d);
375  winpr_Data_Write_UINT32_BE(b, (v >> 32) & 0xFFFFFFFF);
376  winpr_Data_Write_UINT32_BE(b + 4, v & 0xFFFFFFFF);
377  }
378 
379 #if defined(WINPR_DEPRECATED)
380 #define Data_Read_UINT8_NE(_d, _v) _v = winpr_Data_Get_UINT8(_d)
381 
382 #define Data_Read_UINT8(_d, _v) _v = winpr_Data_Get_UINT8(_d)
383 
384 #define Data_Read_UINT16_NE(_d, _v) _v = winpr_Data_Get_UINT16_NE(_d)
385 
386 #define Data_Read_UINT16(_d, _v) _v = winpr_Data_Get_UINT16(_d)
387 
388 #define Data_Read_UINT16_BE(_d, _v) _v = winpr_Data_Get_UINT16_BE(_d)
389 
390 #define Data_Read_UINT32_NE(_d, _v) _v = winpr_Data_Get_UINT32_NE(_d)
391 
392 #define Data_Read_UINT32(_d, _v) _v = winpr_Data_Get_UINT32(_d)
393 
394 #define Data_Read_UINT32_BE(_d, _v) _v = winpr_Data_Get_UINT32_BE(_d)
395 
396 #define Data_Read_UINT64_NE(_d, _v) _v = winpr_Data_Get_UINT64_NE(_d)
397 
398 #define Data_Read_UINT64(_d, _v) _v = winpr_Data_Get_UINT64(_d)
399 
400 #define Data_Read_UINT64_BE(_d, _v) _v = winpr_Data_Get_UINT64_BE(_d)
401 
402 #define Data_Write_UINT8_NE(_d, _v) winpr_Data_Write_UINT8_NE(_d, _v)
403 
404 #define Data_Write_UINT8(_d, _v) winpr_Data_Write_UINT8(_d, _v)
405 
406 #define Data_Write_UINT16_NE(_d, _v) winpr_Data_Write_UINT16_NE(_d, _v)
407 #define Data_Write_UINT16(_d, _v) winpr_Data_Write_UINT16(_d, _v)
408 
409 #define Data_Write_UINT16_BE(_d, _v) winpr_Data_Write_UINT16_BE(_d, _v)
410 
411 #define Data_Write_UINT32_NE(_d, _v) winpr_Data_Write_UINT32_NE(_d, _v)
412 
413 #define Data_Write_UINT32(_d, _v) winpr_Data_Write_UINT32(_d, _v)
414 
415 #define Data_Write_UINT32_BE(_d, _v) winpr_Data_Write_UINT32_BE(_d, _v)
416 
417 #define Data_Write_UINT64_NE(_d, _v) winpr_Data_Write_UINT64_NE(_d, _v)
418 
419 #define Data_Write_UINT64(_d, _v) winpr_Data_Write_UINT64(_d, _v)
420 
421 #define Data_Write_UINT64_BE(_d, _v) winpr_Data_Write_UINT64_BE(_d, _v)
422 #endif
423 
424 #ifdef __cplusplus
425 }
426 #endif
427 
428 #endif /* WINPR_ENDIAN_H */