Modified unpack functions to class member functions.

This commit is contained in:
Takatoshi Kondo 2013-08-27 11:24:48 +09:00
parent ec5c1194fc
commit 11afd4820f

View File

@ -47,12 +47,17 @@ namespace msgpack {
namespace detail { namespace detail {
struct unpack_user { class unpack_user {
zone* z; public:
bool referenced; zone* z() const { return z_; }
void set_z(zone* z) { z_ = z; }
bool referenced() const { return referenced_; }
void set_referenced(bool referenced) { referenced_ = referenced; }
private:
zone* z_;
bool referenced_;
}; };
static inline object template_callback_root(unpack_user* u) static inline object template_callback_root(unpack_user* u)
{ object o = {}; return o; } { object o = {}; return o; }
@ -103,7 +108,7 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, object
{ {
o->type = type::ARRAY; o->type = type::ARRAY;
o->via.array.size = 0; o->via.array.size = 0;
o->via.array.ptr = (object*)u->z->malloc(n*sizeof(object)); o->via.array.ptr = (object*)u->z()->malloc(n*sizeof(object));
if(o->via.array.ptr == NULL) { return -1; } if(o->via.array.ptr == NULL) { return -1; }
return 0; return 0;
} }
@ -115,7 +120,7 @@ static inline int template_callback_map(unpack_user* u, unsigned int n, object*
{ {
o->type = type::MAP; o->type = type::MAP;
o->via.map.size = 0; o->via.map.size = 0;
o->via.map.ptr = (object_kv*)u->z->malloc(n*sizeof(object_kv)); o->via.map.ptr = (object_kv*)u->z()->malloc(n*sizeof(object_kv));
if(o->via.map.ptr == NULL) { return -1; } if(o->via.map.ptr == NULL) { return -1; }
return 0; return 0;
} }
@ -133,27 +138,30 @@ static inline int template_callback_raw(unpack_user* u, const char* b, const cha
o->type = type::RAW; o->type = type::RAW;
o->via.raw.ptr = p; o->via.raw.ptr = p;
o->via.raw.size = l; o->via.raw.size = l;
u->referenced = true; u->set_referenced(true);
return 0; return 0;
} }
struct template_unpack_stack { class template_unpack_stack {
object obj; public:
size_t count; object obj() const { return obj_; }
unsigned int ct; object& obj() { return obj_; }
object map_key; void setObj(object obj) { obj_ = obj; }
size_t count() const { return count_; }
void set_count(size_t count) { count_ = count; }
size_t decl_count() { return --count_; }
unsigned int ct() const { return ct_; }
void set_ct(unsigned int ct) { ct_ = ct; }
object map_key() const { return map_key_; }
void set_map_key(object map_key) { map_key_ = map_key; }
private:
object obj_;
size_t count_;
unsigned int ct_;
object map_key_;
}; };
struct template_context {
unpack_user user;
unsigned int cs;
unsigned int trail;
unsigned int top;
template_unpack_stack stack[MSGPACK_EMBED_STACK_SIZE];
};
inline void init_count(void* buffer) inline void init_count(void* buffer)
{ {
*(volatile _msgpack_atomic_counter_t*)buffer = 1; *(volatile _msgpack_atomic_counter_t*)buffer = 1;
@ -178,161 +186,169 @@ inline _msgpack_atomic_counter_t get_count(void* buffer)
return *(volatile _msgpack_atomic_counter_t*)buffer; return *(volatile _msgpack_atomic_counter_t*)buffer;
} }
inline void template_init(template_context& ctx) class template_context {
{ public:
ctx.cs = CS_HEADER; template_context():cs_(CS_HEADER), trail_(0), top_(0)
ctx.trail = 0; {
ctx.top = 0; stack_[0].setObj(template_callback_root(&user_));
ctx.stack[0].obj = template_callback_root(&ctx.user); }
}
object template_data(template_context const& ctx) void init()
{ {
return ctx.stack[0].obj; cs_ = CS_HEADER;
} trail_ = 0;
top_ = 0;
stack_[0].setObj(template_callback_root(&user_));
}
template <typename T> object data() const
inline unsigned int next_cs(T p) {
{ return stack_[0].obj();
return (unsigned int)*p & 0x1f; }
}
int template_execute(template_context& ctx, const char* data, size_t len, size_t* off) unpack_user& user()
{ {
assert(len >= *off); return user_;
}
const unsigned char* p = (unsigned char*)data + *off; unpack_user const& user() const
const unsigned char* const pe = (unsigned char*)data + len; {
const void* n = nullptr; return user_;
}
unsigned int trail = ctx.trail; int execute(const char* data, size_t len, size_t* off)
unsigned int cs = ctx.cs; {
unsigned int top = ctx.top; assert(len >= *off);
template_unpack_stack* stack = ctx.stack;
/*
unsigned int stack_size = ctx.stack_size;
*/
unpack_user* user = &ctx.user;
object obj; const unsigned char* p = (unsigned char*)data + *off;
template_unpack_stack* c = nullptr; const unsigned char* const pe = (unsigned char*)data + len;
const void* n = nullptr;
int ret; unsigned int trail = trail_;
unsigned int cs = cs_;
unsigned int top = top_;
template_unpack_stack* stack = stack_;
unpack_user* user = &user_;
object obj;
template_unpack_stack* c = nullptr;
int ret;
if(p == pe) { goto _out; } if(p == pe) { goto _out; }
do { do {
switch(cs) { switch(cs) {
case CS_HEADER: case CS_HEADER:
if (0) { if (0) {
} else if(0x00 <= *p && *p <= 0x7f) { // Positive Fixnum } else if(0x00 <= *p && *p <= 0x7f) { // Positive Fixnum
if(template_callback_uint8(user, *(uint8_t*)p, &obj) < 0) { goto _failed; } if(template_callback_uint8(user, *(uint8_t*)p, &obj) < 0) { goto _failed; }
goto _push;
} else if(0xe0 <= *p && *p <= 0xff) { // Negative Fixnum
if(template_callback_int8(user, *(int8_t*)p, &obj) < 0) { goto _failed; }
goto _push;
} else if(0xc0 <= *p && *p <= 0xdf) { // Variable
switch(*p) {
case 0xc0: // nil
if(template_callback_nil(user, &obj) < 0) { goto _failed; }
goto _push; goto _push;
//case 0xc1: // string } else if(0xe0 <= *p && *p <= 0xff) { // Negative Fixnum
// again_terminal_trail(next_cs(p), p+1); if(template_callback_int8(user, *(int8_t*)p, &obj) < 0) { goto _failed; }
case 0xc2: // false
if(template_callback_false(user, &obj) < 0) { goto _failed; }
goto _push; goto _push;
case 0xc3: // true } else if(0xc0 <= *p && *p <= 0xdf) { // Variable
if(template_callback_true(user, &obj) < 0) { goto _failed; } switch(*p) {
goto _push; case 0xc0: // nil
case 0xc4: // bin 8 if(template_callback_nil(user, &obj) < 0) { goto _failed; }
case 0xc5: // bin 16 goto _push;
case 0xc6: // bin 32 //case 0xc1: // string
trail = 1 << (((unsigned int)*p) & 0x03); // again_terminal_trail(next_cs(p), p+1);
cs = next_cs(p); case 0xc2: // false
if(template_callback_false(user, &obj) < 0) { goto _failed; }
goto _push;
case 0xc3: // true
if(template_callback_true(user, &obj) < 0) { goto _failed; }
goto _push;
case 0xc4: // bin 8
case 0xc5: // bin 16
case 0xc6: // bin 32
trail = 1 << (((unsigned int)*p) & 0x03);
cs = next_cs(p);
goto _fixed_trail_again;
//case 0xc7:
//case 0xc8:
//case 0xc9:
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
trail = 1 << (((unsigned int)*p) & 0x03);
cs = next_cs(p);
goto _fixed_trail_again;
//case 0xd4:
//case 0xd5:
//case 0xd6: // big integer 16
//case 0xd7: // big integer 32
//case 0xd8: // big float 16
case 0xd9: // raw 8 (str 8)
case 0xda: // raw 16 (str 16)
case 0xdb: // raw 32 (str 32)
trail = 1 << ((((unsigned int)*p) & 0x03) - 1);
cs = next_cs(p);
goto _fixed_trail_again;
case 0xdc: // array 16
case 0xdd: // array 32
case 0xde: // map 16
case 0xdf: // map 32
trail = 2 << (((unsigned int)*p) & 0x01);
cs = next_cs(p);
goto _fixed_trail_again;
default:
goto _failed;
}
} else if(0xa0 <= *p && *p <= 0xbf) { // FixRaw
trail = (unsigned int)*p & 0x1f;
if(trail == 0) { goto _raw_zero; }
cs = ACS_RAW_VALUE;
goto _fixed_trail_again; goto _fixed_trail_again;
//case 0xc7: } else if(0x90 <= *p && *p <= 0x9f) { // FixArray
//case 0xc8: if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
//case 0xc9: if(template_callback_array(user, ((unsigned int)*p) & 0x0f, &stack[top].obj()) < 0) { goto _failed; }
case 0xca: // float if((((unsigned int)*p) & 0x0f) == 0) { obj = stack[top].obj(); goto _push; }
case 0xcb: // double stack[top].set_ct(CT_ARRAY_ITEM);
case 0xcc: // unsigned int 8 stack[top].set_count(((unsigned int)*p) & 0x0f);
case 0xcd: // unsigned int 16 ++top;
case 0xce: // unsigned int 32 goto _header_again;
case 0xcf: // unsigned int 64
case 0xd0: // signed int 8 } else if(0x80 <= *p && *p <= 0x8f) { // FixMap
case 0xd1: // signed int 16 if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
case 0xd2: // signed int 32 if(template_callback_map(user, ((unsigned int)*p) & 0x0f, &stack[top].obj()) < 0) { goto _failed; }
case 0xd3: // signed int 64 if((((unsigned int)*p) & 0x0f) == 0) { obj = stack[top].obj(); goto _push; }
trail = 1 << (((unsigned int)*p) & 0x03); stack[top].set_ct(CT_MAP_KEY);
cs = next_cs(p); stack[top].set_count(((unsigned int)*p) & 0x0f);
goto _fixed_trail_again; ++top;
//case 0xd4: goto _header_again;
//case 0xd5:
//case 0xd6: // big integer 16 } else {
//case 0xd7: // big integer 32
//case 0xd8: // big float 16
case 0xd9: // raw 8 (str 8)
case 0xda: // raw 16 (str 16)
case 0xdb: // raw 32 (str 32)
trail = 1 << ((((unsigned int)*p) & 0x03) - 1);
cs = next_cs(p);
goto _fixed_trail_again;
case 0xdc: // array 16
case 0xdd: // array 32
case 0xde: // map 16
case 0xdf: // map 32
trail = 2 << (((unsigned int)*p) & 0x01);
cs = next_cs(p);
goto _fixed_trail_again;
default:
goto _failed; goto _failed;
} }
} else if(0xa0 <= *p && *p <= 0xbf) { // FixRaw // end CS_HEADER
trail = (unsigned int)*p & 0x1f;
if(trail == 0) { goto _raw_zero; }
cs = ACS_RAW_VALUE;
goto _fixed_trail_again;
} else if(0x90 <= *p && *p <= 0x9f) { // FixArray
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
if(template_callback_array(user, ((unsigned int)*p) & 0x0f, &stack[top].obj) < 0) { goto _failed; }
if((((unsigned int)*p) & 0x0f) == 0) { obj = stack[top].obj; goto _push; }
stack[top].ct = CT_ARRAY_ITEM;
stack[top].count = ((unsigned int)*p) & 0x0f;
++top;
goto _header_again;
} else if(0x80 <= *p && *p <= 0x8f) { // FixMap
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
if(template_callback_map(user, ((unsigned int)*p) & 0x0f, &stack[top].obj) < 0) { goto _failed; }
if((((unsigned int)*p) & 0x0f) == 0) { obj = stack[top].obj; goto _push; }
stack[top].ct = CT_MAP_KEY;
stack[top].count = ((unsigned int)*p) & 0x0f;
++top;
goto _header_again;
} else {
goto _failed;
}
// end CS_HEADER
_fixed_trail_again: _fixed_trail_again:
++p; ++p;
default: default:
if((size_t)(pe - p) < trail) { goto _out; } if((size_t)(pe - p) < trail) { goto _out; }
n = p; p += trail - 1; n = p; p += trail - 1;
switch(cs) { switch(cs) {
//case CS_ //case CS_
//case CS_ //case CS_
case CS_FLOAT: { case CS_FLOAT: {
union { uint32_t i; float f; } mem; union { uint32_t i; float f; } mem;
mem.i = _msgpack_load32(uint32_t,n); mem.i = _msgpack_load32(uint32_t,n);
if(template_callback_float(user, mem.f, &obj) < 0) { goto _failed; } if(template_callback_float(user, mem.f, &obj) < 0) { goto _failed; }
goto _push; } goto _push; }
case CS_DOUBLE: { case CS_DOUBLE: {
union { uint64_t i; double f; } mem; union { uint64_t i; double f; } mem;
mem.i = _msgpack_load64(uint64_t,n); mem.i = _msgpack_load64(uint64_t,n);
#if defined(__arm__) && !(__ARM_EABI__) // arm-oabi #if defined(__arm__) && !(__ARM_EABI__) // arm-oabi
@ -341,161 +357,173 @@ int template_execute(template_context& ctx, const char* data, size_t len, size_t
#endif #endif
if(template_callback_double(user, mem.f, &obj) < 0) { goto _failed; } if(template_callback_double(user, mem.f, &obj) < 0) { goto _failed; }
goto _push; } goto _push; }
case CS_UINT_8: case CS_UINT_8:
if(template_callback_uint8(user, *(uint8_t*)n, &obj) < 0) { goto _failed; } if(template_callback_uint8(user, *(uint8_t*)n, &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_UINT_16: case CS_UINT_16:
if(template_callback_uint16(user, _msgpack_load16(uint16_t,n), &obj) < 0) { goto _failed; } if(template_callback_uint16(user, _msgpack_load16(uint16_t,n), &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_UINT_32: case CS_UINT_32:
if(template_callback_uint32(user, _msgpack_load32(uint32_t,n), &obj) < 0) { goto _failed; } if(template_callback_uint32(user, _msgpack_load32(uint32_t,n), &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_UINT_64: case CS_UINT_64:
if(template_callback_uint64(user, _msgpack_load64(uint64_t,n), &obj) < 0) { goto _failed; } if(template_callback_uint64(user, _msgpack_load64(uint64_t,n), &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_INT_8: case CS_INT_8:
if(template_callback_int8(user, *(int8_t*)n, &obj) < 0) { goto _failed; } if(template_callback_int8(user, *(int8_t*)n, &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_INT_16: case CS_INT_16:
if(template_callback_int16(user, _msgpack_load16(int16_t,n), &obj) < 0) { goto _failed; } if(template_callback_int16(user, _msgpack_load16(int16_t,n), &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_INT_32: case CS_INT_32:
if(template_callback_int32(user, _msgpack_load32(int32_t,n), &obj) < 0) { goto _failed; } if(template_callback_int32(user, _msgpack_load32(int32_t,n), &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_INT_64: case CS_INT_64:
if(template_callback_int64(user, _msgpack_load64(int64_t,n), &obj) < 0) { goto _failed; } if(template_callback_int64(user, _msgpack_load64(int64_t,n), &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_BIN_8: case CS_BIN_8:
case CS_RAW_8: case CS_RAW_8:
trail = *(uint8_t*)n; trail = *(uint8_t*)n;
if(trail == 0) { goto _raw_zero; } if(trail == 0) { goto _raw_zero; }
cs = ACS_RAW_VALUE; cs = ACS_RAW_VALUE;
goto _fixed_trail_again; goto _fixed_trail_again;
case CS_BIN_16: case CS_BIN_16:
case CS_RAW_16: case CS_RAW_16:
trail = _msgpack_load16(uint16_t, n); trail = _msgpack_load16(uint16_t, n);
if(trail == 0) { goto _raw_zero; } if(trail == 0) { goto _raw_zero; }
cs = ACS_RAW_VALUE; cs = ACS_RAW_VALUE;
goto _fixed_trail_again; goto _fixed_trail_again;
case CS_BIN_32: case CS_BIN_32:
case CS_RAW_32: case CS_RAW_32:
trail = _msgpack_load32(uint32_t, n); trail = _msgpack_load32(uint32_t, n);
if(trail == 0) { goto _raw_zero; } if(trail == 0) { goto _raw_zero; }
cs = ACS_RAW_VALUE; cs = ACS_RAW_VALUE;
goto _fixed_trail_again; goto _fixed_trail_again;
case ACS_RAW_VALUE: case ACS_RAW_VALUE:
_raw_zero: _raw_zero:
if(template_callback_raw(user, (const char*)data, (const char*)n, trail, &obj) < 0) { goto _failed; } if(template_callback_raw(user, (const char*)data, (const char*)n, trail, &obj) < 0) { goto _failed; }
goto _push; goto _push;
case CS_ARRAY_16: case CS_ARRAY_16:
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
if(template_callback_array(user, _msgpack_load16(uint16_t, n), &stack[top].obj) < 0) { goto _failed; } if(template_callback_array(user, _msgpack_load16(uint16_t, n), &stack[top].obj()) < 0) { goto _failed; }
if(_msgpack_load16(uint16_t, n) == 0) { obj = stack[top].obj; goto _push; } if(_msgpack_load16(uint16_t, n) == 0) { obj = stack[top].obj(); goto _push; }
stack[top].ct = CT_ARRAY_ITEM; stack[top].set_ct(CT_ARRAY_ITEM);
stack[top].count = _msgpack_load16(uint16_t, n); stack[top].set_count(_msgpack_load16(uint16_t, n));
++top; ++top;
goto _header_again; goto _header_again;
case CS_ARRAY_32: case CS_ARRAY_32:
/* FIXME security guard */ /* FIXME security guard */
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
if(template_callback_array(user, _msgpack_load32(uint32_t, n), &stack[top].obj) < 0) { goto _failed; } if(template_callback_array(user, _msgpack_load32(uint32_t, n), &stack[top].obj()) < 0) { goto _failed; }
if(_msgpack_load32(uint32_t, n) == 0) { obj = stack[top].obj; goto _push; } if(_msgpack_load32(uint32_t, n) == 0) { obj = stack[top].obj(); goto _push; }
stack[top].ct = CT_ARRAY_ITEM; stack[top].set_ct(CT_ARRAY_ITEM);
stack[top].count = _msgpack_load32(uint32_t, n); stack[top].set_count(_msgpack_load32(uint32_t, n));
++top; ++top;
goto _header_again; goto _header_again;
case CS_MAP_16: case CS_MAP_16:
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
if(template_callback_map(user, _msgpack_load16(uint16_t, n), &stack[top].obj) < 0) { goto _failed; } if(template_callback_map(user, _msgpack_load16(uint16_t, n), &stack[top].obj()) < 0) { goto _failed; }
if(_msgpack_load16(uint16_t, n) == 0) { obj = stack[top].obj; goto _push; } if(_msgpack_load16(uint16_t, n) == 0) { obj = stack[top].obj(); goto _push; }
stack[top].ct = CT_MAP_KEY; stack[top].set_ct(CT_MAP_KEY);
stack[top].count = _msgpack_load16(uint16_t, n); stack[top].set_count(_msgpack_load16(uint16_t, n));
++top; ++top;
goto _header_again;
case CS_MAP_32:
/* FIXME security guard */
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */
if(template_callback_map(user, _msgpack_load32(uint32_t, n), &stack[top].obj()) < 0) { goto _failed; }
if(_msgpack_load32(uint32_t, n) == 0) { obj = stack[top].obj(); goto _push; }
stack[top].set_ct(CT_MAP_KEY);
stack[top].set_count(_msgpack_load32(uint32_t, n));
++top;
goto _header_again;
default:
goto _failed;
}
}
_push:
if(top == 0) { goto _finish; }
c = &stack[top-1];
switch(c->ct()) {
case CT_ARRAY_ITEM:
if(template_callback_array_item(user, &c->obj(), obj) < 0) { goto _failed; }
if(c->decl_count() == 0) {
obj = c->obj();
--top;
/*printf("stack pop %d\n", top);*/
goto _push;
}
goto _header_again; goto _header_again;
case CS_MAP_32: case CT_MAP_KEY:
/* FIXME security guard */ c->set_map_key(obj);
if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ c->set_ct(CT_MAP_VALUE);
if(template_callback_map(user, _msgpack_load32(uint32_t, n), &stack[top].obj) < 0) { goto _failed; } goto _header_again;
if(_msgpack_load32(uint32_t, n) == 0) { obj = stack[top].obj; goto _push; } case CT_MAP_VALUE:
stack[top].ct = CT_MAP_KEY; if(template_callback_map_item(user, &c->obj(), c->map_key(), obj) < 0) { goto _failed; }
stack[top].count = _msgpack_load32(uint32_t, n); if(c->decl_count() == 0) {
++top; obj = c->obj();
--top;
/*printf("stack pop %d\n", top);*/
goto _push;
}
c->set_ct(CT_MAP_KEY);
goto _header_again; goto _header_again;
default: default:
goto _failed; goto _failed;
} }
}
_push:
if(top == 0) { goto _finish; }
c = &stack[top-1];
switch(c->ct) {
case CT_ARRAY_ITEM:
if(template_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 CT_MAP_KEY:
c->map_key = obj;
c->ct = CT_MAP_VALUE;
goto _header_again;
case CT_MAP_VALUE:
if(template_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 = CT_MAP_KEY;
goto _header_again;
default:
goto _failed;
}
_header_again: _header_again:
cs = CS_HEADER; cs = CS_HEADER;
++p; ++p;
} while(p != pe); } while(p != pe);
goto _out; goto _out;
_finish: _finish:
stack[0].obj = obj; stack[0].setObj(obj);
++p; ++p;
ret = 1; ret = 1;
/*printf("-- finish --\n"); */ /*printf("-- finish --\n"); */
goto _end; goto _end;
_failed: _failed:
/*printf("** FAILED **\n"); */ /*printf("** FAILED **\n"); */
ret = -1; ret = -1;
goto _end; goto _end;
_out: _out:
ret = 0; ret = 0;
goto _end; goto _end;
_end: _end:
ctx.cs = cs; cs_ = cs;
ctx.trail = trail; trail_ = trail;
ctx.top = top; top_ = top;
*off = p - (const unsigned char*)data; *off = p - (const unsigned char*)data;
return ret;
}
return ret;
}
private:
template <typename T>
static unsigned int next_cs(T p)
{
return (unsigned int)*p & 0x1f;
}
private:
unpack_user user_;
unsigned int cs_;
unsigned int trail_;
unsigned int top_;
template_unpack_stack stack_[MSGPACK_EMBED_STACK_SIZE];
};
} // detail } // detail
@ -689,9 +717,9 @@ inline unpacker::unpacker(size_t initial_buffer_size)
detail::init_count(buffer_); detail::init_count(buffer_);
detail::template_init(ctx_); ctx_.init();
ctx_.user.z = z_; ctx_.user().set_z(z_);
ctx_.user.referenced = false; ctx_.user().set_referenced(false);
} }
inline unpacker::~unpacker() inline unpacker::~unpacker()
@ -710,7 +738,7 @@ inline void unpacker::reserve_buffer(size_t size)
inline void unpacker::expand_buffer(size_t size) inline void unpacker::expand_buffer(size_t size)
{ {
if(used_ == off_ && detail::get_count(buffer_) == 1 if(used_ == off_ && detail::get_count(buffer_) == 1
&& !ctx_.user.referenced) { && !ctx_.user().referenced()) {
// rewind buffer // rewind buffer
free_ += used_ - COUNTER_SIZE; free_ += used_ - COUNTER_SIZE;
used_ = COUNTER_SIZE; used_ = COUNTER_SIZE;
@ -749,7 +777,7 @@ inline void unpacker::expand_buffer(size_t size)
::memcpy(tmp+COUNTER_SIZE, buffer_ + off_, not_parsed); ::memcpy(tmp+COUNTER_SIZE, buffer_ + off_, not_parsed);
if(ctx_.user.referenced) { if(ctx_.user().referenced()) {
try { try {
z_->push_finalizer(&detail::decl_count, buffer_); z_->push_finalizer(&detail::decl_count, buffer_);
} }
@ -757,7 +785,7 @@ inline void unpacker::expand_buffer(size_t size)
::free(tmp); ::free(tmp);
throw; throw;
} }
ctx_.user.referenced = false; ctx_.user().set_referenced(false);
} else { } else {
detail::decl_count(buffer_); detail::decl_count(buffer_);
} }
@ -822,8 +850,7 @@ inline bool unpacker::execute()
inline int unpacker::execute_imp() inline int unpacker::execute_imp()
{ {
size_t off = off_; size_t off = off_;
int ret = detail::template_execute(ctx_, int ret = ctx_.execute(buffer_, used_, &off_);
buffer_, used_, &off_);
if(off_ > off) { if(off_ > off) {
parsed_ += off_ - off; parsed_ += off_ - off;
} }
@ -832,7 +859,7 @@ inline int unpacker::execute_imp()
inline object unpacker::data() inline object unpacker::data()
{ {
return template_data(ctx_); return ctx_.data();
} }
inline zone* unpacker::release_zone() inline zone* unpacker::release_zone()
@ -848,7 +875,7 @@ inline zone* unpacker::release_zone()
zone* old = z_; zone* old = z_;
z_ = r; z_ = r;
ctx_.user.z = z_; ctx_.user().set_z(z_);
return old; return old;
} }
@ -860,13 +887,13 @@ inline void unpacker::reset_zone()
inline bool unpacker::flush_zone() inline bool unpacker::flush_zone()
{ {
if(ctx_.user.referenced) { if(ctx_.user().referenced()) {
try { try {
z_->push_finalizer(&detail::decl_count, buffer_); z_->push_finalizer(&detail::decl_count, buffer_);
} catch (...) { } catch (...) {
return false; return false;
} }
ctx_.user.referenced = false; ctx_.user().set_referenced(false);
detail::incr_count(buffer_); detail::incr_count(buffer_);
} }
@ -876,7 +903,7 @@ inline bool unpacker::flush_zone()
inline void unpacker::reset() inline void unpacker::reset()
{ {
detail::template_init(ctx_); ctx_.init();
// don't reset referenced flag // don't reset referenced flag
parsed_ = 0; parsed_ = 0;
} }
@ -926,12 +953,12 @@ unpack_imp(const char* data, size_t len, size_t* off,
} }
detail::template_context ctx; detail::template_context ctx;
detail::template_init(ctx); ctx.init();
ctx.user.z = result_zone; ctx.user().set_z(result_zone);
ctx.user.referenced = false; ctx.user().set_referenced(false);
int e = detail::template_execute(ctx, data, len, &noff); int e = ctx.execute(data, len, &noff);
if(e < 0) { if(e < 0) {
return UNPACK_PARSE_ERROR; return UNPACK_PARSE_ERROR;
} }
@ -942,7 +969,7 @@ unpack_imp(const char* data, size_t len, size_t* off,
return UNPACK_CONTINUE; return UNPACK_CONTINUE;
} }
*result = detail::template_data(ctx); *result = ctx.data();
if(noff < len) { if(noff < len) {
return UNPACK_EXTRA_BYTES; return UNPACK_EXTRA_BYTES;