8000 Replaced python ext_hook with C style cb · sesam-io/msgpack-python@610d0d0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 610d0d0

Browse files
committed
Replaced python ext_hook with C style cb
1 parent 3388e4a commit 610d0d0

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

msgpack/_unpacker.pyx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ from cpython.object cimport PyCallable_Check
2121
from cpython.ref cimport Py_DECREF
2222
from cpython.exc cimport PyErr_WarnEx
2323

24+
ctypedef PyObject* (*extptr)(int, const char *pos, unsigned int)
25+
2426
cdef extern from "Python.h":
2527
ctypedef struct PyObject
2628
cdef int PyObject_AsReadBuffer(object o, const void** buff, Py_ssize_t* buf_len) except -1
@@ -46,6 +48,7 @@ cdef extern from "unpack.h":
4648
bint has_pairs_hook # call object_hook with k-v pairs
4749
PyObject* list_hook
4850
PyObject* ext_hook
51+
extptr ext_hook_c
4952
char *encoding
5053
char *unicode_errors
5154
Py_ssize_t max_str_len
@@ -71,7 +74,7 @@ cdef extern from "unpack.h":
7174

7275
cdef inline init_ctx(unpack_context *ctx,
7376
object object_hook, object object_pairs_hook,
74-
object list_hook, object ext_hook,
77+
object list_hook, object ext_hook, extptr ext_hook_c,
7578
bint use_list, char* encoding, char* unicode_errors,
7679
Py_ssize_t max_str_len, Py_ssize_t max_bin_len,
7780
Py_ssize_t max_array_len, Py_ssize_t max_map_len,
@@ -111,6 +114,9 @@ cdef inline init_ctx(unpack_context *ctx,
111114
raise TypeError("ext_hook must be a callable.")
112115
ctx.user.ext_hook = <PyObject*>ext_hook
113116

117+
if ext_hook_c:
118+
ctx.user.ext_hook_c = ext_hook_c
119+
114120
ctx.user.encoding = encoding
115121
ctx.user.unicode_errors = unicode_errors
116122

@@ -155,7 +161,7 @@ cdef inline int get_data_from_buffer(object obj,
155161

156162
def unpackb(object packed, object object_hook=None, object list_hook=None,
157163
bint use_list=1, encoding=None, unicode_errors="strict",
158-
object_pairs_hook=None, ext_hook=ExtType,
164+
object_pairs_hook=None, ext_hook=ExtType, Py_ssize_t ext_hook_c=0,
159165
Py_ssize_t max_str_len=2147483647, # 2**32-1
160166
Py_ssize_t max_bin_len=2147483647,
161167
Py_ssize_t max_array_len=2147483647,
@@ -192,7 +198,7 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
192198
unicode_errors = unicode_errors.encode('ascii')
193199
cerr = PyBytes_AsString(unicode_errors)
194200

195-
init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, ext_hook,
201+
init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, ext_hook, <extptr>ext_hook_c,
196202
use_list, cenc, cerr,
197203
max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len)
198204
ret = unpack_construct(&ctx, buf, buf_len, &off)
@@ -211,7 +217,7 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
211217

212218
def unpack(object stream, object object_hook=None, object list_hook=None,
213219
bint use_list=1, encoding=None, unicode_errors="strict",
214-
object_pairs_hook=None, ext_hook=ExtType,
220+
object_pairs_hook=None, ext_hook=ExtType, Py_ssize_t ext_hook_c=0,
215221
Py_ssize_t max_str_len=2147483647, # 2**32-1
216222
Py_ssize_t max_bin_len=2147483647,
217223
Py_ssize_t max_array_len=2147483647,
@@ -226,7 +232,7 @@ def unpack(object stream, object object_hook=None, object list_hook=None,
226232
"""
227233
return unpackb(stream.read(), use_list=use_list,
228234
object_hook=object_hook, object_pairs_hook=object_pairs_hook, list_hook=list_hook,
229-
encoding=encoding, unicode_errors=unicode_errors, ext_hook=ext_hook,
235+
encoding=encoding, unicode_errors=unicode_errors, ext_hook=ext_hook, ext_hook_c=ext_hook_c,
230236
max_str_len=max_str_len,
231237
max_bin_len=max_bin_len,
232238
max_array_len=max_array_len,
@@ -312,6 +318,7 @@ cdef class Unpacker(object):
312318
cdef Py_ssize_t read_size
313319
# To maintain refcnt.
314320
cdef object object_hook, object_pairs_hook, list_hook, ext_hook
321+
cdef extptr ext_hook_c
315322
cdef object encoding, unicode_errors
316323
cdef Py_ssize_t max_buffer_size
317324

@@ -326,6 +333,7 @@ cdef class Unpacker(object):
326333
object object_hook=None, object object_pairs_hook=None, object list_hook=None,
327334
encoding=None, unicode_errors='strict', int max_buffer_size=0,
328335
object ext_hook=ExtType,
336+
Py_ssize_t ext_hook_c=0,
329337
Py_ssize_t max_str_len=2147483647, # 2**32-1
330338
Py_ssize_t max_bin_len=2147483647,
331339
Py_ssize_t max_array_len=2147483647,
@@ -338,6 +346,7 @@ cdef class Unpacker(object):
338346
self.object_pairs_hook = object_pairs_hook
339347
self.list_hook = list_hook
340348
self.ext_hook = ext_hook
349+
self.ext_hook_c = <extptr>ext_hook_c
341350

342351
self.file_like = file_like
343352
if file_like:
@@ -378,7 +387,7 @@ cdef class Unpacker(object):
378387
cerr = PyBytes_AsString(self.unicode_errors)
379388

380389
init_ctx(&self.ctx, object_hook, object_pairs_hook, list_hook,
381-
ext_hook, use_list, cenc, cerr,
390+
ext_hook, self.ext_hook_c, use_list, cenc, cerr,
382391
max_str_len, max_bin_len, max_array_len,
383392
max_map_len, max_ext_len)
384393

msgpack/unpack.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
#define MSGPACK_EMBED_STACK_SIZE (1024)
2020
#include "unpack_define.h"
2121

22+
typedef PyObject* (*extptr)(int, const char *pos, unsigned int);
23+
2224
typedef struct unpack_user {
2325
int use_list;
2426
PyObject *object_hook;
2527
bool has_pairs_hook;
2628
PyObject *list_hook;
2729
PyObject *ext_hook;
30+
extptr ext_hook_c;
2831
const char *encoding;
2932
const char *unicode_errors;
3033
Py_ssize_t max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len;
@@ -263,12 +266,16 @@ static inline int unpack_callback_ext(unpack_user* u, const char* base, const ch
263266
PyErr_Format(PyExc_ValueError, "%u exceeds max_ext_len(%zd)", length, u->max_ext_len);
264267
return -1;
265268
}
269+
266270
// length also includes the typecode, so the actual data is length-1
267-
#if PY_MAJOR_VERSION == 2
271+
/*#if PY_MAJOR_VERSION == 2
268272
py = PyObject_CallFunction(u->ext_hook, "(is#)", (int)typecode, pos, (Py_ssize_t)length-1);
269273
#else
270274
py = PyObject_CallFunction(u->ext_hook, "(iy#)", (int)typecode, pos, (Py_ssize_t)length-1);
271-
#endif
275+
#endif*/
276+
277+
py = u->ext_hook_c(typecode, pos, length-1);
278+
272279
if (!py)
273280
return -1;
274281
*o = py;

0 commit comments

Comments
 (0)
0