1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/* libmisc/endian.c - Endian-conversion helpers
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libmisc/macro.h> /* for LM_FORCE_SEMICOLON */
#include <libmisc/endian.h>
#define endian_declare_wrappers(NBIT, ENDIAN) \
uint##NBIT##ENDIAN##_t uint##NBIT##ENDIAN##_marshal(uint##NBIT##_t in) { \
uint##NBIT##ENDIAN##_t out; \
uint##NBIT##ENDIAN##_encode(out.octets, in); \
return out; \
} \
uint##NBIT##_t uint##NBIT##ENDIAN##_unmarshal(uint##NBIT##ENDIAN##_t in) { \
return uint##NBIT##ENDIAN##_decode(in.octets); \
} \
LM_FORCE_SEMICOLON
/* Big endian *****************************************************************/
size_t uint16be_encode(uint8_t *out, uint16_t in) {
out[0] = (uint8_t)((in >> 8) & 0xFF);
out[1] = (uint8_t)((in >> 0) & 0xFF);
return 2;
}
uint16_t uint16be_decode(uint8_t *in) {
return (((uint16_t)(in[0])) << 8)
| (((uint16_t)(in[1])) << 0)
;
}
size_t uint32be_encode(uint8_t *out, uint32_t in) {
out[0] = (uint8_t)((in >> 24) & 0xFF);
out[1] = (uint8_t)((in >> 16) & 0xFF);
out[2] = (uint8_t)((in >> 8) & 0xFF);
out[3] = (uint8_t)((in >> 0) & 0xFF);
return 4;
}
uint32_t uint32be_decode(uint8_t *in) {
return (((uint32_t)(in[0])) << 24)
| (((uint32_t)(in[1])) << 16)
| (((uint32_t)(in[2])) << 8)
| (((uint32_t)(in[3])) << 0)
;
}
size_t uint64be_encode(uint8_t *out, uint64_t in) {
out[0] = (uint8_t)((in >> 56) & 0xFF);
out[1] = (uint8_t)((in >> 48) & 0xFF);
out[2] = (uint8_t)((in >> 40) & 0xFF);
out[3] = (uint8_t)((in >> 32) & 0xFF);
out[4] = (uint8_t)((in >> 24) & 0xFF);
out[5] = (uint8_t)((in >> 16) & 0xFF);
out[6] = (uint8_t)((in >> 8) & 0xFF);
out[7] = (uint8_t)((in >> 0) & 0xFF);
return 8;
}
uint64_t uint64be_decode(uint8_t *in) {
return (((uint64_t)(in[0])) << 56)
| (((uint64_t)(in[1])) << 48)
| (((uint64_t)(in[2])) << 40)
| (((uint64_t)(in[3])) << 32)
| (((uint64_t)(in[4])) << 24)
| (((uint64_t)(in[5])) << 16)
| (((uint64_t)(in[6])) << 8)
| (((uint64_t)(in[7])) << 0)
;
}
endian_declare_wrappers(16, be);
endian_declare_wrappers(32, be);
endian_declare_wrappers(64, be);
/* Little endian **************************************************************/
size_t uint16le_encode(uint8_t *out, uint16_t in) {
out[0] = (uint8_t)((in >> 0) & 0xFF);
out[1] = (uint8_t)((in >> 8) & 0xFF);
return 2;
}
uint16_t uint16le_decode(uint8_t *in) {
return (((uint16_t)(in[0])) << 0)
| (((uint16_t)(in[1])) << 8)
;
}
size_t uint32le_encode(uint8_t *out, uint32_t in) {
out[0] = (uint8_t)((in >> 0) & 0xFF);
out[1] = (uint8_t)((in >> 8) & 0xFF);
out[2] = (uint8_t)((in >> 16) & 0xFF);
out[3] = (uint8_t)((in >> 24) & 0xFF);
return 4;
}
uint32_t uint32le_decode(uint8_t *in) {
return (((uint32_t)(in[0])) << 0)
| (((uint32_t)(in[1])) << 8)
| (((uint32_t)(in[2])) << 16)
| (((uint32_t)(in[3])) << 24)
;
}
size_t uint64le_encode(uint8_t *out, uint64_t in) {
out[0] = (uint8_t)((in >> 0) & 0xFF);
out[1] = (uint8_t)((in >> 8) & 0xFF);
out[2] = (uint8_t)((in >> 16) & 0xFF);
out[3] = (uint8_t)((in >> 24) & 0xFF);
out[4] = (uint8_t)((in >> 32) & 0xFF);
out[5] = (uint8_t)((in >> 40) & 0xFF);
out[6] = (uint8_t)((in >> 48) & 0xFF);
out[7] = (uint8_t)((in >> 56) & 0xFF);
return 8;
}
uint64_t uint64le_decode(uint8_t *in) {
return (((uint64_t)(in[0])) << 0)
| (((uint64_t)(in[1])) << 8)
| (((uint64_t)(in[2])) << 16)
| (((uint64_t)(in[3])) << 24)
| (((uint64_t)(in[4])) << 32)
| (((uint64_t)(in[5])) << 40)
| (((uint64_t)(in[6])) << 48)
| (((uint64_t)(in[7])) << 56)
;
}
endian_declare_wrappers(16, le);
endian_declare_wrappers(32, le);
endian_declare_wrappers(64, le);
|