summaryrefslogtreecommitdiff
path: root/libmisc/include
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-21 15:15:22 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-21 19:01:05 -0600
commita27d33b74d77ccb3d9dd9d68f4a9e2d5deed54e0 (patch)
tree67f95b050aaa6021bfd4e0584d2471bcadeb3b6e /libmisc/include
parent1ad43f867bda5a9c0061295989f6c38b5226b512 (diff)
Factor out libmisc/endian.h
Diffstat (limited to 'libmisc/include')
-rw-r--r--libmisc/include/libmisc/endian.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/libmisc/include/libmisc/endian.h b/libmisc/include/libmisc/endian.h
new file mode 100644
index 0000000..eaf9bae
--- /dev/null
+++ b/libmisc/include/libmisc/endian.h
@@ -0,0 +1,129 @@
+/* libmisc/endian.h - Endian-conversion helpers
+ *
+ * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-Licence-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIBMISC_ENDIAN_H_
+#define _LIBMISC_ENDIAN_H_
+
+#include <assert.h>
+#include <stdint.h> /* for uint{n}_t */
+
+/* Big endian *****************************************************************/
+
+typedef struct {
+ uint8_t octets[2];
+} uint16be_t;
+static_assert(sizeof(uint16be_t) == 2);
+
+static inline void uint16be_encode(uint8_t *out, uint16_t in) {
+ out[0] = (uint8_t)((in >> 8) & 0xFF);
+ out[1] = (uint8_t)((in >> 0) & 0xFF);
+}
+
+static inline uint16_t uint16be_decode(uint8_t *in) {
+ return (((uint16_t)(in[0])) << 8)
+ | (((uint16_t)(in[1])) << 0)
+ ;
+}
+
+static inline uint16be_t uint16be_marshal(uint16_t in) {
+ uint16be_t out;
+ uint16be_encode(out.octets, in);
+ return out;
+}
+
+static inline uint16_t uint16be_unmarshal(uint16be_t in) {
+ return uint16be_decode(in.octets);
+}
+
+typedef struct {
+ uint8_t octets[4];
+} uint32be_t;
+static_assert(sizeof(uint32be_t) == 4);
+
+static inline void uint32be_encode(uint8_t *out, uint32_t in) {
+ out[0] = (uint8_t)((in >> 24) & 0xFF);
+ out[1] = (uint8_t)((in >> 16) & 0xFF);
+ out[2] = (uint8_t)((in >> 8) & 0xFF);
+ out[3] = (uint8_t)((in >> 0) & 0xFF);
+}
+
+static inline uint32_t uint32be_decode(uint8_t *in) {
+ return (((uint32_t)(in[0])) << 24)
+ | (((uint32_t)(in[1])) << 16)
+ | (((uint32_t)(in[2])) << 8)
+ | (((uint32_t)(in[3])) << 0)
+ ;
+}
+
+static inline uint32be_t uint32be_marshal(uint32_t in) {
+ uint32be_t out;
+ uint32be_encode(out.octets, in);
+ return out;
+}
+
+static inline uint32_t uint32be_unmarshal(uint32be_t in) {
+ return uint32be_decode(in.octets);
+}
+
+/* Little endian **************************************************************/
+
+typedef struct {
+ uint8_t octets[2];
+} uint16le_t;
+static_assert(sizeof(uint16le_t) == 2);
+
+static inline void uint16le_encode(uint8_t *out, uint16_t in) {
+ out[0] = (uint8_t)((in >> 0) & 0xFF);
+ out[1] = (uint8_t)((in >> 8) & 0xFF);
+}
+
+static inline uint16_t uint16le_decode(uint8_t *in) {
+ return (((uint16_t)(in[0])) << 0)
+ | (((uint16_t)(in[1])) << 8)
+ ;
+}
+
+static inline uint16le_t uint16le_marshal(uint16_t in) {
+ uint16le_t out;
+ uint16le_encode(out.octets, in);
+ return out;
+}
+
+static inline uint16_t uint16le_unmarshal(uint16le_t in) {
+ return uint16le_decode(in.octets);
+}
+
+typedef struct {
+ uint8_t octets[4];
+} uint32le_t;
+static_assert(sizeof(uint32le_t) == 4);
+
+static inline void uint32le_encode(uint8_t *out, uint32_t in) {
+ out[0] = (uint8_t)((in >> 0) & 0xFF);
+ out[1] = (uint8_t)((in >> 8) & 0xFF);
+ out[2] = (uint8_t)((in >> 16) & 0xFF);
+ out[3] = (uint8_t)((in >> 24) & 0xFF);
+}
+
+static inline uint32_t uint32le_decode(uint8_t *in) {
+ return (((uint32_t)(in[0])) << 0)
+ | (((uint32_t)(in[1])) << 8)
+ | (((uint32_t)(in[2])) << 16)
+ | (((uint32_t)(in[3])) << 24)
+ ;
+}
+
+static inline uint32le_t uint32le_marshal(uint32_t in) {
+ uint32le_t out;
+ uint32le_encode(out.octets, in);
+ return out;
+}
+
+static inline uint32_t uint32le_unmarshal(uint32le_t in) {
+ return uint32le_decode(in.octets);
+}
+
+#endif /* _LIBMISC_ENDIAN_H_ */