1 #ifndef R_ENDIAN_H
2 #define R_ENDIAN_H
3
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7
8 /* Endian agnostic functions working on single byte. */
9
r_read_ble8(const void * src)10 static inline ut8 r_read_ble8(const void *src) {
11 if (!src) {
12 return UT8_MAX;
13 }
14 return *(const ut8 *)src;
15 }
16
r_read_at_ble8(const void * src,size_t offset)17 static inline ut8 r_read_at_ble8(const void *src, size_t offset) {
18 return r_read_ble8 (((const ut8*)src) + offset);
19 }
20
r_write_ble8(void * dest,ut8 val)21 static inline void r_write_ble8(void *dest, ut8 val) {
22 *(ut8 *)dest = val;
23 }
24
r_write_at_ble8(void * dest,ut8 val,size_t offset)25 static inline void r_write_at_ble8(void *dest, ut8 val, size_t offset) {
26 ut8 *d = (ut8*)dest + offset;
27 r_write_ble8 (d, val);
28 }
29
30 /* Big Endian functions. */
31
r_read_be8(const void * src)32 static inline ut8 r_read_be8(const void *src) {
33 return r_read_ble8 (src);
34 }
35
r_read_at_be8(const void * src,size_t offset)36 static inline ut8 r_read_at_be8(const void *src, size_t offset) {
37 return r_read_at_ble8 (src, offset);
38 }
39
r_write_be8(void * dest,ut8 val)40 static inline void r_write_be8(void *dest, ut8 val) {
41 r_write_ble8 (dest, val);
42 }
43
r_write_at_be8(void * dest,ut8 val,size_t offset)44 static inline void r_write_at_be8(void *dest, ut8 val, size_t offset) {
45 r_write_at_ble8 (dest, val, offset);
46 }
47
r_read_be16(const void * src)48 static inline ut16 r_read_be16(const void *src) {
49 const ut8 *s = (const ut8*)src;
50 return (((ut16)s[0]) << 8) | (((ut16)s[1]) << 0);
51 }
52
r_read_at_be16(const void * src,size_t offset)53 static inline ut16 r_read_at_be16(const void *src, size_t offset) {
54 const ut8 *s = (const ut8*)src + offset;
55 return r_read_be16 (s);
56 }
57
r_write_be16(void * dest,ut16 val)58 static inline void r_write_be16(void *dest, ut16 val) {
59 r_write_be8 (dest, val >> 8);
60 r_write_at_be8 (dest, (ut8)val, sizeof (ut8));
61 }
62
r_write_at_be16(void * dest,ut16 val,size_t offset)63 static inline void r_write_at_be16(void *dest, ut16 val, size_t offset) {
64 ut8 *d = (ut8*)dest + offset;
65 r_write_be16 (d, val);
66 }
67
r_read_be32(const void * src)68 static inline ut32 r_read_be32(const void *src) {
69 const ut8 *s = (const ut8*)src;
70 return (((ut32)s[0]) << 24) | (((ut32)s[1]) << 16) |
71 (((ut32)s[2]) << 8) | (((ut32)s[3]) << 0);
72 }
73
r_read_at_be32(const void * src,size_t offset)74 static inline ut32 r_read_at_be32(const void *src, size_t offset) {
75 const ut8 *s = (const ut8*)src + offset;
76 return r_read_be32 (s);
77 }
78
r_write_be32(void * dest,ut32 val)79 static inline void r_write_be32(void *dest, ut32 val) {
80 r_write_be16 (dest, val >> 16);
81 r_write_at_be16 (dest, val, sizeof (ut16));
82 }
83
r_write_be24(void * _dest,ut32 val)84 static inline void r_write_be24(void *_dest, ut32 val) {
85 ut8 *dest = (ut8*)_dest;
86 r_write_be8 (dest++, val >> 16);
87 r_write_be8 (dest++, val >> 8);
88 r_write_be8 (dest, val);
89 }
90
r_write_at_be32(void * dest,ut32 val,size_t offset)91 static inline void r_write_at_be32(void *dest, ut32 val, size_t offset) {
92 ut8 *d = (ut8*)dest + offset;
93 r_write_be32 (d, val);
94 }
95
r_read_be64(const void * src)96 static inline ut64 r_read_be64(const void *src) {
97 ut64 val = ((ut64)(r_read_be32 (src))) << 32;
98 val |= r_read_at_be32 (src, sizeof (ut32));
99 return val;
100 }
101
r_read_at_be64(const void * src,size_t offset)102 static inline ut64 r_read_at_be64(const void *src, size_t offset) {
103 const ut8 *s = (const ut8*)src + offset;
104 return r_read_be64 (s);
105 }
106
r_write_be64(void * dest,ut64 val)107 static inline void r_write_be64(void *dest, ut64 val) {
108 r_write_be32 (dest, val >> 32);
109 r_write_at_be32 (dest, (ut32)val, sizeof (ut32));
110 }
111
r_write_at_be64(void * dest,ut64 val,size_t offset)112 static inline void r_write_at_be64(void *dest, ut64 val, size_t offset) {
113 ut8 *d = (ut8*)dest + offset;
114 r_write_be64 (d, val);
115 }
116
117 /* Little Endian functions. */
118
r_read_le8(const void * src)119 static inline ut8 r_read_le8(const void *src) {
120 if (!src) {
121 return UT8_MAX;
122 }
123 return r_read_ble8 (src);
124 }
125
r_read_at_le8(const void * src,size_t offset)126 static inline ut8 r_read_at_le8(const void *src, size_t offset) {
127 return r_read_at_ble8 (src, offset);
128 }
129
r_write_le8(void * dest,ut8 val)130 static inline void r_write_le8(void *dest, ut8 val) {
131 r_write_ble8 (dest, val);
132 }
133
r_write_at_le8(void * dest,ut8 val,size_t offset)134 static inline void r_write_at_le8(void *dest, ut8 val, size_t offset) {
135 r_write_at_ble8 (dest, val, offset);
136 }
137
r_read_le16(const void * src)138 static inline ut16 r_read_le16(const void *src) {
139 if (!src) {
140 return UT16_MAX;
141 }
142 const ut8 *s = (const ut8*)src;
143 return (((ut16)s[1]) << 8) | (((ut16)s[0]) << 0);
144 }
145
r_read_at_le16(const void * src,size_t offset)146 static inline ut16 r_read_at_le16(const void *src, size_t offset) {
147 if (!src) {
148 return UT16_MAX;
149 }
150 const ut8 *s = (const ut8*)src + offset;
151 return r_read_le16 (s);
152 }
153
r_write_le16(void * dest,ut16 val)154 static inline void r_write_le16(void *dest, ut16 val) {
155 r_write_le8 (dest, (ut8)val);
156 r_write_at_le8 (dest, val >> 8, sizeof (ut8));
157 }
158
r_write_at_le16(void * dest,ut16 val,size_t offset)159 static inline void r_write_at_le16(void *dest, ut16 val, size_t offset) {
160 ut8 *d = (ut8 *)dest + offset;
161 r_write_le16 (d, val);
162 }
163
r_write_le24(void * _dest,ut32 val)164 static inline void r_write_le24(void *_dest, ut32 val) {
165 ut8* dest = (ut8*)_dest;
166 r_write_le8 (dest++, val);
167 r_write_le8 (dest++, val >> 8);
168 r_write_le8 (dest, val >> 16);
169 }
170
r_read_le32(const void * src)171 static inline ut32 r_read_le32(const void *src) {
172 if (!src) {
173 return UT32_MAX;
174 }
175 const ut8 *s = (const ut8*)src;
176 return (((ut32)s[3]) << 24) | (((ut32)s[2]) << 16) |
177 (((ut32)s[1]) << 8) | (((ut32)s[0]) << 0);
178 }
179
r_read_at_le32(const void * src,size_t offset)180 static inline ut32 r_read_at_le32(const void *src, size_t offset) {
181 if (!src) {
182 return UT32_MAX;
183 }
184 const ut8 *s = (const ut8*)src + offset;
185 return r_read_le32 (s);
186 }
187
r_write_le32(void * dest,ut32 val)188 static inline void r_write_le32(void *dest, ut32 val) {
189 r_write_le16 (dest, val);
190 r_write_at_le16 (dest, val >> 16, sizeof (ut16));
191 }
192
r_write_at_le32(void * dest,ut32 val,size_t offset)193 static inline void r_write_at_le32(void *dest, ut32 val, size_t offset) {
194 ut8 *d = ((ut8*)dest) + offset;
195 r_write_le32 (d, val);
196 }
197
r_read_le64(const void * src)198 static inline ut64 r_read_le64(const void *src) {
199 ut64 val = ((ut64)(r_read_at_le32 (src, sizeof (ut32)))) << 32;
200 val |= r_read_le32 (src);
201 return val;
202 }
203
r_read_at_le64(const void * src,size_t offset)204 static inline ut64 r_read_at_le64(const void *src, size_t offset) {
205 const ut8 *s = ((const ut8*)src) + offset;
206 return r_read_le64 (s);
207 }
208
r_write_le64(void * dest,ut64 val)209 static inline void r_write_le64(void *dest, ut64 val) {
210 r_write_le32 (dest, (ut32)val);
211 r_write_at_le32 (dest, val >> 32, sizeof (ut32));
212 }
213
r_write_at_le64(void * dest,ut64 val,size_t offset)214 static inline void r_write_at_le64(void *dest, ut64 val, size_t offset) {
215 ut8 *d = (ut8*)dest + offset;
216 r_write_le64 (d, val);
217 }
218
219 /* Middle Endian functions. */
220
r_read_me8(const void * src)221 static inline ut8 r_read_me8(const void *src) {
222 return src ? r_read_ble8 (src): UT8_MAX;
223 }
224
r_read_at_me8(const void * src,size_t offset)225 static inline ut8 r_read_at_me8(const void *src, size_t offset) {
226 return r_read_at_ble8 (src, offset);
227 }
228
r_write_me8(void * dest,ut8 val)229 static inline void r_write_me8(void *dest, ut8 val) {
230 r_write_ble8 (dest, val);
231 }
232
r_write_at_me8(void * dest,ut8 val,size_t offset)233 static inline void r_write_at_me8(void *dest, ut8 val, size_t offset) {
234 r_write_at_ble8 (dest, val, offset);
235 }
236
r_read_me16(const void * src)237 static inline ut16 r_read_me16(const void *src) {
238 if (!src) {
239 return UT16_MAX;
240 }
241 const ut8 *s = (const ut8*)src;
242 return (((ut16)s[0]) << 8) | (((ut16)s[1]) << 0);
243 }
244
r_read_at_me16(const void * src,size_t offset)245 static inline ut16 r_read_at_me16(const void *src, size_t offset) {
246 if (!src) {
247 return UT16_MAX;
248 }
249 const ut8 *s = (const ut8*)src + offset;
250 return r_read_me16 (s);
251 }
252
r_write_me16(void * dest,ut16 val)253 static inline void r_write_me16(void *dest, ut16 val) {
254 r_write_me8 (dest, val >> 8);
255 r_write_at_me8 (dest, (ut8)val, sizeof (ut8));
256 }
257
r_write_at_me16(void * dest,ut16 val,size_t offset)258 static inline void r_write_at_me16(void *dest, ut16 val, size_t offset) {
259 ut8 *d = (ut8 *)dest + offset;
260 r_write_me16 (d, val);
261 }
262
r_read_me32(const void * src)263 static inline ut32 r_read_me32(const void *src) {
264 if (!src) {
265 return UT32_MAX;
266 }
267 const ut8 *s = (const ut8*)src;
268 return (((ut32)s[2]) << 24) | (((ut32)s[1]) << 16) |
269 (((ut32)s[0]) << 8) | (((ut32)s[1]) << 0);
270 }
271
r_read_at_me32(const void * src,size_t offset)272 static inline ut32 r_read_at_me32(const void *src, size_t offset) {
273 if (!src) {
274 return UT32_MAX;
275 }
276 const ut8 *s = (const ut8*)src + offset;
277 return r_read_me32 (s);
278 }
279
r_write_me32(void * dest,ut32 val)280 static inline void r_write_me32(void *dest, ut32 val) {
281 r_write_me16 (dest, val);
282 r_write_at_me16 (dest, val >> 16, sizeof (ut16));
283 }
284
r_write_at_me32(void * dest,ut32 val,size_t offset)285 static inline void r_write_at_me32(void *dest, ut32 val, size_t offset) {
286 ut8 *d = ((ut8*)dest) + offset;
287 r_write_me32 (d, val);
288 }
289
r_read_me64(const void * src)290 static inline ut64 r_read_me64(const void *src) {
291 ut64 val = ((ut64)(r_read_at_me32 (src, sizeof (ut32)))) << 32;
292 val |= r_read_me32 (src);
293 return val;
294 }
295
r_read_at_me64(const void * src,size_t offset)296 static inline ut64 r_read_at_me64(const void *src, size_t offset) {
297 const ut8 *s = ((const ut8*)src) + offset;
298 return r_read_me64 (s);
299 }
300
r_write_me64(void * dest,ut64 val)301 static inline void r_write_me64(void *dest, ut64 val) {
302 r_write_me32 (dest, (ut32)val);
303 r_write_at_me32 (dest, val >> 32, sizeof (ut32));
304 }
305
r_write_at_me64(void * dest,ut64 val,size_t offset)306 static inline void r_write_at_me64(void *dest, ut64 val, size_t offset) {
307 ut8 *d = (ut8*)dest + offset;
308 r_write_me64 (d, val);
309 }
310
311 /* Helper functions */
312
r_read_ble16(const void * src,bool big_endian)313 static inline ut16 r_read_ble16(const void *src, bool big_endian) {
314 return big_endian? r_read_be16 (src): r_read_le16 (src);
315 }
316
r_read_ble32(const void * src,bool big_endian)317 static inline ut32 r_read_ble32(const void *src, bool big_endian) {
318 return big_endian? r_read_be32 (src): r_read_le32 (src);
319 }
320
r_read_ble64(const void * src,bool big_endian)321 static inline ut64 r_read_ble64(const void *src, bool big_endian) {
322 return big_endian? r_read_be64 (src): r_read_le64 (src);
323 }
324
r_read_at_ble16(const void * src,size_t offset,bool big_endian)325 static inline ut16 r_read_at_ble16(const void *src, size_t offset, bool big_endian) {
326 return big_endian ? r_read_at_be16 (src, offset) : r_read_at_le16 (src, offset);
327 }
328
r_read_at_ble32(const void * src,size_t offset,bool big_endian)329 static inline ut32 r_read_at_ble32(const void *src, size_t offset, bool big_endian) {
330 return big_endian ? r_read_at_be32 (src, offset) : r_read_at_le32 (src, offset);
331 }
332
r_read_at_ble64(const void * src,size_t offset,bool big_endian)333 static inline ut64 r_read_at_ble64(const void *src, size_t offset, bool big_endian) {
334 return big_endian ? r_read_at_be64 (src, offset) : r_read_at_le64 (src, offset);
335 }
336
r_read_ble(const void * src,bool big_endian,int size)337 static inline ut64 r_read_ble(const void *src, bool big_endian, int size) {
338 switch (size) {
339 case 8:
340 return (ut64) ((const ut8*)src)[0];
341 case 16:
342 return r_read_ble16 (src, big_endian);
343 case 32:
344 return r_read_ble32 (src, big_endian);
345 case 64:
346 return r_read_ble64 (src, big_endian);
347 default:
348 return UT64_MAX;
349 }
350 }
351
r_write_ble16(void * dest,ut16 val,bool big_endian)352 static inline void r_write_ble16(void *dest, ut16 val, bool big_endian) {
353 big_endian? r_write_be16 (dest, val): r_write_le16 (dest, val);
354 }
355
r_write_ble24(void * dest,ut32 val,bool big_endian)356 static inline void r_write_ble24(void *dest, ut32 val, bool big_endian) {
357 big_endian? r_write_be24 (dest, val): r_write_le24 (dest, val);
358 }
359
r_write_ble32(void * dest,ut32 val,bool big_endian)360 static inline void r_write_ble32(void *dest, ut32 val, bool big_endian) {
361 big_endian? r_write_be32 (dest, val): r_write_le32 (dest, val);
362 }
363
r_write_ble64(void * dest,ut64 val,bool big_endian)364 static inline void r_write_ble64(void *dest, ut64 val, bool big_endian) {
365 big_endian? r_write_be64 (dest, val): r_write_le64 (dest, val);
366 }
367
r_write_ble(void * dst,ut64 val,bool big_endian,int size)368 static inline void r_write_ble(void *dst, ut64 val, bool big_endian, int size) {
369 switch (size) {
370 case 8:
371 ((ut8*)dst)[0] = (ut8) val;
372 break;
373 case 16:
374 r_write_ble16 (dst, (ut16) val, big_endian);
375 break;
376 case 24:
377 r_write_ble24 (dst, (ut32) val, big_endian);
378 break;
379 case 32:
380 r_write_ble32 (dst, (ut32) val, big_endian);
381 break;
382 case 64:
383 r_write_ble64 (dst, val, big_endian);
384 break;
385 default:
386 break;
387 }
388 }
389
390 // TODO: find better names and write vapis
391 #define ut8p_b(x) ((x)[0])
392 #define ut8p_bw(x) ((x)[0]|((x)[1]<<8))
393 #define ut8p_bd(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24))
394 #define ut8p_bq(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24)|((x)[4]<<32)|((x)[5]<<40)|((x)[6]<<48)|((x)[7]<<56))
395 #define ut8p_lw(x) ((x)[1]|((x)[0]<<8))
396 #define ut8p_ld(x) ((x)[3]|((x)[2]<<8)|((x)[1]<<16)|((x)[0]<<24))
397 #define ut8p_lq(x) ((x)[7]|((x)[6]<<8)|((x)[5]<<16)|((x)[4]<<24)|((x)[3]<<32)|((x)[2]<<40)|((x)[1]<<48)|((x)[0]<<56))
398
399 /*swap*/
r_swap_ut16(ut16 val)400 static inline ut16 r_swap_ut16(ut16 val) {
401 return (val << 8) | (val >> 8 );
402 }
403
r_swap_st16(st16 val)404 static inline st16 r_swap_st16(st16 val) {
405 val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF );
406 return (val << 16) | (val >> 16);
407 }
408
r_swap_ut32(ut32 val)409 static inline ut32 r_swap_ut32(ut32 val) {
410 val = ((val << 8) & 0xFF00FF00 ) | ((val >> 8) & 0xFF00FF );
411 return (val << 16) | (val >> 16);
412 }
413
r_swap_st32(st32 val)414 static inline st32 r_swap_st32(st32 val) {
415 val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF );
416 return (val << 16) | ((val >> 16) & 0xFFFF);
417 }
418
r_swap_ut64(ut64 val)419 static inline ut64 r_swap_ut64(ut64 val) {
420 val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
421 val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
422 return (val << 32) | (val >> 32);
423 }
424
r_swap_st64(st64 val)425 static inline st64 r_swap_st64(st64 val) {
426 val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL );
427 val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL );
428 return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
429 }
430
431 /* Some "secured" functions, to do basic operation (mul, sub, add...) on integers */
UT64_ADD(ut64 * r,ut64 a,ut64 b)432 static inline int UT64_ADD(ut64 *r, ut64 a, ut64 b) {
433 if (UT64_MAX - a < b) {
434 return 0;
435 }
436 if (r) {
437 *r = a + b;
438 }
439 return 1;
440 }
441
UT64_MUL(ut64 * r,ut64 a,ut64 b)442 static inline int UT64_MUL(ut64 *r, ut64 a, ut64 b) {
443 if (a && UT64_MAX / a < b) {
444 return 0;
445 }
446 if (r) {
447 *r = a * b;
448 }
449 return 1;
450 }
451
UT64_SUB(ut64 * r,ut64 a,ut64 b)452 static inline int UT64_SUB(ut64 *r, ut64 a, ut64 b) {
453 if (b > a) {
454 return 0;
455 }
456 if (r) {
457 *r = a - b;
458 }
459 return 1;
460 }
461
UT32_ADD(ut32 * r,ut32 a,ut32 b)462 static inline int UT32_ADD(ut32 *r, ut32 a, ut32 b) {
463 if (UT32_MAX - a < b) {
464 return 0;
465 }
466 if (r) {
467 *r = a + b;
468 }
469 return 1;
470 }
471
UT32_MUL(ut32 * r,ut32 a,ut32 b)472 static inline int UT32_MUL(ut32 *r, ut32 a, ut32 b) {
473 if (a && UT32_MAX / a < b) {
474 return 0;
475 }
476 if (r) {
477 *r = a * b;
478 }
479 return 1;
480 }
481
UT32_SUB(ut32 * r,ut32 a,ut32 b)482 static inline int UT32_SUB(ut32 *r, ut32 a, ut32 b) {
483 if (b > a) {
484 return 0;
485 }
486 if (r) {
487 *r = a - b;
488 }
489 return 1;
490 }
491
UT16_ADD(ut16 * r,ut16 a,ut16 b)492 static inline int UT16_ADD(ut16 *r, ut16 a, ut16 b) {
493 if (UT16_MAX - a < b) {
494 return 0;
495 }
496 if (r) {
497 *r = a + b;
498 }
499 return 1;
500 }
501
UT16_MUL(ut16 * r,ut16 a,ut16 b)502 static inline int UT16_MUL(ut16 *r, ut16 a, ut16 b) {
503 if (a && UT16_MAX / a < b) {
504 return 0;
505 }
506 if (r) {
507 *r = a * b;
508 }
509 return 1;
510 }
511
UT16_SUB(ut16 * r,ut16 a,ut16 b)512 static inline int UT16_SUB(ut16 *r, ut16 a, ut16 b) {
513 if (b > a) {
514 return 0;
515 }
516 if (r) {
517 *r = a - b;
518 }
519 return 1;
520 }
521
UT8_ADD(ut8 * r,ut8 a,ut8 b)522 static inline int UT8_ADD(ut8 *r, ut8 a, ut8 b) {
523 if (UT8_MAX - a < b) {
524 return 0;
525 }
526 if (r) {
527 *r = a + b;
528 }
529 return 1;
530 }
531
UT8_MUL(ut8 * r,ut8 a,ut8 b)532 static inline int UT8_MUL(ut8 *r, ut8 a, ut8 b) {
533 if (a && UT8_MAX / a < b) {
534 return 0;
535 }
536 if (r) {
537 *r = a * b;
538 }
539 return 1;
540 }
541
UT8_SUB(ut8 * r,ut8 a,ut8 b)542 static inline int UT8_SUB(ut8 *r, ut8 a, ut8 b) {
543 if (b > a) {
544 return 0;
545 }
546 if (r) {
547 *r = a - b;
548 }
549 return 1;
550 }
551
552 #ifdef __cplusplus
553 }
554 #endif
555
556 #endif
557