diff options
Diffstat (limited to 'libmisc')
-rw-r--r-- | libmisc/include/libmisc/endian.h | 129 |
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_ */ |