@@ -229,7 +229,8 @@ cdef class Unpacker(object):
229229 cdef char * buf
230230 cdef size_t buf_size, buf_head, buf_tail
231231 cdef object file_like
232- cdef int read_size
232+ cdef object file_like_read
233+ cdef Py_ssize_t read_size
233234 cdef bint use_list
234235 cdef object object_hook
235236
@@ -239,12 +240,16 @@ cdef class Unpacker(object):
239240 def __dealloc__ (self ):
240241 free(self .buf);
241242
242- def __init__ (self , file_like = None , int read_size = 0 , bint use_list = 0 ,
243+ def __init__ (self , file_like = None , Py_ssize_t read_size = 0 , bint use_list = 0 ,
243244 object object_hook = None , object list_hook = None ):
244245 if read_size == 0 :
245246 read_size = 1024 * 1024
246247 self .use_list = use_list
247248 self .file_like = file_like
249+ if file_like:
250+ self .file_like_read = file_like.read
251+ if not PyCallable_Check(self .file_like_read):
252+ raise ValueError (" `file_like.read` must be a callable." )
248253 self .read_size = read_size
249254 self .buf = < char * > malloc(read_size)
250255 self .buf_size = read_size
@@ -265,6 +270,9 @@ cdef class Unpacker(object):
265270 def feed (self , object next_bytes ):
266271 cdef char * buf
267272 cdef Py_ssize_t buf_len
273+ if self .file_like is not None :
274+ raise AssertionError (
275+ " unpacker.feed() is not be able to use with`file_like`." )
268276 PyObject_AsReadBuffer(next_bytes, < const_void_ptr* > & buf, & buf_len)
269277 self .append_buffer(buf, buf_len)
270278
@@ -298,7 +306,7 @@ cdef class Unpacker(object):
298306 # prepare self.buf from file_like
299307 cdef fill_buffer(self ):
300308 if self .file_like is not None :
301- next_bytes = self .file_like.read (self .read_size)
309+ next_bytes = self .file_like_read (self .read_size)
302310 if next_bytes:
303311 self .append_buffer(PyBytes_AsString(next_bytes),
304312 PyBytes_Size(next_bytes))
@@ -308,18 +316,19 @@ cdef class Unpacker(object):
308316 cpdef unpack(self ):
309317 """ unpack one object"""
310318 cdef int ret
311- self .fill_buffer()
312- ret = template_execute(& self .ctx, self .buf, self .buf_tail, & self .buf_head)
313- if ret == 1 :
314- o = template_data(& self .ctx)
315- template_init(& self .ctx)
316- return o
317- elif ret == 0 :
318- if self .file_like is not None :
319- return self .unpack()
320- raise StopIteration , " No more unpack data."
321- else :
322- raise ValueError , " Unpack failed."
319+ while 1 :
320+ ret = template_execute(& self .ctx, self .buf, self .buf_tail, & self .buf_head)
321+ if ret == 1 :
322+ o = template_data(& self .ctx)
323+ template_init(& self .ctx)
324+ return o
325+ elif ret == 0 :
326+ if self .file_like is not None :
327+ self .fill_buffer()
328+ continue
329+ raise StopIteration (" No more unpack data." )
330+ else :
331+ raise ValueError (" Unpack failed: error = %d " % (ret,))
323332
324333 def __iter__ (self ):
325334 return UnpackIterator(self )
0 commit comments