@@ -467,11 +467,16 @@ cdef class Unpacker(object):
467467 else :
468468 self .file_like = None
469469
470- cdef object _unpack(self , execute_fn execute):
470+ cdef object _unpack(self , execute_fn execute, object write_bytes ):
471471 cdef int ret
472472 cdef object obj
473+ cdef size_t prev_head
473474 while 1 :
475+ prev_head = self .buf_head
474476 ret = execute(& self .ctx, self .buf, self .buf_tail, & self .buf_head)
477+ if write_bytes is not None :
478+ write_bytes(PyBytes_FromStringAndSize(self .buf + prev_head, self .buf_head - prev_head))
479+
475480 if ret == 1 :
476481 obj = template_data(& self .ctx)
477482 template_init(& self .ctx)
@@ -484,27 +489,35 @@ cdef class Unpacker(object):
484489 else :
485490 raise ValueError (" Unpack failed: error = %d " % (ret,))
486491
487- def unpack (self ):
488- """ unpack one object"""
489- return self ._unpack(template_construct)
492+ def unpack (self , object write_bytes = None ):
493+ """
494+ unpack one object
495+
496+ If write_bytes is not None, it will be called with parts of the raw message as it is unpacked.
497+ """
498+ return self ._unpack(template_construct, write_bytes)
499+
500+ def skip (self , object write_bytes = None ):
501+ """
502+ read and ignore one object, returning None
490503
491- def skip ( self ):
492- """ read and ignore one object, returning None """
493- return self ._unpack(template_skip)
504+ If write_bytes is not None, it will be called with parts of the raw message as it is unpacked.
505+ """
506+ return self ._unpack(template_skip, write_bytes )
494507
495- def read_array_header (self ):
508+ def read_array_header (self , object write_bytes = None ):
496509 """ assuming the next object is an array, return its size n, such that the next n unpack() calls will iterate over its contents."""
497- return self ._unpack(read_array_header)
510+ return self ._unpack(read_array_header, write_bytes )
498511
499- def read_map_header (self ):
512+ def read_map_header (self , object write_bytes = None ):
500513 """ assuming the next object is a map, return its size n, such that the next n * 2 unpack() calls will iterate over its key-value pairs."""
501- return self ._unpack(read_map_header)
514+ return self ._unpack(read_map_header, write_bytes )
502515
503516 def __iter__ (self ):
504517 return self
505518
506519 def __next__ (self ):
507- return self ._unpack(template_construct)
520+ return self ._unpack(template_construct, None )
508521
509522 # for debug.
510523 # def _buf(self):
0 commit comments