@@ -479,11 +479,16 @@ cdef class Unpacker(object):
479479 else :
480480 self .file_like = None
481481
482- cdef object _unpack(self , execute_fn execute):
482+ cdef object _unpack(self , execute_fn execute, object write_bytes ):
483483 cdef int ret
484484 cdef object obj
485+ cdef size_t prev_head
485486 while 1 :
487+ prev_head = self .buf_head
486488 ret = execute(& self .ctx, self .buf, self .buf_tail, & self .buf_head)
489+ if write_bytes is not None :
490+ write_bytes(PyBytes_FromStringAndSize(self .buf + prev_head, self .buf_head - prev_head))
491+
487492 if ret == 1 :
488493 obj = template_data(& self .ctx)
489494 template_init(& self .ctx)
@@ -496,27 +501,35 @@ cdef class Unpacker(object):
496501 else :
497502 raise ValueError (" Unpack failed: error = %d " % (ret,))
498503
499- def unpack (self ):
500- """ unpack one object"""
501- return self ._unpack(template_construct)
504+ def unpack (self , object write_bytes = None ):
505+ """
506+ unpack one object
507+
508+ If write_bytes is not None, it will be called with parts of the raw message as it is unpacked.
509+ """
510+ return self ._unpack(template_construct, write_bytes)
511+
512+ def skip (self , object write_bytes = None ):
513+ """
514+ read and ignore one object, returning None
502515
503- def skip ( self ):
504- """ read and ignore one object, returning None """
505- return self ._unpack(template_skip)
516+ If write_bytes is not None, it will be called with parts of the raw message as it is unpacked.
517+ """
518+ return self ._unpack(template_skip, write_bytes )
506519
507- def read_array_header (self ):
520+ def read_array_header (self , object write_bytes = None ):
508521 """ assuming the next object is an array, return its size n, such that the next n unpack() calls will iterate over its contents."""
509- return self ._unpack(read_array_header)
522+ return self ._unpack(read_array_header, write_bytes )
510523
511- def read_map_header (self ):
524+ def read_map_header (self , object write_bytes = None ):
512525 """ 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."""
513- return self ._unpack(read_map_header)
526+ return self ._unpack(read_map_header, write_bytes )
514527
515528 def __iter__ (self ):
516529 return self
517530
518531 def __next__ (self ):
519- return self ._unpack(template_construct)
532+ return self ._unpack(template_construct, None )
520533
521534 # for debug.
522535 # def _buf(self):
0 commit comments