aboutsummaryrefslogtreecommitdiff
path: root/msgpack.c
diff options
context:
space:
mode:
Diffstat (limited to 'msgpack.c')
-rw-r--r--msgpack.c284
1 files changed, 122 insertions, 162 deletions
diff --git a/msgpack.c b/msgpack.c
index 70cd463..e30501c 100644
--- a/msgpack.c
+++ b/msgpack.c
@@ -2,36 +2,36 @@
#include <endian.h> // endianness
#include <string.h> // 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;
-// }