From cec0dafe35f9ddb0892943389bc3050f0be8d56a Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 27 Aug 2025 00:12:50 +0200 Subject: [PATCH] Byte header --- byte_header.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 byte_header.c diff --git a/byte_header.c b/byte_header.c new file mode 100644 index 0000000..f0d44a6 --- /dev/null +++ b/byte_header.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +/* + * Pack header data into a byte. + * 3 bits are used for type (2^3 = 8 different types) + * 5 bits are used for length (2^5 = 32 max length, unit is up to you) + */ + +typedef enum { + Ok = 0, + OversizedType, + OversizedLen, +} Result; + +#define TYPE_LEN (4) +#define LEN (4) + +Result msg_create_header(uint8_t type, uint8_t len, uint8_t *out); +void msg_parse_header(uint8_t header, uint8_t *type_out, uint8_t *len_out); + +int main(void) { + assert(TYPE_LEN + LEN <= 8); + uint8_t maxlen = (1 << LEN) - 1; + uint8_t maxtype = (1 << TYPE_LEN) - 1; + + { + uint8_t hdr; + Result res = msg_create_header(3, 8, &hdr); + + if (res == OversizedType) + printf("The type is out of range"); + if (res == OversizedLen) + printf("The length is out of range"); + + printf("Header: 0x%02X\n", hdr); + printf("Error: %d\n", res); + + uint8_t plen, ptype; + msg_parse_header(hdr, &ptype, &plen); + printf("Type: %d\n", ptype); + printf("Len: %d\n", plen); + } + { + printf("Max len: %d\n", maxlen); + printf("Max type: %d\n", maxtype); + + uint8_t hdr; + Result res = msg_create_header(maxtype, maxlen, &hdr); + assert(res == Ok); + + uint8_t plen, ptype; + msg_parse_header(hdr, &ptype, &plen); + printf("plen: %d\n", plen); + printf("ptype: %d\n", ptype); + assert(ptype == maxtype); + assert(plen == maxlen); + } + { + for (int i = 0; i < 1000; i++) { + uint8_t len = arc4random() % maxlen; + uint8_t type = arc4random() % maxtype; + uint8_t hdr; + Result res = msg_create_header(type, len, &hdr); + assert(res == Ok); + + uint8_t plen, ptype; + msg_parse_header(hdr, &ptype, &plen); + assert(ptype == type); + assert(plen == len); + } + } + + return 0; +} + +Result msg_create_header(uint8_t type, uint8_t len, uint8_t *out) { + if (type > (1 << TYPE_LEN) - 1) + return OversizedType; + + if (len > (1 << LEN) - 1) + return OversizedLen; + + *out = (type << LEN) | (len & (0xFF >> TYPE_LEN)); + + return Ok; +} + +void msg_parse_header(uint8_t header, uint8_t *type_out, uint8_t *len_out) { + *type_out = (header >> LEN) & ((1 << LEN) - 1); + *len_out = header & (0xFF >> TYPE_LEN); +}