From 25792c81d9e4c1667ca6bcac28ae7b49afff90a1 Mon Sep 17 00:00:00 2001 From: kartofen Date: Fri, 18 Apr 2025 23:17:29 +0300 Subject: floats, raws, more testing --- msgpack.c | 284 +++++++++++++++++++++++++++----------------------------------- 1 file changed, 122 insertions(+), 162 deletions(-) (limited to 'msgpack.c') diff --git a/msgpack.c b/msgpack.c index 70cd463..e30501c 100644 --- a/msgpack.c +++ b/msgpack.c @@ -2,36 +2,36 @@ #include // endianness #include // memcpy -#define PINT8_H(p) (*(int8_t*)(p)) -#define PINT16_H(p) ((int16_t)be16toh(*(uint16_t *)(p))) -#define PINT32_H(p) ((int32_t)be32toh(*(uint32_t *)(p))) -#define PINT64_H(p) ((int64_t)be64toh(*(uint64_t *)(p))) - -#define PUINT8_H(p) (*(uint8_t*)(p)) -#define PUINT16_H(p) (be16toh(*(uint16_t *)(p))) -#define PUINT32_H(p) (be32toh(*(uint32_t *)(p))) -#define PUINT64_H(p) (be64toh(*(uint64_t *)(p))) - -#define H_UINT8(b) ((uint8_t)b) -#define H_UINT16(b) ((uint16_t)htobe16((uint16_t)(b))) -#define H_UINT32(b) ((uint32_t)htobe32((uint32_t)(b))) -#define H_UINT64(b) ((uint64_t)htobe64((uint64_t)(b))) - -#define H_UINT8_CPY(b, p) (((uint8_t*)(p))[0] = H_UINT8(b)); -#define H_UINT16_CPY(b, p) (((uint16_t*)(p))[0] = H_UINT16(b)) -#define H_UINT32_CPY(b, p) (((uint32_t*)(p))[0] = H_UINT32(b)) -#define H_UINT64_CPY(b, p) (((uint64_t*)(p))[0] = H_UINT64(b)) - -#define H_INT8_CPY(b, p) H_UINT8_CPY(b, p) -#define H_INT16_CPY(b, p) H_UINT16_CPY(b, p) -#define H_INT32_CPY(b, p) H_UINT32_CPY(b, p) -#define H_INT64_CPY(b, p) H_UINT64_CPY(b, p) - -// fix these -// #define F32_H(b) (*(float *) &be32toh(*(uint32_t *)(b))) -// #define F64_H(b) (*(double *)&be64toh(*(uint64_t *)(b))) -// #define H_F32(b) (*(float *) &htobe32(*(uint32_t *)(b))) -// #define H_F64(b) (*(double *)&htobe64(*(uint64_t *)(b))) +#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 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 _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 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) 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 // range low, range high #define RANGES(X) \ @@ -53,32 +53,32 @@ X(0xC3, FMT_BOOL_FALSE, MSGPACK_BOOL, false) // byte, format, type, subtype, offset, lengh, field, conv, range high, range low -#define FORMAT_INT(X) \ - X(0x00, FMT_FIX_UINT, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 0, 1, u, UINT8, 0, 127) \ - X(0XE0, FMT_FIX_INT, MSGPACK_INT, MSGPACK_INT_SIGNED, 0, 1, i, INT8, -32, -1) \ - X(0xCC, FMT_U8, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 1, u, UINT8, 0, UINT8_MAX) \ - X(0xCD, FMT_U16, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 2, u, UINT16, 0, UINT16_MAX) \ - X(0xCE, FMT_U32, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 4, u, UINT32, 0, UINT32_MAX) \ - X(0xCF, FMT_U64, MSGPACK_INT, MSGPACK_INT_UNSIGNED, 1, 8, u, UINT64, 0, UINT64_MAX) \ - X(0xD0, FMT_I8, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 1, i, INT8, INT8_MIN, INT8_MAX) \ - X(0xD1, FMT_I16, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 2, i, INT16, INT16_MIN, INT16_MAX) \ - X(0xD2, FMT_I32, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 4, i, INT32, INT32_MIN, INT32_MAX) \ - X(0xD3, FMT_I64, MSGPACK_INT, MSGPACK_INT_SIGNED, 1, 8, i, INT64, INT64_MIN, INT64_MAX) +#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) // byte, format, type, subtype, offset, length, field, conv #define FORMAT_FLOAT(X) \ - X(0xCA, FMT_FLOAT, MSGPACK_FLOAT, MSGPACK_FLOAT_32, 1, 4, f, F32) \ - X(0xCB, FMT_DOUBLE, MSGPACK_FLOAT, MSGPACK_FLOAT_64, 1, 8, d, F64) - -// // byte, fmt, type, subtype, offset, length, data -// #define FORMAT_RAW(X) \ -// X(0xA0, FMT_FIX_STR, MSGPACK_RAW, MSGPACK_RAW_STRING, 1, pack->bin[0] & 0x0F) \ -// X(0xC4, FMT_BIN8, MSGPACK_RAW, MSGPACK_RAW_BIN, 1, pack->bin[1]) \ -// X(0xC5, FMT_BIN16, MSGPACK_RAW, MSGPACK_RAW_BIN, 3, UINT16_H(pack->bin+1)) \ -// X(0xC6, FMT_BIN32, MSGPACK_RAW, MSGPACK_RAW_BIN, 5, UINT32_H(pack->bin+1)) \ -// X(0xD9, FMT_STR8, MSGPACK_RAW, MSGPACK_RAW_STRING, 1, pack->bin[1]) \ -// X(0xDA, FMT_STR16, MSGPACK_RAW, MSGPACK_RAW_STRING, 3, UINT16_H(pack->bin+1)) \ -// X(0xDB, FMT_STR32, MSGPACK_RAW, MSGPACK_RAW_STRING, 5, UINT32_H(pack->bin+1)) + 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 +#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)) // // byte, fmt, type, elements, offset, lenght // #define FORMAT_ARRAY(X) \ @@ -98,7 +98,7 @@ FORMAT_BOOL (X) \ FORMAT_INT (X) \ FORMAT_FLOAT (X) \ - // FORMAT_RAW (X) \ + FORMAT_RAW (X) \ // FORMAT_ARRAY (X) \ // FORMAT_MAP (X) \ // FORMAT_EXT (X) @@ -142,7 +142,7 @@ static const enum msgpack_fmt byte_to_fmt[] = { } while(0) static enum msgpack_fmt pack_fmt(msgpack_t *pack); -static enum msgpack_fmt data_fmt(enum msgpack_type type, enum msgpack_type subtype, void *m); +static enum msgpack_fmt data_fmt(enum msgpack_type type, enum msgpack_type subtype, const void *m); #define FMT_FOR_READ(pack, type, subtype, m) pack_fmt(pack) #define FMT_FOR_WRITE(pack, type, subtype, m) data_fmt(type, subtype, m) @@ -160,7 +160,7 @@ const enum msgpack_type subtype; if(!m) \ return ERROR(MSGPACK_##type, MSGPACK_ERROR_INVALID_ARGUMENT); \ \ - enum msgpack_fmt fmt = \ + const enum msgpack_fmt fmt = \ FMT_FOR_##op(pack, MSGPACK_##type, subtype, m); \ \ switch(fmt) { \ @@ -183,32 +183,77 @@ const enum msgpack_type subtype; return SUCCESS(x_type); #define OP_INT_READ(_byte, ptr, value, x_conv) \ - value = P##x_conv##_H(ptr) + value = PTOH(x_conv, ptr) #define OP_INT_WRITE(x_byte, ptr, value, x_conv) \ (ptr-1)[0] = x_byte; /* temp fix*/ \ - H_##x_conv##_CPY((value), (ptr)) + HTOP2(x_conv, value, ptr) -#define MAKE_X_INT(op, x_byte, x_fmt, x_type, x_subtype, x_offset, x_length, x_field, x_conv, ...) \ +#define OP_FLOAT_READ(_byte, ptr, value, x_conv) \ + value = PTOH_F(x_conv, ptr) +#define OP_FLOAT_WRITE(x_byte, ptr, value, x_conv) \ + (ptr-1)[0] = x_byte; /* temp fix*/ \ + HTOP2_F(x_conv, value, ptr) + +#define MAKE_X_INTORFLOAT(type, op, x_byte, x_fmt, x_type, x_subtype, x_offset, x_length, x_field, x_conv, ...) \ case x_fmt: \ ENOUGH_BYTES(pack, (x_offset) + (x_length), \ return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \ - OP_INT_##op(x_byte, pack->bin + (x_offset), m->x_field, x_conv); \ + OP_##type##_##op(x_byte, pack->bin + (x_offset), m->x_field, x_conv); \ \ 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 X_RAW_WRITE(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; \ + 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); \ + } \ + \ + 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_INT(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__) -int msgpack_read_nil (msgpack_t *pack);// COMPOSE_FUNCTION(READ, NIL) +#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__) + +// int msgpack_read_nil (msgpack_t *pack); int msgpack_read_bool (msgpack_t *pack, bool *m) COMPOSE_FUNCTION(READ, BOOL) int msgpack_read_int (msgpack_t *pack, union mp_int *m) COMPOSE_FUNCTION(READ, INT) -// int msgpack_read_float (msgpack_t *pack, union mp_float *m); COMPOSE_FUNCTION(READ, FLOAT) +int msgpack_read_float (msgpack_t *pack, union mp_float *m) COMPOSE_FUNCTION(READ, FLOAT) -// int msgpack_read_raw (msgpack_t *pack, struct mp_bin *m) COMPOSE_FUNCTION(READ, RAW) +int msgpack_read_raw (msgpack_t *pack, struct mp_bin *m) COMPOSE_FUNCTION(READ, RAW) // int msgpack_read_raw_cpy (msgpack_t *pack, struct mp_bin *m); // int msgpack_read_ext (msgpack_t *pack, struct mp_bin *m) COMPOSE_FUNCTION(READ, EXT) // int msgpack_read_ext_cpy (msgpack_t *pack, struct mp_bin *m); @@ -218,13 +263,11 @@ int msgpack_read_int (msgpack_t *pack, union mp_int *m) COMPOSE_FUNCTION(RE // int msgpack_read_array2 (const msgpack_t *pack, struct mp_array *m); // int msgpack_read_map2 (const msgpack_t *pack, struct mp_map *m); -#define X_BOOL_WRITE(...) MAKE_X_BOOL(WRITE, __VA_ARGS__) -#define X_INT_WRITE(...) MAKE_X_INT(WRITE, __VA_ARGS__) - -int msgpack_write_nil (msgpack_t *pack); + +// int msgpack_write_nil (msgpack_t *pack); int msgpack_write_bool (msgpack_t *pack, const bool *m) COMPOSE_FUNCTION(WRITE, BOOL) 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); +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_ext (msgpack_t *pack, const struct mp_bin *m, enum msgpack_type subtype); @@ -249,7 +292,7 @@ static enum msgpack_fmt pack_fmt(msgpack_t *pack) } #define WRAP_FMT_BOOL(e) \ - case MSGPACK_BOOL: switch(*(bool *)m) {e; default: break; } break; + case MSGPACK_BOOL: switch((int)*(bool *)m) {e; default: break; } break; #define X_FMT_BOOL(_byte, x_fmt, x_type, x_data) \ case x_data: return x_fmt; @@ -262,104 +305,21 @@ static enum msgpack_fmt pack_fmt(msgpack_t *pack) return x_fmt; \ else -static enum msgpack_fmt data_fmt(enum msgpack_type type, enum msgpack_type subtype, void *m) +#define WRAP_FMT_FLOAT(e) \ + case MSGPACK_FLOAT: switch(subtype) {e; default: break; } break; +#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 + +static enum msgpack_fmt data_fmt(enum msgpack_type type, enum msgpack_type subtype, const void *m) { switch(type) { WRAP_FMT_BOOL(FORMAT_BOOL(X_FMT_BOOL)) WRAP_FMT_INT(FORMAT_INT(X_FMT_INT)) + WRAP_FMT_FLOAT(FORMAT_FLOAT(X_FMT_FLOAT)) default: return FMT_UNKNOWN; } return FMT_UNKNOWN; } - - - -// #define X_FLOAT(...) X_INT(__VA_ARGS__) - -// #define OP_RAW_READ(x_byte, pack, m, x_offset, x_length) \ -// m->bin = pack->bin + (x_offset); \ -// m->size = (x_length); \ - -// #define X_READ_RAW(op, x_byte, x_fmt, x_type, x_subtype, x_offset, x_length_expr) \ -// case x_fmt: \ -// ENOUGH_BYTES(pack, (x_offset), \ -// return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \ -// size_t length = x_length_expr; \ -// ENOUGH_BYTES(pack, (size_t)(x_offset) + (x_length), \ -// return ERROR2(x_type, MSGPACK_ERROR_UNEXPECTED_END, x_subtype)); \ -// OP_RAW_##op(x_byte, pack, m, (x_offset), (x_length)); \ -// \ -// MOVE_PACK(pack, (x_offset) + (x_length)); \ -// return SUCCESS2(x_type, x_subtype); - -// #define X_READ_EXT(...) //X_READ_RAW(__VA_ARGS__) - -// #define X_READ_ARRAY(_byte, x_fmt, x_type, x_elements, x_offset, _length) \ -// case x_fmt: \ -// ENOUGH_BYTES(pack, (x_offset), \ -// return ERROR(x_type, MSGPACK_ERROR_UNEXPECTED_END)); \ -// *m = x_elements; \ -// \ -// MOVE_PACK(pack, (x_offset)); \ -// return SUCCESS(x_type); - -// #define X_READ_MAP(...) X_READ_ARRAY(__VA_ARGS__) - - - -// #define X_COMPLEX_LENGTH(_byte, x_fmt, _type, x_elements, x_offset, x_length) \ -// case x_fmt: { \ -// ENOUGH_BYTES(pack, (x_offset), return 0); \ -// offset = (x_offset); \ -// elements = (x_elements); \ -// } break; - -// static size_t elements_length(msgpack_t *pack, enum msgpack_fmt fmt) -// { -// size_t offset = 0; -// size_t elements = 0; - -// switch(fmt) { -// FORMAT_ARRAY(X_COMPLEX_LENGTH) -// FORMAT_MAP(X_COMPLEX_LENGTH) -// default: return 0; -// } - -// for(size_t i = 0; i < elements; i++) { -// msgpack_t new_pack = {pack->bin + offset, -// pack->size - offset};//, pack->membuf}; -// size_t len = pack_size(&new_pack); -// if(len == 0) return 0; - -// offset += len; -// ENOUGH_BYTES(pack, offset, return 0); -// } - -// return offset; -// } - -// #define X_PACK_SIZE(_byte, x_fmt, _type, _, x_offset, x_length, ...) \ -// case x_fmt: { \ -// ENOUGH_BYTES(pack, (x_offset), return 0); \ -// offset = (x_offset); \ -// length = (x_length); \ -// } break; - -// static size_t pack_size(msgpack_t *pack) -// { -// enum msgpack_fmt fmt = pack_fmt(pack); - -// size_t offset = 0; -// size_t length = 0; - -// switch(fmt) { -// FORMATS(X_PACK_SIZE) -// default: return 0; -// } - -// if(fmt_to_type[fmt] == MSGPACK_ARRAY || fmt_to_type[fmt] == MSGPACK_MAP) -// if(length == 0) return 0; - -// return offset + length; -// } -- cgit v1.2.3