1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #ifndef _COMMONLIB_ENDIAN_H_
4 #define _COMMONLIB_ENDIAN_H_
5
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <string.h>
9
10 /* Endian agnostic functions working on single byte. */
11
read_ble8(const void * src)12 static inline uint8_t read_ble8(const void *src)
13 {
14 const uint8_t *s = src;
15 return *s;
16 }
17
read_at_ble8(const void * src,size_t offset)18 static inline uint8_t read_at_ble8(const void *src, size_t offset)
19 {
20 const uint8_t *s = src;
21 s += offset;
22 return read_ble8(s);
23 }
24
write_ble8(void * dest,uint8_t val)25 static inline void write_ble8(void *dest, uint8_t val)
26 {
27 *(uint8_t *)dest = val;
28 }
29
write_at_ble8(void * dest,uint8_t val,size_t offset)30 static inline void write_at_ble8(void *dest, uint8_t val, size_t offset)
31 {
32 uint8_t *d = dest;
33 d += offset;
34 write_ble8(d, val);
35 }
36
37 /* Big Endian functions. */
38
read_be8(const void * src)39 static inline uint8_t read_be8(const void *src)
40 {
41 return read_ble8(src);
42 }
43
read_at_be8(const void * src,size_t offset)44 static inline uint8_t read_at_be8(const void *src, size_t offset)
45 {
46 return read_at_ble8(src, offset);
47 }
48
write_be8(void * dest,uint8_t val)49 static inline void write_be8(void *dest, uint8_t val)
50 {
51 write_ble8(dest, val);
52 }
53
write_at_be8(void * dest,uint8_t val,size_t offset)54 static inline void write_at_be8(void *dest, uint8_t val, size_t offset)
55 {
56 write_at_ble8(dest, val, offset);
57 }
58
read_be16(const void * src)59 static inline uint16_t read_be16(const void *src)
60 {
61 const uint8_t *s = src;
62 return (((uint16_t)s[0]) << 8) | (((uint16_t)s[1]) << 0);
63 }
64
read_at_be16(const void * src,size_t offset)65 static inline uint16_t read_at_be16(const void *src, size_t offset)
66 {
67 const uint8_t *s = src;
68 s += offset;
69 return read_be16(s);
70 }
71
write_be16(void * dest,uint16_t val)72 static inline void write_be16(void *dest, uint16_t val)
73 {
74 write_be8(dest, val >> 8);
75 write_at_be8(dest, val >> 0, sizeof(uint8_t));
76 }
77
write_at_be16(void * dest,uint16_t val,size_t offset)78 static inline void write_at_be16(void *dest, uint16_t val, size_t offset)
79 {
80 uint8_t *d = dest;
81 d += offset;
82 write_be16(d, val);
83 }
84
read_be32(const void * src)85 static inline uint32_t read_be32(const void *src)
86 {
87 const uint8_t *s = src;
88 return (((uint32_t)s[0]) << 24) | (((uint32_t)s[1]) << 16) |
89 (((uint32_t)s[2]) << 8) | (((uint32_t)s[3]) << 0);
90 }
91
read_at_be32(const void * src,size_t offset)92 static inline uint32_t read_at_be32(const void *src, size_t offset)
93 {
94 const uint8_t *s = src;
95 s += offset;
96 return read_be32(s);
97 }
98
write_be32(void * dest,uint32_t val)99 static inline void write_be32(void *dest, uint32_t val)
100 {
101 write_be16(dest, val >> 16);
102 write_at_be16(dest, val >> 0, sizeof(uint16_t));
103 }
104
write_at_be32(void * dest,uint32_t val,size_t offset)105 static inline void write_at_be32(void *dest, uint32_t val, size_t offset)
106 {
107 uint8_t *d = dest;
108 d += offset;
109 write_be32(d, val);
110 }
111
read_be64(const void * src)112 static inline uint64_t read_be64(const void *src)
113 {
114 uint64_t val;
115 val = read_be32(src);
116 val <<= 32;
117 val |= read_at_be32(src, sizeof(uint32_t));
118 return val;
119 }
120
read_at_be64(const void * src,size_t offset)121 static inline uint64_t read_at_be64(const void *src, size_t offset)
122 {
123 const uint8_t *s = src;
124 s += offset;
125 return read_be64(s);
126 }
127
write_be64(void * dest,uint64_t val)128 static inline void write_be64(void *dest, uint64_t val)
129 {
130 write_be32(dest, val >> 32);
131 write_at_be32(dest, val >> 0, sizeof(uint32_t));
132 }
133
write_at_be64(void * dest,uint64_t val,size_t offset)134 static inline void write_at_be64(void *dest, uint64_t val, size_t offset)
135 {
136 uint8_t *d = dest;
137 d += offset;
138 write_be64(d, val);
139 }
140
141 /* Little Endian functions. */
142
read_le8(const void * src)143 static inline uint8_t read_le8(const void *src)
144 {
145 return read_ble8(src);
146 }
147
read_at_le8(const void * src,size_t offset)148 static inline uint8_t read_at_le8(const void *src, size_t offset)
149 {
150 return read_at_ble8(src, offset);
151 }
152
write_le8(void * dest,uint8_t val)153 static inline void write_le8(void *dest, uint8_t val)
154 {
155 write_ble8(dest, val);
156 }
157
write_at_le8(void * dest,uint8_t val,size_t offset)158 static inline void write_at_le8(void *dest, uint8_t val, size_t offset)
159 {
160 write_at_ble8(dest, val, offset);
161 }
162
read_le16(const void * src)163 static inline uint16_t read_le16(const void *src)
164 {
165 const uint8_t *s = src;
166 return (((uint16_t)s[1]) << 8) | (((uint16_t)s[0]) << 0);
167 }
168
read_at_le16(const void * src,size_t offset)169 static inline uint16_t read_at_le16(const void *src, size_t offset)
170 {
171 const uint8_t *s = src;
172 s += offset;
173 return read_le16(s);
174 }
175
write_le16(void * dest,uint16_t val)176 static inline void write_le16(void *dest, uint16_t val)
177 {
178 write_le8(dest, val >> 0);
179 write_at_le8(dest, val >> 8, sizeof(uint8_t));
180 }
181
write_at_le16(void * dest,uint16_t val,size_t offset)182 static inline void write_at_le16(void *dest, uint16_t val, size_t offset)
183 {
184 uint8_t *d = dest;
185 d += offset;
186 write_le16(d, val);
187 }
188
read_le32(const void * src)189 static inline uint32_t read_le32(const void *src)
190 {
191 const uint8_t *s = src;
192 return (((uint32_t)s[3]) << 24) | (((uint32_t)s[2]) << 16) |
193 (((uint32_t)s[1]) << 8) | (((uint32_t)s[0]) << 0);
194 }
195
read_at_le32(const void * src,size_t offset)196 static inline uint32_t read_at_le32(const void *src, size_t offset)
197 {
198 const uint8_t *s = src;
199 s += offset;
200 return read_le32(s);
201 }
202
write_le32(void * dest,uint32_t val)203 static inline void write_le32(void *dest, uint32_t val)
204 {
205 write_le16(dest, val >> 0);
206 write_at_le16(dest, val >> 16, sizeof(uint16_t));
207 }
208
write_at_le32(void * dest,uint32_t val,size_t offset)209 static inline void write_at_le32(void *dest, uint32_t val, size_t offset)
210 {
211 uint8_t *d = dest;
212 d += offset;
213 write_le32(d, val);
214 }
215
read_le64(const void * src)216 static inline uint64_t read_le64(const void *src)
217 {
218 uint64_t val;
219 val = read_at_le32(src, sizeof(uint32_t));
220 val <<= 32;
221 val |= read_le32(src);
222 return val;
223 }
224
read_at_le64(const void * src,size_t offset)225 static inline uint64_t read_at_le64(const void *src, size_t offset)
226 {
227 const uint8_t *s = src;
228 s += offset;
229 return read_le64(s);
230 }
231
write_le64(void * dest,uint64_t val)232 static inline void write_le64(void *dest, uint64_t val)
233 {
234 write_le32(dest, val >> 0);
235 write_at_le32(dest, val >> 32, sizeof(uint32_t));
236 }
237
write_at_le64(void * dest,uint64_t val,size_t offset)238 static inline void write_at_le64(void *dest, uint64_t val, size_t offset)
239 {
240 uint8_t *d = dest;
241 d += offset;
242 write_le64(d, val);
243 }
244
zero_n(void * dest,size_t n)245 static inline void zero_n(void *dest, size_t n)
246 {
247 memset(dest, 0, n);
248 }
249
250 #endif
251