Skip to content

Commit d56e2b2

Browse files
committed
Use C++ function templating for skip()/construct()
1 parent 96ed236 commit d56e2b2

File tree

4 files changed

+27
-22
lines changed

4 files changed

+27
-22
lines changed

msgpack/_msgpack.pyx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,10 @@ cdef extern from "unpack.h":
208208
unsigned int ct
209209
PyObject* key
210210

211-
int template_execute(template_context* ctx, const_char_ptr data,
212-
size_t len, size_t* off, bint construct) except -1
211+
ctypedef int (*execute_fn)(template_context* ctx, const_char_ptr data,
212+
size_t len, size_t* off) except -1
213+
execute_fn template_construct
214+
execute_fn template_skip
213215
void template_init(template_context* ctx)
214216
object template_data(template_context* ctx)
215217

@@ -257,7 +259,7 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
257259
if not PyCallable_Check(list_hook):
258260
raise TypeError("list_hook must be a callable.")
259261
ctx.user.list_hook = <PyObject*>list_hook
260-
ret = template_execute(&ctx, buf, buf_len, &off, 1)
262+
ret = template_construct(&ctx, buf, buf_len, &off)
261263
if ret == 1:
262264
obj = template_data(&ctx)
263265
if off < buf_len:
@@ -455,16 +457,13 @@ cdef class Unpacker(object):
455457
else:
456458
self.file_like = None
457459

458-
cdef object _unpack(self, bint construct):
460+
cdef object _unpack(self, execute_fn execute):
459461
cdef int ret
460462
cdef object obj
461463
while 1:
462-
ret = template_execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head, construct)
464+
ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head)
463465
if ret == 1:
464-
if construct:
465-
obj = template_data(&self.ctx)
466-
else:
467-
obj = None
466+
obj = template_data(&self.ctx)
468467
template_init(&self.ctx)
469468
return obj
470469
elif ret == 0:
@@ -477,17 +476,17 @@ cdef class Unpacker(object):
477476

478477
def unpack(self):
479478
"""unpack one object"""
480-
return self._unpack(1)
479+
return self._unpack(template_construct)
481480

482481
def skip(self):
483482
"""read and ignore one object, returning None"""
484-
return self._unpack(0)
483+
return self._unpack(template_skip)
485484

486485
def __iter__(self):
487486
return self
488487

489488
def __next__(self):
490-
return self._unpack(1)
489+
return self._unpack(template_construct)
491490

492491
# for debug.
493492
#def _buf(self):

msgpack/unpack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ typedef struct unpack_user {
4141

4242
#define msgpack_unpack_user unpack_user
4343

44+
typedef int (*execute_fn)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off);
4445

4546
struct template_context;
4647
typedef struct template_context template_context;

msgpack/unpack_template.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context
9595
}
9696

9797

98-
msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off, int construct)
98+
template <bool construct>
99+
msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off)
99100
{
100101
assert(len >= *off);
101102

@@ -380,6 +381,8 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
380381

381382

382383
_finish:
384+
if (!construct)
385+
msgpack_unpack_callback(_nil)(user, &obj);
383386
stack[0].obj = obj;
384387
++p;
385388
ret = 1;
@@ -405,20 +408,22 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c
405408
#undef construct_cb
406409
}
407410

408-
409-
#undef msgpack_unpack_func
410-
#undef msgpack_unpack_callback
411-
#undef msgpack_unpack_struct
412-
#undef msgpack_unpack_object
413-
#undef msgpack_unpack_user
414-
415411
#undef push_simple_value
416412
#undef push_fixed_value
417413
#undef push_variable_value
418414
#undef again_fixed_trail
419415
#undef again_fixed_trail_if_zero
420416
#undef start_container
421417

418+
static const execute_fn template_construct = &template_execute<true>;
419+
static const execute_fn template_skip = &template_execute<false>;
420+
421+
#undef msgpack_unpack_func
422+
#undef msgpack_unpack_callback
423+
#undef msgpack_unpack_struct
424+
#undef msgpack_unpack_object
425+
#undef msgpack_unpack_user
426+
422427
#undef NEXT_CS
423428

424429
/* vim: set ts=4 sw=4 noexpandtab */

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
def cythonize(src):
2020
sys.stderr.write("cythonize: %r\n" % (src,))
21-
cython_compiler.compile([src])
21+
cython_compiler.compile([src], cplus=True)
2222

2323
def ensure_source(src):
2424
pyx = os.path.splitext(src)[0] + '.pyx'
@@ -67,7 +67,7 @@ def __init__(self, *args, **kwargs):
6767
else:
6868
Sdist = sdist
6969

70-
sources = ['msgpack/_msgpack.c']
70+
sources = ['msgpack/_msgpack.cpp']
7171
libraries = []
7272
if sys.platform == 'win32':
7373
libraries.append('ws2_32')

0 commit comments

Comments
 (0)