diff options
Diffstat (limited to 'host/lib/deps/rpclib/include/rpc/msgpack/unpack_template.h')
-rw-r--r-- | host/lib/deps/rpclib/include/rpc/msgpack/unpack_template.h | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/host/lib/deps/rpclib/include/rpc/msgpack/unpack_template.h b/host/lib/deps/rpclib/include/rpc/msgpack/unpack_template.h new file mode 100644 index 000000000..a88fb0a46 --- /dev/null +++ b/host/lib/deps/rpclib/include/rpc/msgpack/unpack_template.h @@ -0,0 +1,482 @@ +/* + * MessagePack unpacking routine template + * + * Copyright (C) 2008-2010 FURUHASHI Sadayuki + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef msgpack_unpack_func +#error msgpack_unpack_func template is not defined +#endif + +#ifndef msgpack_unpack_callback +#error msgpack_unpack_callback template is not defined +#endif + +#ifndef msgpack_unpack_struct +#error msgpack_unpack_struct template is not defined +#endif + +#ifndef msgpack_unpack_struct_decl +#define msgpack_unpack_struct_decl(name) msgpack_unpack_struct(name) +#endif + +#ifndef msgpack_unpack_object +#error msgpack_unpack_object type is not defined +#endif + +#ifndef msgpack_unpack_user +#error msgpack_unpack_user type is not defined +#endif + +#ifndef USE_CASE_RANGE +#if !defined(_MSC_VER) +#define USE_CASE_RANGE +#endif +#endif + +msgpack_unpack_struct_decl(_stack) { + msgpack_unpack_object obj; + size_t count; + unsigned int ct; + msgpack_unpack_object map_key; +}; + +msgpack_unpack_struct_decl(_context) { + msgpack_unpack_user user; + unsigned int cs; + unsigned int trail; + unsigned int top; + /* + msgpack_unpack_struct(_stack)* stack; + unsigned int stack_size; + msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE]; + */ + msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE]; +}; + + +msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx) +{ + ctx->cs = MSGPACK_CS_HEADER; + ctx->trail = 0; + ctx->top = 0; + /* + ctx->stack = ctx->embed_stack; + ctx->stack_size = MSGPACK_EMBED_STACK_SIZE; + */ + ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user); +} + +/* +msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx) +{ + if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) { + free(ctx->stack); + } +} +*/ + +msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx) +{ + return (ctx)->stack[0].obj; +} + + +msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off) +{ + assert(len >= *off); + { + const unsigned char* p = (unsigned char*)data + *off; + const unsigned char* const pe = (unsigned char*)data + len; + const void* n = NULL; + + unsigned int trail = ctx->trail; + unsigned int cs = ctx->cs; + unsigned int top = ctx->top; + msgpack_unpack_struct(_stack)* stack = ctx->stack; + /* + unsigned int stack_size = ctx->stack_size; + */ + msgpack_unpack_user* user = &ctx->user; + + msgpack_unpack_object obj; + msgpack_unpack_struct(_stack)* c = NULL; + + int ret; + +#define push_simple_value(func) \ + if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \ + goto _push +#define push_fixed_value(func, arg) \ + if(msgpack_unpack_callback(func)(user, arg, &obj) < 0) { goto _failed; } \ + goto _push +#define push_variable_value(func, base, pos, len) \ + if(msgpack_unpack_callback(func)(user, \ + (const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \ + goto _push + +#define again_fixed_trail(_cs, trail_len) \ + trail = trail_len; \ + cs = _cs; \ + goto _fixed_trail_again +#define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \ + trail = trail_len; \ + if(trail == 0) { goto ifzero; } \ + cs = _cs; \ + goto _fixed_trail_again + +#define start_container(func, count_, ct_) \ + if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \ + if(msgpack_unpack_callback(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \ + if((count_) == 0) { obj = stack[top].obj; goto _push; } \ + stack[top].ct = ct_; \ + stack[top].count = count_; \ + ++top; \ + /*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \ + /*printf("stack push %d\n", top);*/ \ + /* FIXME \ + if(top >= stack_size) { \ + if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \ + size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \ + size_t nsize = csize * 2; \ + msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \ + if(tmp == NULL) { goto _failed; } \ + memcpy(tmp, ctx->stack, csize); \ + ctx->stack = stack = tmp; \ + ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \ + } else { \ + size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \ + msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \ + if(tmp == NULL) { goto _failed; } \ + ctx->stack = stack = tmp; \ + ctx->stack_size = stack_size = stack_size * 2; \ + } \ + } \ + */ \ + goto _header_again + +#define NEXT_CS(p) \ + ((unsigned int)*p & 0x1f) + +#ifdef USE_CASE_RANGE +#define SWITCH_RANGE_BEGIN switch(*p) { +#define SWITCH_RANGE(FROM, TO) case FROM ... TO: +#define SWITCH_RANGE_DEFAULT default: +#define SWITCH_RANGE_END } +#else +#define SWITCH_RANGE_BEGIN { if(0) { +#define SWITCH_RANGE(FROM, TO) } else if(FROM <= *p && *p <= TO) { +#define SWITCH_RANGE_DEFAULT } else { +#define SWITCH_RANGE_END } } +#endif + + if(p == pe) { goto _out; } + do { + switch(cs) { + case MSGPACK_CS_HEADER: + SWITCH_RANGE_BEGIN + SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum + push_fixed_value(_uint8, *(uint8_t*)p); + SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum + push_fixed_value(_int8, *(int8_t*)p); + SWITCH_RANGE(0xc0, 0xdf) // Variable + switch(*p) { + case 0xc0: // nil + push_simple_value(_nil); + //case 0xc1: // string + // again_terminal_trail(NEXT_CS(p), p+1); + case 0xc2: // false + push_simple_value(_false); + case 0xc3: // true + push_simple_value(_true); + case 0xc4: // bin 8 + case 0xc5: // bin 16 + case 0xc6: // bin 32 + again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); + 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 + case 0xcd: // unsigned int 16 + case 0xce: // unsigned int 32 + case 0xcf: // unsigned int 64 + case 0xd0: // signed int 8 + case 0xd1: // signed int 16 + case 0xd2: // signed int 32 + case 0xd3: // signed int 64 + again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); + case 0xd4: // fixext 1 + case 0xd5: // fixext 2 + case 0xd6: // fixext 4 + case 0xd7: // fixext 8 + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, + (1 << (((unsigned int)*p) & 0x03)) + 1, _ext_zero); + case 0xd8: // fixext 16 + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 16+1, _ext_zero); + + case 0xd9: // str 8 + case 0xda: // str 16 + case 0xdb: // str 32 + again_fixed_trail(NEXT_CS(p), 1 << ((((unsigned int)*p) & 0x03) - 1)); + case 0xdc: // array 16 + case 0xdd: // array 32 + case 0xde: // map 16 + case 0xdf: // map 32 + again_fixed_trail(NEXT_CS(p), 2u << (((unsigned int)*p) & 0x01)); + default: + goto _failed; + } + SWITCH_RANGE(0xa0, 0xbf) // FixStr + again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, ((unsigned int)*p & 0x1f), _str_zero); + SWITCH_RANGE(0x90, 0x9f) // FixArray + start_container(_array, ((unsigned int)*p) & 0x0f, MSGPACK_CT_ARRAY_ITEM); + SWITCH_RANGE(0x80, 0x8f) // FixMap + start_container(_map, ((unsigned int)*p) & 0x0f, MSGPACK_CT_MAP_KEY); + + SWITCH_RANGE_DEFAULT + goto _failed; + SWITCH_RANGE_END + // end MSGPACK_CS_HEADER + + + _fixed_trail_again: + ++p; + + default: + if((size_t)(pe - p) < trail) { goto _out; } + n = p; p += trail - 1; + switch(cs) { + //case MSGPACK_CS_ + //case MSGPACK_CS_ + case MSGPACK_CS_FLOAT: { + union { uint32_t i; float f; } mem; + _msgpack_load32(uint32_t, n, &mem.i); + push_fixed_value(_float, mem.f); } + case MSGPACK_CS_DOUBLE: { + union { uint64_t i; double f; } mem; + _msgpack_load64(uint64_t, n, &mem.i); +#if defined(TARGET_OS_IPHONE) + // ok +#elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi + // https://github.com/msgpack/msgpack-perl/pull/1 + mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); +#endif + push_fixed_value(_double, mem.f); } + case MSGPACK_CS_UINT_8: + push_fixed_value(_uint8, *(uint8_t*)n); + case MSGPACK_CS_UINT_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + push_fixed_value(_uint16, tmp); + } + case MSGPACK_CS_UINT_32:{ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + push_fixed_value(_uint32, tmp); + } + case MSGPACK_CS_UINT_64:{ + uint64_t tmp; + _msgpack_load64(uint64_t,n,&tmp); + push_fixed_value(_uint64, tmp); + } + case MSGPACK_CS_INT_8: + push_fixed_value(_int8, *(int8_t*)n); + case MSGPACK_CS_INT_16:{ + int16_t tmp; + _msgpack_load16(int16_t,n,&tmp); + push_fixed_value(_int16, tmp); + } + case MSGPACK_CS_INT_32:{ + int32_t tmp; + _msgpack_load32(int32_t,n,&tmp); + push_fixed_value(_int32, tmp); + } + case MSGPACK_CS_INT_64:{ + int64_t tmp; + _msgpack_load64(int64_t,n,&tmp); + push_fixed_value(_int64, tmp); + } + case MSGPACK_CS_FIXEXT_1: + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 1+1, _ext_zero); + case MSGPACK_CS_FIXEXT_2: + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 2+1, _ext_zero); + case MSGPACK_CS_FIXEXT_4: + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 4+1, _ext_zero); + case MSGPACK_CS_FIXEXT_8: + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 8+1, _ext_zero); + case MSGPACK_CS_FIXEXT_16: + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, 16+1, _ext_zero); + case MSGPACK_CS_STR_8: + again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, *(uint8_t*)n, _str_zero); + case MSGPACK_CS_BIN_8: + again_fixed_trail_if_zero(MSGPACK_ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero); + case MSGPACK_CS_EXT_8: + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, (*(uint8_t*)n) + 1, _ext_zero); + case MSGPACK_CS_STR_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, tmp, _str_zero); + } + case MSGPACK_CS_BIN_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + again_fixed_trail_if_zero(MSGPACK_ACS_BIN_VALUE, tmp, _bin_zero); + } + case MSGPACK_CS_EXT_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, tmp + 1, _ext_zero); + } + case MSGPACK_CS_STR_32:{ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + again_fixed_trail_if_zero(MSGPACK_ACS_STR_VALUE, tmp, _str_zero); + } + case MSGPACK_CS_BIN_32:{ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + again_fixed_trail_if_zero(MSGPACK_ACS_BIN_VALUE, tmp, _bin_zero); + } + case MSGPACK_CS_EXT_32:{ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + again_fixed_trail_if_zero(MSGPACK_ACS_EXT_VALUE, tmp + 1, _ext_zero); + } + case MSGPACK_ACS_STR_VALUE: + _str_zero: + push_variable_value(_str, data, n, trail); + case MSGPACK_ACS_BIN_VALUE: + _bin_zero: + push_variable_value(_bin, data, n, trail); + case MSGPACK_ACS_EXT_VALUE: + _ext_zero: + push_variable_value(_ext, data, n, trail); + + case MSGPACK_CS_ARRAY_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + start_container(_array, tmp, MSGPACK_CT_ARRAY_ITEM); + } + case MSGPACK_CS_ARRAY_32:{ + /* FIXME security guard */ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + start_container(_array, tmp, MSGPACK_CT_ARRAY_ITEM); + } + + case MSGPACK_CS_MAP_16:{ + uint16_t tmp; + _msgpack_load16(uint16_t,n,&tmp); + start_container(_map, tmp, MSGPACK_CT_MAP_KEY); + } + case MSGPACK_CS_MAP_32:{ + /* FIXME security guard */ + uint32_t tmp; + _msgpack_load32(uint32_t,n,&tmp); + start_container(_map, tmp, MSGPACK_CT_MAP_KEY); + } + + default: + goto _failed; + } + } + + _push: + if(top == 0) { goto _finish; } + c = &stack[top-1]; + switch(c->ct) { + case MSGPACK_CT_ARRAY_ITEM: + if(msgpack_unpack_callback(_array_item)(user, &c->obj, obj) < 0) { goto _failed; } + if(--c->count == 0) { + obj = c->obj; + --top; + /*printf("stack pop %d\n", top);*/ + goto _push; + } + goto _header_again; + case MSGPACK_CT_MAP_KEY: + c->map_key = obj; + c->ct = MSGPACK_CT_MAP_VALUE; + goto _header_again; + case MSGPACK_CT_MAP_VALUE: + if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; } + if(--c->count == 0) { + obj = c->obj; + --top; + /*printf("stack pop %d\n", top);*/ + goto _push; + } + c->ct = MSGPACK_CT_MAP_KEY; + goto _header_again; + + default: + goto _failed; + } + + _header_again: + cs = MSGPACK_CS_HEADER; + ++p; + } while(p != pe); + goto _out; + + + _finish: + stack[0].obj = obj; + ++p; + ret = 1; + /*printf("-- finish --\n"); */ + goto _end; + + _failed: + /*printf("** FAILED **\n"); */ + ret = -1; + goto _end; + + _out: + ret = 0; + goto _end; + + _end: + ctx->cs = cs; + ctx->trail = trail; + ctx->top = top; + *off = (size_t)(p - (const unsigned char*)data); + + return ret; + } +} + +#undef msgpack_unpack_func +#undef msgpack_unpack_callback +#undef msgpack_unpack_struct +#undef msgpack_unpack_object +#undef msgpack_unpack_user + +#undef push_simple_value +#undef push_fixed_value +#undef push_variable_value +#undef again_fixed_trail +#undef again_fixed_trail_if_zero +#undef start_container + +#undef NEXT_CS + +#undef SWITCH_RANGE_BEGIN +#undef SWITCH_RANGE +#undef SWITCH_RANGE_DEFAULT +#undef SWITCH_RANGE_END |