Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions msgpack/_msgpack.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ cdef extern from "unpack.h":
PyObject* key

int template_execute(template_context* ctx, const_char_ptr data,
size_t len, size_t* off) except -1
size_t len, size_t* off, bool construct) except -1
void template_init(template_context* ctx)
object template_data(template_context* ctx)

Expand Down Expand Up @@ -247,7 +247,7 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
if not PyCallable_Check(list_hook):
raise TypeError("list_hook must be a callable.")
ctx.user.list_hook = <PyObject*>list_hook
ret = template_execute(&ctx, buf, buf_len, &off)
ret = template_execute(&ctx, buf, buf_len, &off, True)
if ret == 1:
return template_data(&ctx)
else:
Expand Down Expand Up @@ -438,15 +438,12 @@ cdef class Unpacker(object):
else:
self.file_like = None

cpdef unpack(self):
"""unpack one object"""
cpdef _unpack(self, bool construct):
cdef int ret
while 1:
ret = template_execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head)
ret = template_execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head, construct)
if ret == 1:
o = template_data(&self.ctx)
template_init(&self.ctx)
return o
return
elif ret == 0:
if self.file_like is not None:
self.read_from_file()
Expand All @@ -455,6 +452,18 @@ cdef class Unpacker(object):
else:
raise ValueError("Unpack failed: error = %d" % (ret,))

cpdef unpack(self):
"""unpack one object"""
self._unpack(True)
o = template_data(&self.ctx)
template_init(&self.ctx)


cpdef skip(self):
"""read and ignore one object, returning None"""
self._unpack(False)
template_init(&self.ctx)

def __iter__(self):
return self

Expand Down
24 changes: 14 additions & 10 deletions msgpack/unpack_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context
}


msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off, bool construct)
{
assert(len >= *off);

Expand All @@ -117,14 +117,17 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c

int ret;

#define construct_cb(name) \
construct && msgpack_unpack_callback(name)

#define push_simple_value(func) \
if(msgpack_unpack_callback(func)(user, &obj) < 0) { goto _failed; } \
if(construct_cb(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; } \
if(construct_cb(func)(user, arg, &obj) < 0) { goto _failed; } \
goto _push
#define push_variable_value(func, base, pos, len) \
if(msgpack_unpack_callback(func)(user, \
if(construct_cb(func)(user, \
(const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \
goto _push

Expand All @@ -140,9 +143,9 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c

#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(construct_cb(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \
if((count_) == 0) { obj = stack[top].obj; \
msgpack_unpack_callback(func##_end)(user, &obj); \
construct_cb(func##_end)(user, &obj); \
goto _push; } \
stack[top].ct = ct_; \
stack[top].size = count_; \
Expand Down Expand Up @@ -340,10 +343,10 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
c = &stack[top-1];
switch(c->ct) {
case CT_ARRAY_ITEM:
if(msgpack_unpack_callback(_array_item)(user, c->count, &c->obj, obj) < 0) { goto _failed; }
if(construct_cb(_array_item)(user, c->count, &c->obj, obj) < 0) { goto _failed; }
if(++c->count == c->size) {
obj = c->obj;
msgpack_unpack_callback(_array_end)(user, &obj);
construct_cb(_array_end)(user, &obj);
--top;
/*printf("stack pop %d\n", top);*/
goto _push;
Expand All @@ -354,10 +357,10 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
c->ct = CT_MAP_VALUE;
goto _header_again;
case CT_MAP_VALUE:
if(msgpack_unpack_callback(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; }
if(construct_cb(_map_item)(user, &c->obj, c->map_key, obj) < 0) { goto _failed; }
if(++c->count == c->size) {
obj = c->obj;
msgpack_unpack_callback(_map_end)(user, &obj);
construct_cb(_map_end)(user, &obj);
--top;
/*printf("stack pop %d\n", top);*/
goto _push;
Expand Down Expand Up @@ -399,6 +402,7 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
*off = p - (const unsigned char*)data;

return ret;
#undef construct_cb
}


Expand Down