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:
| M | src/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 */