22 #ifndef LELY_UTIL_ENDIAN_H_
23 #define LELY_UTIL_ENDIAN_H_
32 #define betoh16 be16toh
33 #define letoh16 le16toh
34 #define betoh32 be32toh
35 #define letoh32 le32toh
36 #define betoh64 be64toh
37 #define letoh64 le64toh
40 #ifndef LELY_UTIL_ENDIAN_INLINE
41 #define LELY_UTIL_ENDIAN_INLINE static inline
44 #ifndef LELY_BIG_ENDIAN
45 #if defined(__BIG_ENDIAN__) || defined(__big_endian__) \
46 || (__GNUC__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
47 || defined(__ARMEB__) || defined(__AARCH64EB__) \
48 || defined(__THUMBEB__)
49 #define LELY_BIG_ENDIAN 1
55 #undef LELY_LITTLE_ENDIAN
58 #ifndef LELY_LITTLE_ENDIAN
59 #if defined(__LITTLE_ENDIAN__) || defined(__little_endian__) \
60 || (__GNUC__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
61 || defined(__i386__) || defined(_M_IX86) \
62 || defined(__x86_64__) || defined(_M_AMD64) \
63 || defined(__ARMEL__) || defined(__AARCH64EL__) \
64 || defined(__THUMBEL__)
65 #define LELY_LITTLE_ENDIAN 1
70 #if LELY_LITTLE_ENDIAN
71 #undef LELY_BIG_ENDIAN
74 #if !LELY_BIG_ENDIAN && !LELY_LITTLE_ENDIAN
75 #error Unable to determine byte order or byte order is not supported.
83 LELY_UTIL_ENDIAN_INLINE uint_least16_t
htobe16(uint_least16_t x);
88 LELY_UTIL_ENDIAN_INLINE uint_least16_t betoh16(uint_least16_t x);
93 LELY_UTIL_ENDIAN_INLINE uint_least16_t
htole16(uint_least16_t x);
98 LELY_UTIL_ENDIAN_INLINE uint_least16_t letoh16(uint_least16_t x);
103 LELY_UTIL_ENDIAN_INLINE uint_least32_t
htobe32(uint_least32_t x);
108 LELY_UTIL_ENDIAN_INLINE uint_least32_t betoh32(uint_least32_t x);
113 LELY_UTIL_ENDIAN_INLINE uint_least32_t
htole32(uint_least32_t x);
118 LELY_UTIL_ENDIAN_INLINE uint_least32_t letoh32(uint_least32_t x);
123 LELY_UTIL_ENDIAN_INLINE uint_least64_t
htobe64(uint_least64_t x);
128 LELY_UTIL_ENDIAN_INLINE uint_least64_t betoh64(uint_least64_t x);
133 LELY_UTIL_ENDIAN_INLINE uint_least64_t
htole64(uint_least64_t x);
138 LELY_UTIL_ENDIAN_INLINE uint_least64_t letoh64(uint_least64_t x);
143 LELY_UTIL_ENDIAN_INLINE
void stbe_i16(uint_least8_t dst[2], int_least16_t x);
146 LELY_UTIL_ENDIAN_INLINE int_least16_t
ldbe_i16(
const uint_least8_t src[2]);
149 LELY_UTIL_ENDIAN_INLINE
void stbe_u16(uint_least8_t dst[2], uint_least16_t x);
152 LELY_UTIL_ENDIAN_INLINE uint_least16_t
ldbe_u16(
const uint_least8_t src[2]);
155 LELY_UTIL_ENDIAN_INLINE
void stle_i16(uint_least8_t dst[2], int_least16_t x);
158 LELY_UTIL_ENDIAN_INLINE int_least16_t
ldle_i16(
const uint_least8_t src[2]);
161 LELY_UTIL_ENDIAN_INLINE
void stle_u16(uint_least8_t dst[2], uint_least16_t x);
164 LELY_UTIL_ENDIAN_INLINE uint_least16_t
ldle_u16(
const uint_least8_t src[2]);
167 LELY_UTIL_ENDIAN_INLINE
void stbe_i32(uint_least8_t dst[4], int_least32_t x);
170 LELY_UTIL_ENDIAN_INLINE int_least32_t
ldbe_i32(
const uint_least8_t src[4]);
173 LELY_UTIL_ENDIAN_INLINE
void stbe_u32(uint_least8_t dst[4], uint_least32_t x);
176 LELY_UTIL_ENDIAN_INLINE uint_least32_t
ldbe_u32(
const uint_least8_t src[4]);
179 LELY_UTIL_ENDIAN_INLINE
void stle_i32(uint_least8_t dst[4], int_least32_t x);
182 LELY_UTIL_ENDIAN_INLINE int_least32_t
ldle_i32(
const uint_least8_t src[4]);
185 LELY_UTIL_ENDIAN_INLINE
void stle_u32(uint_least8_t dst[4], uint_least32_t x);
188 LELY_UTIL_ENDIAN_INLINE uint_least32_t
ldle_u32(
const uint_least8_t src[4]);
191 LELY_UTIL_ENDIAN_INLINE
void stbe_i64(uint_least8_t dst[8], int_least64_t x);
194 LELY_UTIL_ENDIAN_INLINE int_least64_t
ldbe_i64(
const uint_least8_t src[8]);
197 LELY_UTIL_ENDIAN_INLINE
void stbe_u64(uint_least8_t dst[8], uint_least64_t x);
200 LELY_UTIL_ENDIAN_INLINE uint_least64_t
ldbe_u64(
const uint_least8_t src[8]);
203 LELY_UTIL_ENDIAN_INLINE
void stle_i64(uint_least8_t dst[8], int_least64_t x);
206 LELY_UTIL_ENDIAN_INLINE int_least64_t
ldle_i64(
const uint_least8_t src[8]);
209 LELY_UTIL_ENDIAN_INLINE
void stle_u64(uint_least8_t dst[8], uint_least64_t x);
212 LELY_UTIL_ENDIAN_INLINE uint_least64_t
ldle_u64(
const uint_least8_t src[8]);
214 #ifdef LELY_FLT16_TYPE
220 LELY_UTIL_ENDIAN_INLINE
void stbe_flt16(uint_least8_t dst[2], flt16_t x);
226 LELY_UTIL_ENDIAN_INLINE flt16_t ldbe_flt16(
const uint_least8_t src[2]);
232 LELY_UTIL_ENDIAN_INLINE
void stle_flt16(uint_least8_t dst[2], flt16_t x);
238 LELY_UTIL_ENDIAN_INLINE flt16_t ldle_flt16(
const uint_least8_t src[2]);
240 #endif // LELY_FLT16_TYPE
242 #ifdef LELY_FLT32_TYPE
248 LELY_UTIL_ENDIAN_INLINE
void stbe_flt32(uint_least8_t dst[4], flt32_t x);
254 LELY_UTIL_ENDIAN_INLINE flt32_t ldbe_flt32(
const uint_least8_t src[4]);
260 LELY_UTIL_ENDIAN_INLINE
void stle_flt32(uint_least8_t dst[4], flt32_t x);
266 LELY_UTIL_ENDIAN_INLINE flt32_t ldle_flt32(
const uint_least8_t src[4]);
268 #endif // LELY_FLT32_TYPE
270 #ifdef LELY_FLT64_TYPE
276 LELY_UTIL_ENDIAN_INLINE
void stbe_flt64(uint_least8_t dst[8], flt64_t x);
282 LELY_UTIL_ENDIAN_INLINE flt64_t ldbe_flt64(
const uint_least8_t src[8]);
288 LELY_UTIL_ENDIAN_INLINE
void stle_flt64(uint_least8_t dst[8], flt64_t x);
294 LELY_UTIL_ENDIAN_INLINE flt64_t ldle_flt64(
const uint_least8_t src[8]);
296 #endif // LELY_FLT64_TYPE
310 void bcpybe(uint_least8_t *dst,
int dstbit,
const uint_least8_t *src,
311 int srcbit,
size_t n);
325 void bcpyle(uint_least8_t *dst,
int dstbit,
const uint_least8_t *src,
326 int srcbit,
size_t n);
329 LELY_UTIL_ENDIAN_INLINE uint_least16_t
332 x &= UINT16_C(0xffff);
335 #elif LELY_LITTLE_ENDIAN
342 LELY_UTIL_ENDIAN_INLINE uint_least16_t
343 betoh16(uint_least16_t x)
350 LELY_UTIL_ENDIAN_INLINE uint_least16_t
353 x &= UINT16_C(0xffff);
356 #elif LELY_LITTLE_ENDIAN
363 LELY_UTIL_ENDIAN_INLINE uint_least16_t
364 letoh16(uint_least16_t x)
371 LELY_UTIL_ENDIAN_INLINE uint_least32_t
374 x &= UINT32_C(0xffffffff);
377 #elif LELY_LITTLE_ENDIAN
384 LELY_UTIL_ENDIAN_INLINE uint_least32_t
385 betoh32(uint_least32_t x)
392 LELY_UTIL_ENDIAN_INLINE uint_least32_t
395 x &= UINT32_C(0xffffffff);
398 #elif LELY_LITTLE_ENDIAN
405 LELY_UTIL_ENDIAN_INLINE uint_least32_t
406 letoh32(uint_least32_t x)
413 LELY_UTIL_ENDIAN_INLINE uint_least64_t
416 x &= UINT64_C(0xffffffffffffffff);
419 #elif LELY_LITTLE_ENDIAN
426 LELY_UTIL_ENDIAN_INLINE uint_least64_t
427 betoh64(uint_least64_t x)
434 LELY_UTIL_ENDIAN_INLINE uint_least64_t
437 x &= UINT64_C(0xffffffffffffffff);
440 #elif LELY_LITTLE_ENDIAN
447 LELY_UTIL_ENDIAN_INLINE uint_least64_t
448 letoh64(uint_least64_t x)
454 LELY_UTIL_ENDIAN_INLINE
void
460 LELY_UTIL_ENDIAN_INLINE int_least16_t
466 LELY_UTIL_ENDIAN_INLINE
void
471 memcpy(dst, &x,
sizeof(x));
473 dst[0] = (x >> 8) & 0xff;
478 LELY_UTIL_ENDIAN_INLINE uint_least16_t
482 uint_least16_t x = 0;
483 memcpy(&x, src,
sizeof(x));
486 return ((uint_least16_t)(src[0] & 0xff) << 8)
487 | ((uint_least16_t)(src[1] & 0xff));
491 LELY_UTIL_ENDIAN_INLINE
void
497 LELY_UTIL_ENDIAN_INLINE int_least16_t
503 LELY_UTIL_ENDIAN_INLINE
void
508 memcpy(dst, &x,
sizeof(x));
511 dst[1] = (x >> 8) & 0xff;
515 LELY_UTIL_ENDIAN_INLINE uint_least16_t
519 uint_least16_t x = 0;
520 memcpy(&x, src,
sizeof(x));
523 return (uint_least16_t)(src[0] & 0xff)
524 | ((uint_least16_t)(src[1] & 0xff) << 8);
528 LELY_UTIL_ENDIAN_INLINE
void
534 LELY_UTIL_ENDIAN_INLINE int_least32_t
540 LELY_UTIL_ENDIAN_INLINE
void
545 memcpy(dst, &x,
sizeof(x));
547 dst[0] = (x >> 24) & 0xff;
548 dst[1] = (x >> 16) & 0xff;
549 dst[2] = (x >> 8) & 0xff;
554 LELY_UTIL_ENDIAN_INLINE uint_least32_t
558 uint_least32_t x = 0;
559 memcpy(&x, src,
sizeof(x));
562 return ((uint_least32_t)(src[0] & 0xff) << 24)
563 | ((uint_least32_t)(src[1] & 0xff) << 16)
564 | ((uint_least32_t)(src[2] & 0xff) << 8)
565 | ((uint_least32_t)(src[3] & 0xff));
569 LELY_UTIL_ENDIAN_INLINE
void
575 LELY_UTIL_ENDIAN_INLINE int_least32_t
581 LELY_UTIL_ENDIAN_INLINE
void
586 memcpy(dst, &x,
sizeof(x));
589 dst[1] = (x >> 8) & 0xff;
590 dst[2] = (x >> 16) & 0xff;
591 dst[3] = (x >> 24) & 0xff;
595 LELY_UTIL_ENDIAN_INLINE uint_least32_t
599 uint_least32_t x = 0;
600 memcpy(&x, src,
sizeof(x));
603 return (uint_least32_t)(src[0] & 0xff)
604 | ((uint_least32_t)(src[1] & 0xff) << 8)
605 | ((uint_least32_t)(src[2] & 0xff) << 16)
606 | ((uint_least32_t)(src[3] & 0xff) << 24);
610 LELY_UTIL_ENDIAN_INLINE
void
616 LELY_UTIL_ENDIAN_INLINE int_least64_t
622 LELY_UTIL_ENDIAN_INLINE
void
627 memcpy(dst, &x,
sizeof(x));
629 dst[0] = (x >> 56) & 0xff;
630 dst[1] = (x >> 48) & 0xff;
631 dst[2] = (x >> 40) & 0xff;
632 dst[3] = (x >> 32) & 0xff;
633 dst[4] = (x >> 24) & 0xff;
634 dst[5] = (x >> 16) & 0xff;
635 dst[6] = (x >> 8) & 0xff;
640 LELY_UTIL_ENDIAN_INLINE uint_least64_t
644 uint_least64_t x = 0;
645 memcpy(&x, src,
sizeof(x));
648 return ((uint_least64_t)(src[0] & 0xff) << 56)
649 | ((uint_least64_t)(src[1] & 0xff) << 48)
650 | ((uint_least64_t)(src[2] & 0xff) << 40)
651 | ((uint_least64_t)(src[3] & 0xff) << 32)
652 | ((uint_least64_t)(src[4] & 0xff) << 24)
653 | ((uint_least64_t)(src[5] & 0xff) << 16)
654 | ((uint_least64_t)(src[6] & 0xff) << 8)
655 | ((uint_least64_t)(src[7] & 0xff));
659 LELY_UTIL_ENDIAN_INLINE
void
665 LELY_UTIL_ENDIAN_INLINE int_least64_t
671 LELY_UTIL_ENDIAN_INLINE
void
676 memcpy(dst, &x,
sizeof(x));
679 dst[1] = (x >> 8) & 0xff;
680 dst[2] = (x >> 16) & 0xff;
681 dst[3] = (x >> 24) & 0xff;
682 dst[4] = (x >> 32) & 0xff;
683 dst[5] = (x >> 40) & 0xff;
684 dst[6] = (x >> 48) & 0xff;
685 dst[7] = (x >> 56) & 0xff;
689 LELY_UTIL_ENDIAN_INLINE uint_least64_t
693 uint_least64_t x = 0;
694 memcpy(&x, src,
sizeof(x));
697 return (uint_least64_t)(src[0] & 0xff)
698 | ((uint_least64_t)(src[1] & 0xff) << 8)
699 | ((uint_least64_t)(src[2] & 0xff) << 16)
700 | ((uint_least64_t)(src[3] & 0xff) << 24)
701 | ((uint_least64_t)(src[4] & 0xff) << 32)
702 | ((uint_least64_t)(src[5] & 0xff) << 40)
703 | ((uint_least64_t)(src[6] & 0xff) << 48)
704 | ((uint_least64_t)(src[7] & 0xff) << 56);
708 #ifdef LELY_FLT16_TYPE
710 LELY_UTIL_ENDIAN_INLINE
void
711 stbe_flt16(uint_least8_t dst[2], flt16_t x)
713 uint_least16_t tmp = 0;
714 memcpy(&tmp, &x,
sizeof(x));
718 LELY_UTIL_ENDIAN_INLINE flt16_t
719 ldbe_flt16(
const uint_least8_t src[2])
723 memcpy(&x, &tmp,
sizeof(x));
727 LELY_UTIL_ENDIAN_INLINE
void
728 stle_flt16(uint_least8_t dst[2], flt16_t x)
730 uint_least16_t tmp = 0;
731 memcpy(&tmp, &x,
sizeof(x));
735 LELY_UTIL_ENDIAN_INLINE flt16_t
736 ldle_flt16(
const uint_least8_t src[2])
740 memcpy(&x, &tmp,
sizeof(x));
744 #endif // LELY_FLT16_TYPE
746 #ifdef LELY_FLT32_TYPE
748 LELY_UTIL_ENDIAN_INLINE
void
749 stbe_flt32(uint_least8_t dst[4], flt32_t x)
751 uint_least32_t tmp = 0;
752 memcpy(&tmp, &x,
sizeof(x));
756 LELY_UTIL_ENDIAN_INLINE flt32_t
757 ldbe_flt32(
const uint_least8_t src[4])
761 memcpy(&x, &tmp,
sizeof(x));
765 LELY_UTIL_ENDIAN_INLINE
void
766 stle_flt32(uint_least8_t dst[4], flt32_t x)
768 uint_least32_t tmp = 0;
769 memcpy(&tmp, &x,
sizeof(x));
773 LELY_UTIL_ENDIAN_INLINE flt32_t
774 ldle_flt32(
const uint_least8_t src[4])
778 memcpy(&x, &tmp,
sizeof(x));
782 #endif // LELY_FLT32_TYPE
784 #ifdef LELY_FLT64_TYPE
786 LELY_UTIL_ENDIAN_INLINE
void
787 stbe_flt64(uint_least8_t dst[8], flt64_t x)
789 uint_least64_t tmp = 0;
790 memcpy(&tmp, &x,
sizeof(x));
794 LELY_UTIL_ENDIAN_INLINE flt64_t
795 ldbe_flt64(
const uint_least8_t src[8])
799 memcpy(&x, &tmp,
sizeof(x));
803 LELY_UTIL_ENDIAN_INLINE
void
804 stle_flt64(uint_least8_t dst[8], flt64_t x)
806 uint_least64_t tmp = 0;
807 memcpy(&tmp, &x,
sizeof(x));
811 LELY_UTIL_ENDIAN_INLINE flt64_t
812 ldle_flt64(
const uint_least8_t src[8])
816 memcpy(&x, &tmp,
sizeof(x));
820 #endif // LELY_FLT64_TYPE
826 #endif // !LELY_UTIL_ENDIAN_H_