summaryrefslogtreecommitdiff
path: root/msgpack/_unpacker.pyx
diff options
context:
space:
mode:
authorINADA Naoki <inada-n@klab.com>2013-10-20 15:08:31 +0900
committerINADA Naoki <inada-n@klab.com>2013-10-20 15:08:31 +0900
commit27f0cba8a5f36393517ee85d2c339847b76e0c6b (patch)
tree470bc84905240c82d2e1f4e710d55a288661f635 /msgpack/_unpacker.pyx
parent7123341ca89a9a3afee8521cc16a1a419ea8871e (diff)
parent6386481024ec045d9ef991a2c975902276812508 (diff)
downloadmsgpack-python-27f0cba8a5f36393517ee85d2c339847b76e0c6b.tar.gz
Merge branch 'master' of https://github.com/antocuni/msgpack-python into newspec
Conflicts: msgpack/fallback.py msgpack/unpack.h msgpack/unpack_define.h msgpack/unpack_template.h
Diffstat (limited to 'msgpack/_unpacker.pyx')
-rw-r--r--msgpack/_unpacker.pyx39
1 files changed, 37 insertions, 2 deletions
diff --git a/msgpack/_unpacker.pyx b/msgpack/_unpacker.pyx
index 7b0c8a6..cf30670 100644
--- a/msgpack/_unpacker.pyx
+++ b/msgpack/_unpacker.pyx
@@ -24,6 +24,7 @@ cdef extern from "unpack.h":
PyObject* object_hook
bint has_pairs_hook # call object_hook with k-v pairs
PyObject* list_hook
+ PyObject* ext_type_hook
char *encoding
char *unicode_errors
@@ -45,6 +46,7 @@ cdef extern from "unpack.h":
cdef inline init_ctx(unpack_context *ctx,
object object_hook, object object_pairs_hook, object list_hook,
+ object ext_type_hook,
bint use_list, char* encoding, char* unicode_errors):
unpack_init(ctx)
ctx.user.use_list = use_list
@@ -71,9 +73,17 @@ cdef inline init_ctx(unpack_context *ctx,
raise TypeError("list_hook must be a callable.")
ctx.user.list_hook = <PyObject*>list_hook
+ if ext_type_hook is not None:
+ if not PyCallable_Check(ext_type_hook):
+ raise TypeError("ext_type_hook must be a callable.")
+ ctx.user.ext_type_hook = <PyObject*>ext_type_hook
+
ctx.user.encoding = encoding
ctx.user.unicode_errors = unicode_errors
+def default_read_extended_type(typecode, data):
+ raise NotImplementedError("Cannot decode extended type with typecode=%d" % typecode)
+
def unpackb(object packed, object object_hook=None, object list_hook=None,
bint use_list=1, encoding=None, unicode_errors="strict",
object_pairs_hook=None,
@@ -106,7 +116,8 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
unicode_errors = unicode_errors.encode('ascii')
cerr = PyBytes_AsString(unicode_errors)
- init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, use_list, cenc, cerr)
+ init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, default_read_extended_type,
+ use_list, cenc, cerr)
ret = unpack_construct(&ctx, buf, buf_len, &off)
if ret == 1:
obj = unpack_data(&ctx)
@@ -248,7 +259,10 @@ cdef class Unpacker(object):
self.unicode_errors = unicode_errors
cerr = PyBytes_AsString(self.unicode_errors)
- init_ctx(&self.ctx, object_hook, object_pairs_hook, list_hook, use_list, cenc, cerr)
+ ext_type_hook = self.read_extended_type
+ Py_INCREF(ext_type_hook)
+ init_ctx(&self.ctx, object_hook, object_pairs_hook, list_hook,
+ ext_type_hook, use_list, cenc, cerr)
def feed(self, object next_bytes):
"""Append `next_bytes` to internal buffer."""
@@ -358,6 +372,24 @@ cdef class Unpacker(object):
"""
return self._unpack(unpack_construct, write_bytes)
+ def unpack_one(self, object write_bytes=None):
+ """
+ unpack one object
+
+ If write_bytes is not None, it will be called with parts of the raw
+ message as it is unpacked.
+
+ Raises `UnpackValueError` if there are no more bytes to unpack.
+ Raises ``ExtraData`` if there are still bytes left after the unpacking.
+ """
+ try:
+ result = self.unpack()
+ except OutOfData:
+ raise UnpackValueError("Data is not enough")
+ if self.buf_head < self.buf_tail:
+ raise ExtraData(result, self.buf[self.buf_head:])
+ return result
+
def skip(self, object write_bytes=None):
"""
read and ignore one object, returning None
@@ -385,6 +417,9 @@ cdef class Unpacker(object):
"""
return self._unpack(read_map_header, write_bytes)
+ def read_extended_type(self, typecode, data):
+ return default_read_extended_type(typecode, data)
+
def __iter__(self):
return self