diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | msgpack/_unpacker.pyx | 52 |
2 files changed, 28 insertions, 26 deletions
@@ -10,7 +10,7 @@ doc: cd docs && make zip cython: - cython msgpack/*.pyx + cython --cplus msgpack/*.pyx python3: cython python3 setup.py build_ext -i -f diff --git a/msgpack/_unpacker.pyx b/msgpack/_unpacker.pyx index 06806bd..9ff1085 100644 --- a/msgpack/_unpacker.pyx +++ b/msgpack/_unpacker.pyx @@ -2,6 +2,9 @@ #cython: embedsignature=True from cpython cimport * +cdef extern from "Python.h": + ctypedef struct PyObject + cdef int PyObject_AsReadBuffer(object o, const void* buff, Py_ssize_t* buf_len) except -1 from libc.stdlib cimport * from libc.string cimport * @@ -15,8 +18,8 @@ from msgpack.exceptions import ( ) + cdef extern from "unpack.h": - ctypedef struct PyObject ctypedef struct msgpack_user: bint use_list PyObject* object_hook @@ -87,33 +90,32 @@ def unpackb(object packed, object object_hook=None, object list_hook=None, cdef size_t off = 0 cdef int ret - cdef Py_buffer buff + cdef char* buf + cdef Py_ssize_t buf_len cdef char* cenc = NULL cdef char* cerr = NULL - PyObject_GetBuffer(packed, &buff, PyBUF_SIMPLE) - try: - if encoding is not None: - if isinstance(encoding, unicode): - encoding = encoding.encode('ascii') - cenc = PyBytes_AsString(encoding) - - if unicode_errors is not None: - if isinstance(unicode_errors, unicode): - 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) - ret = unpack_construct(&ctx, <char*>buff.buf, buff.len, &off) - if ret == 1: - obj = unpack_data(&ctx) - if off < buff.len: - raise ExtraData(obj, PyBytes_FromStringAndSize(<char*>buff.buf+off, buff.len-off)) - return obj - else: - raise UnpackValueError("Unpack failed: error = %d" % (ret,)) - finally: - PyBuffer_Release(&buff) + PyObject_AsReadBuffer(packed, <const void*>&buf, &buf_len) + + if encoding is not None: + if isinstance(encoding, unicode): + encoding = encoding.encode('ascii') + cenc = PyBytes_AsString(encoding) + + if unicode_errors is not None: + if isinstance(unicode_errors, unicode): + 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) + ret = unpack_construct(&ctx, buf, buf_len, &off) + if ret == 1: + obj = unpack_data(&ctx) + if off < buf_len: + raise ExtraData(obj, PyBytes_FromStringAndSize(buf+off, buf_len-off)) + return obj + else: + raise UnpackValueError("Unpack failed: error = %d" % (ret,)) def unpack(object stream, object object_hook=None, object list_hook=None, |