aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2025-04-19 01:01:46 +0300
committerkartofen <mladenovnasko0@gmail.com>2025-04-19 01:01:46 +0300
commit81b8e14fd785141193c62bcd0023815b2a6cb810 (patch)
tree5872f8bb3688d1c0aeaef5856720bd1faeac92e1
parent25792c81d9e4c1667ca6bcac28ae7b49afff90a1 (diff)
change unit conversions and writing as rawHEADmaster
-rw-r--r--msgpack.c146
-rw-r--r--test.c23
2 files changed, 87 insertions, 82 deletions
diff --git a/msgpack.c b/msgpack.c
index e30501c..c125a2d 100644
--- a/msgpack.c
+++ b/msgpack.c
@@ -2,36 +2,32 @@
#include <endian.h> // endianness
#include <string.h> // memcpy
-#define ITOF(bits, v) (((union {uint32_t u32; float f32; uint64_t u64; double f64;}){.u##bits = v}).f##bits)
-#define FTOI(bits, v) (((union {uint32_t u32; float f32; uint64_t u64; double f64;}){.f##bits = v}).u##bits)
+#define EXPAND_CALL(c, ...) c(__VA_ARGS__)
+#define CAR(a, b) a
+#define CDR(a, b) b
#define INT int
#define UINT uint
-#define F32 float // possibly remove
-#define F64 double // possibly remove
#define htobe8(i) (i)
#define be8toh(i) (i)
-#define __HTOI(bits, i) htobe##bits(i)
-#define __ITOH(bits, i) be##bits##toh(i)
+#define _HTOI(bits, i) htobe##bits(i)
+#define _ITOH(bits, i) be##bits##toh(i)
-#define _ITOH(type, bits, i) ((type)__ITOH(bits, i))
-#define _HTOI(type, bits, h) ((type)__HTOI(bits, h))
-#define _PTOH(type, bits, p) ((type)__ITOH(bits, (*(type *)(p))))
-#define _HTOP2(type, bits, h, p) ((*(type *)(p)) = __HTOI(bits, h))
-#define _PTOH_F(type, bits, p) ITOF(bits, _PTOH(uint##bits##_t, bits, p)) // possibly remove
-#define _HTOP2_F(type, bits, f, p) _HTOP2(uint##bits##_t, bits, FTOI(bits, f), p) // possibly remove
+#define CONV_ALL(...) __VA_ARGS__
+#define CONV_TYPE(t, b) t##b##_t
+#define CONV_BITS(t, b) b
-#define EXPAND_CALL(c, ...) c(__VA_ARGS__)
-#define EXPAND_CONV1(t, b) t##b##_t, b
-#define EXPAND_CONV2(b) F##b, b
+#define ITOH(c, i) ((CONV_TYPE c)EXPAND_CALL(_ITOH, CONV_BITS c, i))
+#define HTOI(c, h) ((CONV_TYPE c)EXPAND_CALL(_HTOI, CONV_BITS c, i))
+#define PTOH(c, p) ((CONV_TYPE c)EXPAND_CALL(_ITOH, CONV_BITS c, (*(CONV_TYPE c*)(p))))
+#define HTOP2(c, h, p) (((*(CONV_TYPE c *)(p)) = EXPAND_CALL(_HTOI, CONV_BITS c, h)))
-#define ITOH(c, i) EXPAND_CALL(_TTOH, EXPAND_CONV1 c, i)
-#define HTOI(c, h) EXPAND_CALL(_HTOH, EXPAND_CONV1 c, h)
-#define PTOH(c, p) EXPAND_CALL(_PTOH, EXPAND_CONV1 c, p)
-#define HTOP2(c, h, p) EXPAND_CALL(_HTOP2, EXPAND_CONV1 c, h, p)
-#define PTOH_F(c, p) EXPAND_CALL(_PTOH_F, EXPAND_CONV2 c, p) // possibly remove
-#define HTOP2_F(c, f, p) EXPAND_CALL(_HTOP2_F, EXPAND_CONV2 c, f, p) // possibly remove
+#define ITOF(bits, v) (((union {uint32_t u32; float f32; uint64_t u64; double f64;}){.u##bits = v}).f##bits)
+#define FTOI(bits, v) (((union {uint32_t u32; float f32; uint64_t u64; double f64;}){.f##bits = v}).u##bits)
+
+#define PTOH_F(c, p) EXPAND_CALL(ITOF, CONV_ALL c, PTOH((UINT, CONV_ALL c), p)) // possibly remove
+#define HTOP2_F(c, f, p) HTOP2((UINT, CONV_ALL c), EXPAND_CALL(FTOI, CONV_ALL c, f), p) // possibly remove
// range low, range high
#define RANGES(X) \
@@ -52,33 +48,33 @@
X(0xC2, FMT_BOOL_TRUE, MSGPACK_BOOL, true) \
X(0xC3, FMT_BOOL_FALSE, MSGPACK_BOOL, false)
-// byte, format, type, subtype, offset, lengh, field, conv, range high, range low
+// byte, format, type, subtype, offset, lengh, field, conv, range
#define FORMAT_INT(X) \
- X(0x00, FMT_FIX_UINT, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 0, 1, u, (UINT, 8), 0, 127) \
- X(0XE0, FMT_FIX_INT, MSGPACK_INT, MSGPACK_INT_SIGNED, 0, 1, i, (INT, 8), -32, -1) \
- X(0xCC, FMT_U8, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 1, u, (UINT, 8), 0, UINT8_MAX) \
- X(0xCD, FMT_U16, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 2, u, (UINT, 16), 0, UINT16_MAX) \
- X(0xCE, FMT_U32, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 4, u, (UINT, 32), 0, UINT32_MAX) \
- X(0xCF, FMT_U64, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 8, u, (UINT, 64), 0, UINT64_MAX) \
- X(0xD0, FMT_I8, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 1, i, (INT, 8), INT8_MIN, INT8_MAX) \
- X(0xD1, FMT_I16, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 2, i, (INT, 16), INT16_MIN, INT16_MAX) \
- X(0xD2, FMT_I32, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 4, i, (INT, 32), INT32_MIN, INT32_MAX) \
- X(0xD3, FMT_I64, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 8, i, (INT, 64), INT64_MIN, INT64_MAX)
+ X(0x00, FMT_FIX_UINT, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 0, 1, u, (UINT, 8), (0, 127)) \
+ X(0XE0, FMT_FIX_INT, MSGPACK_INT, MSGPACK_INT_SIGNED, 0, 1, i, (INT, 8), (-32, -1)) \
+ X(0xCC, FMT_U8, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 1, u, (UINT, 8), (0, UINT8_MAX)) \
+ X(0xCD, FMT_U16, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 2, u, (UINT, 16), (0, UINT16_MAX)) \
+ X(0xCE, FMT_U32, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 4, u, (UINT, 32), (0, UINT32_MAX)) \
+ X(0xCF, FMT_U64, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 8, u, (UINT, 64), (0, UINT64_MAX)) \
+ X(0xD0, FMT_I8, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 1, i, (INT, 8), (INT8_MIN, INT8_MAX)) \
+ X(0xD1, FMT_I16, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 2, i, (INT, 16), (INT16_MIN, INT16_MAX)) \
+ X(0xD2, FMT_I32, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 4, i, (INT, 32), (INT32_MIN, INT32_MAX)) \
+ X(0xD3, FMT_I64, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 8, i, (INT, 64), (INT64_MIN, INT64_MAX))
// byte, format, type, subtype, offset, length, field, conv
#define FORMAT_FLOAT(X) \
X(0xCA, FMT_FLOAT, MSGPACK_FLOAT, MSGPACK_FLOAT_32, 1, 4, f, (32)) \
X(0xCB, FMT_DOUBLE, MSGPACK_FLOAT, MSGPACK_FLOAT_64, 1, 8, d, (64))
-// byte, fmt, type, subtype, offset, conv
+// byte, fmt, type, subtype, offset, conv, max
#define FORMAT_RAW(X) \
- X(0xA0, FMT_FIX_STR, MSGPACK_RAW, MSGPACK_RAW_STRING, 1, (UINT, 8)) \
- X(0xC4, FMT_BIN8, MSGPACK_RAW, MSGPACK_RAW_BIN, 2, (UINT, 8)) \
- X(0xC5, FMT_BIN16, MSGPACK_RAW, MSGPACK_RAW_BIN, 3, (UINT, 16)) \
- X(0xC6, FMT_BIN32, MSGPACK_RAW, MSGPACK_RAW_BIN, 5, (UINT, 32)) \
- X(0xD9, FMT_STR8, MSGPACK_RAW, MSGPACK_RAW_STRING, 2, (UINT, 8)) \
- X(0xDA, FMT_STR16, MSGPACK_RAW, MSGPACK_RAW_STRING, 3, (UINT, 16)) \
- X(0xDB, FMT_STR32, MSGPACK_RAW, MSGPACK_RAW_STRING, 5, (UINT, 32))
+ X(0xA0, FMT_FIX_STR, MSGPACK_RAW, MSGPACK_RAW_STRING, 1, (UINT, 8), 31) \
+ X(0xC4, FMT_BIN8, MSGPACK_RAW, MSGPACK_RAW_BIN, 2, (UINT, 8), UINT8_MAX) \
+ X(0xC5, FMT_BIN16, MSGPACK_RAW, MSGPACK_RAW_BIN, 3, (UINT, 16), UINT16_MAX) \
+ X(0xC6, FMT_BIN32, MSGPACK_RAW, MSGPACK_RAW_BIN, 5, (UINT, 32), UINT32_MAX) \
+ X(0xD9, FMT_STR8, MSGPACK_RAW, MSGPACK_RAW_STRING, 2, (UINT, 8), UINT8_MAX) \
+ X(0xDA, FMT_STR16, MSGPACK_RAW, MSGPACK_RAW_STRING, 3, (UINT, 16), UINT16_MAX) \
+ X(0xDB, FMT_STR32, MSGPACK_RAW, MSGPACK_RAW_STRING, 5, (UINT, 32), UINT32_MAX)
// // byte, fmt, type, elements, offset, lenght
// #define FORMAT_ARRAY(X) \
@@ -119,9 +115,6 @@ static const enum msgpack_fmt byte_to_fmt[] = {
FORMATS(X_BYTE_FMT)
};
-// static size_t elements_length(msgpack_t *pack, enum msgpack_fmt fmt);
-// static size_t pack_size(msgpack_t *pack);
-
// --- helper macros --- //
@@ -171,6 +164,8 @@ const enum msgpack_type subtype;
} \
}
+// TODO: refactor these things, they are hard to read
+
#define OP_BOOL_READ(x_byte, pack, m, x_data) \
*m = x_data
#define OP_BOOL_WRITE(x_byte, pack, m, x_data) \
@@ -203,50 +198,47 @@ const enum msgpack_type subtype;
MOVE_PACK(pack, (x_offset) + (x_length)); \
return SUCCESS2(x_type, x_subtype);
-#define X_RAW_READ(_byte, x_fmt, x_type, x_subtype, x_offset, x_conv) \
- case x_fmt: { \
- ENOUGH_BYTES(pack, (x_offset), \
- return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \
- size_t length = (x_fmt == FMT_FIX_STR) ? PTOH(x_conv, pack->bin) & 0x0F \
- : PTOH(x_conv, pack->bin + 1); \
- ENOUGH_BYTES(pack, (x_offset) + length, \
- return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \
- \
- m->size = length; \
- m->bin = pack->bin + (x_offset); \
- \
- MOVE_PACK(pack, (x_offset) + length); \
- return SUCCESS2(x_type, x_subtype); \
- }
+#define OP_RAW_LENGTH_READ(x_fmt, x_conv) \
+ (x_fmt == FMT_FIX_STR) ? PTOH(x_conv, pack->bin) & 0x1F \
+ : PTOH(x_conv, pack->bin + 1);
+
+#define OP_RAW_LENGTH_WRITE(x_fmt, x_conv) m->size
+
+#define OP_RAW_READ(x_byte, x_offset, x_conv) \
+ m->size = length; \
+ m->bin = pack->bin + (x_offset);
+
+#define OP_RAW_WRITE(x_byte, x_offset, x_conv) \
+ pack->bin[0] = x_byte; \
+ if (fmt == FMT_FIX_STR) pack->bin[0] |= (uint8_t)length; \
+ else HTOP2(x_conv, length, pack->bin+1); \
+ memcpy(pack->bin+(x_offset), m->bin, m->size);
-#define X_RAW_WRITE(x_byte, x_fmt, x_type, x_subtype, x_offset, x_conv) \
+#define MAKE_X_RAW(op, x_byte, x_fmt, x_type, x_subtype, x_offset, x_conv, ...) \
case x_fmt: { \
ENOUGH_BYTES(pack, (x_offset), \
return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \
- size_t length = *m; \
+ size_t length = OP_RAW_LENGTH_##op(x_fmt, x_conv); \
+ \
ENOUGH_BYTES(pack, (x_offset) + length, \
return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \
- \
- pack->bin[0] = x_byte; \
- if (fmt == FMT_FIX_STR) { \
- pack->bin[0] |= (uint8_t)length; \
- } else { \
- HTOP2(x_conv, length, pack->bin+1); \
- } \
+ OP_RAW_##op(x_byte, x_offset, x_conv); \
\
MOVE_PACK(pack, (x_offset) + length); \
return SUCCESS2(x_type, x_subtype); \
- }
-
+ }
+
// --- api implemention --- //
#define X_BOOL_READ(...) MAKE_X_BOOL(READ, __VA_ARGS__)
#define X_INT_READ(...) MAKE_X_INTORFLOAT(INT, READ, __VA_ARGS__)
#define X_FLOAT_READ(...) MAKE_X_INTORFLOAT(FLOAT, READ, __VA_ARGS__)
+#define X_RAW_READ(...) MAKE_X_RAW(READ, __VA_ARGS__)
#define X_BOOL_WRITE(...) MAKE_X_BOOL(WRITE, __VA_ARGS__)
#define X_INT_WRITE(...) MAKE_X_INTORFLOAT(INT, WRITE, __VA_ARGS__)
#define X_FLOAT_WRITE(...) MAKE_X_INTORFLOAT(FLOAT, WRITE, __VA_ARGS__)
+#define X_RAW_WRITE(...) MAKE_X_RAW(WRITE, __VA_ARGS__)
// int msgpack_read_nil (msgpack_t *pack);
int msgpack_read_bool (msgpack_t *pack, bool *m) COMPOSE_FUNCTION(READ, BOOL)
@@ -269,7 +261,7 @@ int msgpack_write_bool (msgpack_t *pack, const bool *m) COMPOSE_FUN
int msgpack_write_int (msgpack_t *pack, const union mp_int *m, enum msgpack_type subtype) COMPOSE_FUNCTION(WRITE, INT)
int msgpack_write_float (msgpack_t *pack, const union mp_float *m, enum msgpack_type subtype) COMPOSE_FUNCTION(WRITE, FLOAT)
-// int msgpack_write_raw (msgpack_t *pack, const struct mp_bin *m, enum msgpack_type subtype);
+int msgpack_write_raw (msgpack_t *pack, const struct mp_bin *m, enum msgpack_type subtype) COMPOSE_FUNCTION(WRITE, RAW)
// int msgpack_write_ext (msgpack_t *pack, const struct mp_bin *m, enum msgpack_type subtype);
// int msgpack_write_array (msgpack_t *pack, const size_t *m);
@@ -298,10 +290,10 @@ static enum msgpack_fmt pack_fmt(msgpack_t *pack)
#define WRAP_FMT_INT(e) \
case MSGPACK_INT: e; break;
-#define X_FMT_INT(_byte, x_fmt, x_type, x_subtype, _offset, _length, x_field, _conv, x_range_low, x_range_high) \
+#define X_FMT_INT(_byte, x_fmt, x_type, x_subtype, _offset, _length, x_field, _conv, x_range) \
if((x_subtype == subtype) && \
- (((union mp_int *)m)->x_field >= x_range_low) && \
- (((union mp_int *)m)->x_field <= x_range_high)) \
+ (((union mp_int *)m)->x_field >= CAR x_range) && \
+ (((union mp_int *)m)->x_field <= CDR x_range)) \
return x_fmt; \
else
@@ -310,7 +302,12 @@ static enum msgpack_fmt pack_fmt(msgpack_t *pack)
#define X_FMT_FLOAT(_byte, x_fmt, _type, x_subtype, _offset, _length, _field, _conv) \
case x_subtype: return x_fmt;
-// TODO: add X_FMT_RAW
+#define WRAP_FMT_RAW(e) \
+ case MSGPACK_RAW: e; break;
+#define X_FMT_RAW(_byte, x_fmt, x_type, x_subtype, _offset, _conv, x_range_max) \
+ if((x_subtype == subtype) && \
+ ((struct mp_bin *)m)->size <= x_range_max) return x_fmt; \
+ else
static enum msgpack_fmt data_fmt(enum msgpack_type type, enum msgpack_type subtype, const void *m)
{
@@ -318,6 +315,7 @@ static enum msgpack_fmt data_fmt(enum msgpack_type type, enum msgpack_type subty
WRAP_FMT_BOOL(FORMAT_BOOL(X_FMT_BOOL))
WRAP_FMT_INT(FORMAT_INT(X_FMT_INT))
WRAP_FMT_FLOAT(FORMAT_FLOAT(X_FMT_FLOAT))
+ WRAP_FMT_RAW(FORMAT_RAW(X_FMT_RAW))
default: return FMT_UNKNOWN;
}
diff --git a/test.c b/test.c
index 4ee5298..6b405dd 100644
--- a/test.c
+++ b/test.c
@@ -140,7 +140,7 @@ int main(void)
logvar(e, msgpack_error_string[e], "%s"); \
if(e == MSGPACK_ERROR_WRONG_TYPE) \
logvar(a, msgpack_type_string[a], "%s"); \
- else logvar(a, "%hhx"); \
+ else logvar(a, "0x%hhx"); \
return; \
}
@@ -303,18 +303,25 @@ int test_float()
return failed_asserts;
}
-void raw_1(uint8_t *bin, size_t size, struct mp_bin b)
+void raw_1(uint8_t *bin, size_t size, struct mp_bin r)
{
- msgpack_t pack = msgpack_init(bin, size, NULL);
+ uint8_t b[64] = {0};
struct mp_bin v = {0};
- MSGPACK_CHECK2(msgpack_read_raw(&pack, &v), (t, e, a),
+ MSGPACK_CHECK2(msgpack_read_raw(&msgpack_init(bin, size, NULL), &v),
+ (t, e, a),
BODY_SUCCESS_2(t, a, MSGPACK_RAW, MSGPACK_RAW_STRING),
BODY_FAILED_1(t, e, a));
- assert(v.size == b.size, logvar(v.size, "%z"));
- assert(memcmp(v.bin, b.bin, v.size) == 0, logbytes(v.bin, v.size));
+ assert(v.size == r.size, logvar(v.size, "%zu"));
+ assert(memcmp(v.bin, r.bin, v.size) == 0, logbytes(v.bin, v.size));
+ MSGPACK_CHECK2(msgpack_write_raw(&msgpack_init(b, sizeof(b), NULL), &r, MSGPACK_RAW_STRING),
+ (t, e, a),
+ BODY_SUCCESS_2(t, a, MSGPACK_RAW, MSGPACK_RAW_STRING),
+ BODY_FAILED_1(t, e, a));
+
+ assert(memcmp(b, bin, size) == 0, logbytes(b, size));
}
int test_raw()
@@ -322,8 +329,8 @@ int test_raw()
failed_asserts = 0;
check_condition(raw_1("\xa5hello", 6,
(struct mp_bin){.size = 5, .bin = "hello"}), );
- check_condition(raw_1("\xd9\x05hello", 7,
- (struct mp_bin){.size = 5, .bin = "hello"}), );
+ check_condition(raw_1("\xd9\x24hello_______________________________", 38,
+ (struct mp_bin){.size = 36, .bin = "hello_______________________________"}), );
return failed_asserts;
}