diff --git a/include/msgpack/object.h b/include/msgpack/object.h index 560008fe..3d0d1225 100644 --- a/include/msgpack/object.h +++ b/include/msgpack/object.h @@ -69,6 +69,12 @@ typedef struct { const char* ptr; } msgpack_object_bin; +typedef struct { + int8_t type; + uint32_t size; + const char* ptr; +} msgpack_object_ext; + typedef union { bool boolean; uint64_t u64; @@ -78,6 +84,7 @@ typedef union { msgpack_object_map map; msgpack_object_str str; msgpack_object_bin bin; + msgpack_object_ext ext; } msgpack_object_union; typedef struct msgpack_object { diff --git a/include/msgpack/pack.h b/include/msgpack/pack.h index d19c3014..ea0fbf70 100644 --- a/include/msgpack/pack.h +++ b/include/msgpack/pack.h @@ -100,6 +100,9 @@ static int msgpack_pack_str_body(msgpack_packer* pk, const void* b, size_t l); static int msgpack_pack_bin(msgpack_packer* pk, size_t l); static int msgpack_pack_bin_body(msgpack_packer* pk, const void* b, size_t l); +static int msgpack_pack_ext(msgpack_packer* pk, size_t l, int8_t type); +static int msgpack_pack_ext_body(msgpack_packer* pk, const void* b, size_t l); + int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); diff --git a/include/msgpack/pack_template.h b/include/msgpack/pack_template.h index f86f6e8d..9426a217 100644 --- a/include/msgpack/pack_template.h +++ b/include/msgpack/pack_template.h @@ -803,6 +803,73 @@ msgpack_pack_inline_func(_bin_body)(msgpack_pack_user x, const void* b, size_t l msgpack_pack_append_buffer(x, (const unsigned char*)b, l); } +/* + * Ext + */ + +msgpack_pack_inline_func(_ext)(msgpack_pack_user x, size_t l, int8_t type) +{ + switch(l) { + case 1: { + char buf[2]; + buf[0] = 0xd4; + buf[1] = type; + msgpack_pack_append_buffer(x, buf, 2); + } break; + case 2: { + char buf[2]; + buf[0] = 0xd5; + buf[1] = type; + msgpack_pack_append_buffer(x, buf, 2); + } break; + case 4: { + char buf[2]; + buf[0] = 0xd6; + buf[1] = type; + msgpack_pack_append_buffer(x, buf, 2); + } break; + case 8: { + char buf[2]; + buf[0] = 0xd7; + buf[1] = type; + msgpack_pack_append_buffer(x, buf, 2); + } break; + case 16: { + char buf[2]; + buf[0] = 0xd8; + buf[1] = type; + msgpack_pack_append_buffer(x, buf, 2); + } break; + default: + l += 1; + if(l < 256) { + char buf[3]; + buf[0] = 0xc7; + buf[1] = l; + buf[2] = type; + msgpack_pack_append_buffer(x, buf, 3); + } else if(l < 65536) { + char buf[4]; + buf[0] = 0xc8; + _msgpack_store16(&buf[1], l); + buf[3] = type; + msgpack_pack_append_buffer(x, buf, 4); + } else { + char buf[6]; + buf[0] = 0xc9; + _msgpack_store32(&buf[1], l); + buf[5] = type; + msgpack_pack_append_buffer(x, buf, 6); + } + break; + } +} + +msgpack_pack_inline_func(_ext_body)(msgpack_pack_user x, const void* b, size_t l) +{ + msgpack_pack_append_buffer(x, (const unsigned char*)b, l); +} + #undef msgpack_pack_inline_func #undef msgpack_pack_user #undef msgpack_pack_append_buffer diff --git a/include/msgpack/unpack_template.h b/include/msgpack/unpack_template.h index 598f552f..7e50692f 100644 --- a/include/msgpack/unpack_template.h +++ b/include/msgpack/unpack_template.h @@ -205,9 +205,10 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c case 0xc5: // bin 16 case 0xc6: // bin 32 again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); - //case 0xc7: - //case 0xc8: - //case 0xc9: + case 0xc7: // ext 8 + case 0xc8: // ext 16 + case 0xc9: // ext 32 + again_fixed_trail(NEXT_CS(p), 1 << ((((unsigned int)*p) + 1) & 0x03)); case 0xca: // float case 0xcb: // double case 0xcc: // unsigned int 8 @@ -219,11 +220,15 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c case 0xd2: // signed int 32 case 0xd3: // signed int 64 again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); - //case 0xd4: - //case 0xd5: - //case 0xd6: // big integer 16 - //case 0xd7: // big integer 32 - //case 0xd8: // big float 16 + case 0xd4: // fixext 1 + case 0xd5: // fixext 2 + case 0xd6: // fixext 4 + case 0xd7: // fixext 8 + again_fixed_trail_if_zero(ACS_EXT_VALUE, + (1 << (((unsigned int)*p) & 0x03)) + 1, _ext_zero); + case 0xd8: // fixext 16 + again_fixed_trail_if_zero(ACS_EXT_VALUE, 16+1, _ext_zero); + case 0xd9: // str 8 case 0xda: // str 16 case 0xdb: // str 32 @@ -304,31 +309,22 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c _msgpack_load64(int64_t,n,&tmp); push_fixed_value(_int64, tmp); } - - //case CS_ - //case CS_ - //case CS_BIG_INT_16: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load16(uint16_t,n), _big_int_zero); - //case CS_BIG_INT_32: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load32(uint32_t,n), _big_int_zero); - //case ACS_BIG_INT_VALUE: - //_big_int_zero: - // // FIXME - // push_variable_value(_big_int, data, n, trail); - - //case CS_BIG_FLOAT_16: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load16(uint16_t,n), _big_float_zero); - //case CS_BIG_FLOAT_32: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load32(uint32_t,n), _big_float_zero); - //case ACS_BIG_FLOAT_VALUE: - //_big_float_zero: - // // FIXME - // push_variable_value(_big_float, data, n, trail); - + case CS_FIXEXT_1: + again_fixed_trail_if_zero(ACS_EXT_VALUE, 1+1, _ext_zero); + case CS_FIXEXT_2: + again_fixed_trail_if_zero(ACS_EXT_VALUE, 2+1, _ext_zero); + case CS_FIXEXT_4: + again_fixed_trail_if_zero(ACS_EXT_VALUE, 4+1, _ext_zero); + case CS_FIXEXT_8: + again_fixed_trail_if_zero(ACS_EXT_VALUE, 8+1, _ext_zero); + case CS_FIXEXT_16: + again_fixed_trail_if_zero(ACS_EXT_VALUE, 16+1, _ext_zero); case CS_STR_8: again_fixed_trail_if_zero(ACS_STR_VALUE, *(uint8_t*)n, _str_zero); case CS_BIN_8: again_fixed_trail_if_zero(ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero); + case CS_EXT_8: + again_fixed_trail_if_zero(ACS_EXT_VALUE, *(uint8_t*)n, _ext_zero); case CS_STR_16:{ uint16_t tmp; _msgpack_load16(uint16_t,n,&tmp); @@ -339,6 +335,11 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c _msgpack_load16(uint16_t,n,&tmp); again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero); } + case CS_EXT_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + again_fixed_trail_if_zero(ACS_EXT_VALUE, tmp, _ext_zero); + } case CS_STR_32:{ uint32_t tmp; _msgpack_load32(uint32_t,n,&tmp); @@ -349,12 +350,20 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c _msgpack_load32(uint32_t,n,&tmp); again_fixed_trail_if_zero(ACS_BIN_VALUE, tmp, _bin_zero); } + case CS_EXT_32:{ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + again_fixed_trail_if_zero(ACS_EXT_VALUE, tmp, _ext_zero); + } case ACS_STR_VALUE: _str_zero: push_variable_value(_str, data, n, trail); case ACS_BIN_VALUE: _bin_zero: push_variable_value(_bin, data, n, trail); + case ACS_EXT_VALUE: + _ext_zero: + push_variable_value(_ext, data, n, trail); case CS_ARRAY_16:{ uint16_t tmp; diff --git a/src/objectc.c b/src/objectc.c index ff5f6882..840d4332 100644 --- a/src/objectc.c +++ b/src/objectc.c @@ -68,6 +68,13 @@ int msgpack_pack_object(msgpack_packer* pk, msgpack_object d) return msgpack_pack_bin_body(pk, d.via.bin.ptr, d.via.bin.size); } + case MSGPACK_OBJECT_EXT: + { + int ret = msgpack_pack_ext(pk, d.via.ext.size, d.via.ext.type); + if(ret < 0) { return ret; } + return msgpack_pack_ext_body(pk, d.via.ext.ptr, d.via.ext.size); + } + case MSGPACK_OBJECT_ARRAY: { int ret = msgpack_pack_array(pk, d.via.array.size); @@ -141,6 +148,13 @@ void msgpack_object_print(FILE* out, msgpack_object o) fprintf(out, "\""); break; + case MSGPACK_OBJECT_EXT: + fprintf(out, "(ext: %" PRIi8 ")", o.via.ext.type); + fprintf(out, "\""); + fwrite(o.via.ext.ptr, o.via.ext.size, 1, out); + fprintf(out, "\""); + break; + case MSGPACK_OBJECT_ARRAY: fprintf(out, "["); if(o.via.array.size != 0) { @@ -209,6 +223,11 @@ bool msgpack_object_equal(const msgpack_object x, const msgpack_object y) return x.via.bin.size == y.via.bin.size && memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0; + case MSGPACK_OBJECT_EXT: + return x.via.ext.size == y.via.ext.size && + x.via.ext.type == y.via.ext.type && + memcmp(x.via.ext.ptr, y.via.ext.ptr, x.via.ext.size) == 0; + case MSGPACK_OBJECT_ARRAY: if(x.via.array.size != y.via.array.size) { return false; diff --git a/src/unpack.c b/src/unpack.c index 20a02e4b..33b1bec0 100644 --- a/src/unpack.c +++ b/src/unpack.c @@ -261,6 +261,18 @@ static inline int template_callback_bin(unpack_user* u, const char* b, const cha return 0; } +static inline int template_callback_ext(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o) +{ + MSGPACK_UNUSED(u); + MSGPACK_UNUSED(b); + o->type = MSGPACK_OBJECT_EXT; + o->via.ext.type = *p; + o->via.ext.ptr = p + 1; + o->via.ext.size = l - 1; + u->referenced = true; + return 0; +} + #include "msgpack/unpack_template.h"