rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 791c82e5601a4b795056959a1726600ba0b2a16e
parent 9fc5ea8eef98f7ab333c0b28668ec24681ad2adf
Author: vaplv <vaplv@free.fr>
Date:   Fri, 25 Apr 2025 16:51:57 +0200

Rewrite endianness functions

Use only plain C, to provide a portable implementation, i.e. independent
of machine byte order or alignment.

Compiler-dependent directives are always provided if the user needs to
request machine byte order.

Diffstat:
Msrc/endianness.h | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 69 insertions(+), 33 deletions(-)

diff --git a/src/endianness.h b/src/endianness.h @@ -27,68 +27,104 @@ #error "Undefined byte ordering macros" #endif -static FINLINE uint16_t byte_swap_16(const uint16_t ui) { return bswap_16(ui); } -static FINLINE uint32_t byte_swap_32(const uint32_t ui) { return bswap_32(ui); } -static FINLINE uint64_t byte_swap_64(const uint64_t ui) { return bswap_64(ui); } +static FINLINE uint16_t +byte_swap_16(const uint16_t ui) +{ + union { uint16_t ui; uint8_t bytes[2]; } ucast; + ucast.ui = ui; + SWAP(uint8_t, ucast.bytes[0], ucast.bytes[1]); + return ucast.ui; +} + +static FINLINE uint32_t +byte_swap_32(const uint32_t ui) +{ + union { uint32_t ui; uint8_t bytes[4]; } ucast; + ucast.ui = ui; + SWAP(uint8_t, ucast.bytes[0], ucast.bytes[3]); + SWAP(uint8_t, ucast.bytes[1], ucast.bytes[2]); + return ucast.ui; +} +static FINLINE uint64_t +byte_swap_64(const uint64_t ui) +{ + union { uint64_t ui; uint8_t bytes[8]; } ucast; + ucast.ui = ui; + SWAP(uint8_t, ucast.bytes[0], ucast.bytes[7]); + SWAP(uint8_t, ucast.bytes[1], ucast.bytes[6]); + SWAP(uint8_t, ucast.bytes[2], ucast.bytes[5]); + SWAP(uint8_t, ucast.bytes[3], ucast.bytes[4]); + return ucast.ui; +} static FINLINE uint16_t little_endian_16(const uint16_t ui) { -#if BYTE_ORDER == LITTLE_ENDIAN - return ui; -#elif BYTE_ORDER == BIG_ENDIAN - return byte_swap_16(ui); -#endif + union { uint16_t ui; uint8_t bytes[2]; } ucast; + ucast.ui = ui; + return ((uint16_t)ucast.bytes[0] << 0) + | ((uint16_t)ucast.bytes[1] << 8); } static FINLINE uint32_t little_endian_32(const uint32_t ui) { -#if BYTE_ORDER == LITTLE_ENDIAN - return ui; -#elif BYTE_ORDER == BIG_ENDIAN - return byte_swap_32(ui); -#endif + union { uint32_t ui; uint8_t bytes[4]; } ucast; + ucast.ui = ui; + return ((uint32_t)ucast.bytes[0] << 0) + | ((uint32_t)ucast.bytes[1] << 8) + | ((uint32_t)ucast.bytes[2] << 16) + | ((uint32_t)ucast.bytes[3] << 24); } static FINLINE uint64_t little_endian_64(const uint64_t ui) { -#if BYTE_ORDER == LITTLE_ENDIAN - return ui; -#elif BYTE_ORDER == BIG_ENDIAN - return byte_swap_64(ui); -#endif + union { uint64_t ui; uint8_t bytes[8]; } ucast; + ucast.ui = ui; + return ((uint64_t)ucast.bytes[0] << 0) + | ((uint64_t)ucast.bytes[1] << 8) + | ((uint64_t)ucast.bytes[2] << 16) + | ((uint64_t)ucast.bytes[3] << 24) + | ((uint64_t)ucast.bytes[4] << 32) + | ((uint64_t)ucast.bytes[5] << 40) + | ((uint64_t)ucast.bytes[6] << 48) + | ((uint64_t)ucast.bytes[7] << 56); } static FINLINE uint16_t big_endian_16(const uint16_t ui) { -#if BYTE_ORDER == LITTLE_ENDIAN - return byte_swap_16(ui); -#elif BYTE_ORDER == BIG_ENDIAN - return ui; -#endif + union { uint16_t ui; uint8_t bytes[2]; } ucast; + ucast.ui = ui; + return ((uint16_t)ucast.bytes[0] << 8) + | ((uint16_t)ucast.bytes[1] << 0); } static FINLINE uint32_t big_endian_32(const uint32_t ui) { -#if BYTE_ORDER == LITTLE_ENDIAN - return byte_swap_32(ui); -#elif BYTE_ORDER == BIG_ENDIAN - return ui; -#endif + union { uint32_t ui; uint8_t bytes[2]; } ucast; + ucast.ui = ui; + return ((uint32_t)ucast.bytes[0] << 24) + | ((uint32_t)ucast.bytes[1] << 16) + | ((uint32_t)ucast.bytes[2] << 8) + | ((uint32_t)ucast.bytes[3] << 0); } static FINLINE uint64_t big_endian_64(const uint64_t ui) { -#if BYTE_ORDER == LITTLE_ENDIAN - return byte_swap_64(ui); -#elif BYTE_ORDER == BIG_ENDIAN - return ui; -#endif + union { uint64_t ui; uint8_t bytes[8]; } ucast; + ucast.ui = ui; + return ((uint64_t)ucast.bytes[0] << 56) + | ((uint64_t)ucast.bytes[1] << 48) + | ((uint64_t)ucast.bytes[2] << 40) + | ((uint64_t)ucast.bytes[3] << 32) + | ((uint64_t)ucast.bytes[4] << 24) + | ((uint64_t)ucast.bytes[5] << 16) + | ((uint64_t)ucast.bytes[6] << 8) + | ((uint64_t)ucast.bytes[7] << 0); } #endif /* ENDIANNESS_H */