Skip to content

Commit c037aa7

Browse files
committed
Merge pull request #59 from msgpack/refactor
Use new style buffer interface.
2 parents 075dbec + 085db7f commit c037aa7

File tree

1 file changed

+31
-32
lines changed

1 file changed

+31
-32
lines changed

msgpack/_unpacker.pyx

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
#cython: embedsignature=True
33

44
from cpython cimport *
5-
cdef extern from "Python.h":
6-
ctypedef char* const_void_ptr "const void*"
7-
ctypedef struct PyObject
8-
cdef int PyObject_AsReadBuffer(object o, const_void_ptr* buff, Py_ssize_t* buf_len) except -1
95

106
from libc.stdlib cimport *
117
from libc.string cimport *
@@ -19,8 +15,8 @@ from msgpack.exceptions import (
1915
)
2016

2117

22-
2318
cdef extern from "unpack.h":
19+
ctypedef struct PyObject
2420
ctypedef struct msgpack_user:
2521
bint use_list
2622
PyObject* object_hook
@@ -91,32 +87,33 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
9187
cdef size_t off = 0
9288
cdef int ret
9389

94-
cdef char* buf
95-
cdef Py_ssize_t buf_len
90+
cdef Py_buffer buff
9691
cdef char* cenc = NULL
9792
cdef char* cerr = NULL
9893

99-
PyObject_AsReadBuffer(packed, <const_void_ptr*>&buf, &buf_len)
100-
101-
if encoding is not None:
102-
if isinstance(encoding, unicode):
103-
encoding = encoding.encode('ascii')
104-
cenc = PyBytes_AsString(encoding)
105-
106-
if unicode_errors is not None:
107-
if isinstance(unicode_errors, unicode):
108-
unicode_errors = unicode_errors.encode('ascii')
109-
cerr = PyBytes_AsString(unicode_errors)
110-
111-
init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, use_list, cenc, cerr)
112-
ret = unpack_construct(&ctx, buf, buf_len, &off)
113-
if ret == 1:
114-
obj = unpack_data(&ctx)
115-
if off < buf_len:
116-
raise ExtraData(obj, PyBytes_FromStringAndSize(buf+off, buf_len-off))
117-
return obj
118-
else:
119-
raise UnpackValueError("Unpack failed: error = %d" % (ret,))
94+
PyObject_GetBuffer(packed, &buff, PyBUF_SIMPLE)
95+
try:
96+
if encoding is not None:
97+
if isinstance(encoding, unicode):
98+
encoding = encoding.encode('ascii')
99+
cenc = PyBytes_AsString(encoding)
100+
101+
if unicode_errors is not None:
102+
if isinstance(unicode_errors, unicode):
103+
unicode_errors = unicode_errors.encode('ascii')
104+
cerr = PyBytes_AsString(unicode_errors)
105+
106+
init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, use_list, cenc, cerr)
107+
ret = unpack_construct(&ctx, <char*>buff.buf, buff.len, &off)
108+
if ret == 1:
109+
obj = unpack_data(&ctx)
110+
if off < buff.len:
111+
raise ExtraData(obj, PyBytes_FromStringAndSize(<char*>(buff)+off, buff.len-off))
112+
return obj
113+
else:
114+
raise UnpackValueError("Unpack failed: error = %d" % (ret,))
115+
finally:
116+
PyBuffer_Release(&buff)
120117

121118

122119
def unpack(object stream, object object_hook=None, object list_hook=None,
@@ -254,13 +251,15 @@ cdef class Unpacker(object):
254251

255252
def feed(self, object next_bytes):
256253
"""Append `next_bytes` to internal buffer."""
257-
cdef char* buf
258-
cdef Py_ssize_t buf_len
254+
cdef Py_buffer pybuff
259255
if self.file_like is not None:
260256
raise AssertionError(
261257
"unpacker.feed() is not be able to use with `file_like`.")
262-
PyObject_AsReadBuffer(next_bytes, <const_void_ptr*>&buf, &buf_len)
263-
self.append_buffer(buf, buf_len)
258+
PyObject_GetBuffer(next_bytes, &pybuff, PyBUF_SIMPLE)
259+
try:
260+
self.append_buffer(<char*>pybuff.buf, pybuff.len)
261+
finally:
262+
PyBuffer_Release(&pybuff)
264263

265264
cdef append_buffer(self, void* _buf, Py_ssize_t _buf_len):
266265
cdef:

0 commit comments

Comments
 (0)