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