@@ -246,16 +246,16 @@ def __init__(self, file_like=None, read_size=0, use_list=True,
246246 raise TypeError ("`ext_hook` is not callable" )
247247
248248 def feed (self , next_bytes ):
249+ assert self ._fb_feeding
249250 if isinstance (next_bytes , array .array ):
250251 next_bytes = next_bytes .tostring ()
251- elif isinstance (next_bytes , bytearray ):
252- next_bytes = bytes (next_bytes )
253- assert self ._fb_feeding
254- if (self ._fb_buf_n + len (next_bytes ) - self ._fb_sloppiness
255- > self ._max_buffer_size ):
252+ view = memoryview (next_bytes )
253+ assert view .itemsize == 1
254+ L = len (view )
255+ if self ._fb_buf_n + L - self ._fb_sloppiness > self ._max_buffer_size :
256256 raise BufferFull
257- self ._fb_buf_n += len ( next_bytes )
258- self ._fb_buffers .append (next_bytes )
257+ self ._fb_buf_n += L
258+ self ._fb_buffers .append (view )
259259
260260 def _fb_sloppy_consume (self ):
261261 """ Gets rid of some of the used parts of the buffer. """
@@ -322,9 +322,10 @@ def _fb_read(self, n, write_bytes=None):
322322 return buffs [self ._fb_buf_i ][self ._fb_buf_o - n :self ._fb_buf_o ]
323323
324324 # The remaining cases.
325- ret = b''
326- while len (ret ) != n :
327- sliced = n - len (ret )
325+ ret = []
326+ n_read = 0
327+ while n_read != n :
328+ sliced = n - n_read
328329 if self ._fb_buf_i == len (buffs ):
329330 if self ._fb_feeding :
330331 break
@@ -334,34 +335,39 @@ def _fb_read(self, n, write_bytes=None):
334335 tmp = self .file_like .read (to_read )
335336 if not tmp :
336337 break
337- buffs .append (tmp )
338- self ._fb_buf_n += len (tmp )
338+ tmpview = memoryview (tmp )
339+ assert tmpview .itemsize == 1
340+ buffs .append (tmpview )
341+ self ._fb_buf_n += len (tmpview )
339342 continue
340- ret += buffs [self ._fb_buf_i ][self ._fb_buf_o :self ._fb_buf_o + sliced ]
343+ to_append = buffs [self ._fb_buf_i ][self ._fb_buf_o :self ._fb_buf_o + sliced ]
344+ n_read += len (to_append )
345+ ret .append (to_append )
341346 self ._fb_buf_o += sliced
342347 if self ._fb_buf_o >= len (buffs [self ._fb_buf_i ]):
343348 self ._fb_buf_o = 0
344349 self ._fb_buf_i += 1
350+ ret = b'' .join ([view .tobytes () for view in ret ])
345351 if len (ret ) != n :
346352 self ._fb_rollback ()
347353 raise OutOfData
348354 if write_bytes is not None :
349355 write_bytes (ret )
350- return ret
356+ return memoryview ( ret )
351357
352358 def _read_header (self , execute = EX_CONSTRUCT , write_bytes = None ):
353359 typ = TYPE_IMMEDIATE
354360 n = 0
355361 obj = None
356- c = self ._fb_read (1 , write_bytes )
362+ c = self ._fb_read (1 , write_bytes ). tobytes ()
357363 b = ord (c )
358- if b & 0b10000000 == 0 :
364+ if b & 0b10000000 == 0 :
359365 obj = b
360366 elif b & 0b11100000 == 0b11100000 :
361367 obj = struct .unpack ("b" , c )[0 ]
362368 elif b & 0b11100000 == 0b10100000 :
363369 n = b & 0b00011111
364- obj = self ._fb_read (n , write_bytes )
370+ obj = self ._fb_read (n , write_bytes ). tobytes ()
365371 typ = TYPE_RAW
366372 if n > self ._max_str_len :
367373 raise UnpackValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
@@ -386,37 +392,37 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
386392 n = struct .unpack ("B" , self ._fb_read (1 , write_bytes ))[0 ]
387393 if n > self ._max_bin_len :
388394 raise UnpackValueError ("%s exceeds max_bin_len(%s)" % (n , self ._max_bin_len ))
389- obj = self ._fb_read (n , write_bytes )
395+ obj = self ._fb_read (n , write_bytes ). tobytes ()
390396 elif b == 0xc5 :
391397 typ = TYPE_BIN
392398 n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
393399 if n > self ._max_bin_len :
394400 raise UnpackValueError ("%s exceeds max_bin_len(%s)" % (n , self ._max_bin_len ))
395- obj = self ._fb_read (n , write_bytes )
401+ obj = self ._fb_read (n , write_bytes ). tobytes ()
396402 elif b == 0xc6 :
397403 typ = TYPE_BIN
398404 n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
399405 if n > self ._max_bin_len :
400406 raise UnpackValueError ("%s exceeds max_bin_len(%s)" % (n , self ._max_bin_len ))
401- obj = self ._fb_read (n , write_bytes )
407+ obj = self ._fb_read (n , write_bytes ). tobytes ()
402408 elif b == 0xc7 : # ext 8
403409 typ = TYPE_EXT
404410 L , n = struct .unpack ('Bb' , self ._fb_read (2 , write_bytes ))
405411 if L > self ._max_ext_len :
406412 raise UnpackValueError ("%s exceeds max_ext_len(%s)" % (L , self ._max_ext_len ))
407- obj = self ._fb_read (L , write_bytes )
413+ obj = self ._fb_read (L , write_bytes ). tobytes ()
408414 elif b == 0xc8 : # ext 16
409415 typ = TYPE_EXT
410416 L , n = struct .unpack ('>Hb' , self ._fb_read (3 , write_bytes ))
411417 if L > self ._max_ext_len :
412418 raise UnpackValueError ("%s exceeds max_ext_len(%s)" % (L , self ._max_ext_len ))
413- obj = self ._fb_read (L , write_bytes )
419+ obj = self ._fb_read (L , write_bytes ). tobytes ()
414420 elif b == 0xc9 : # ext 32
415421 typ = TYPE_EXT
416422 L , n = struct .unpack ('>Ib' , self ._fb_read (5 , write_bytes ))
417423 if L > self ._max_ext_len :
418424 raise UnpackValueError ("%s exceeds max_ext_len(%s)" % (L , self ._max_ext_len ))
419- obj = self ._fb_read (L , write_bytes )
425+ obj = self ._fb_read (L , write_bytes ). tobytes ()
420426 elif b == 0xca :
421427 obj = struct .unpack (">f" , self ._fb_read (4 , write_bytes ))[0 ]
422428 elif b == 0xcb :
@@ -467,19 +473,19 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
467473 n = struct .unpack ("B" , self ._fb_read (1 , write_bytes ))[0 ]
468474 if n > self ._max_str_len :
469475 raise UnpackValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
470- obj = self ._fb_read (n , write_bytes )
476+ obj = self ._fb_read (n , write_bytes ). tobytes ()
471477 elif b == 0xda :
472478 typ = TYPE_RAW
473479 n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
474480 if n > self ._max_str_len :
475481 raise UnpackValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
476- obj = self ._fb_read (n , write_bytes )
482+ obj = self ._fb_read (n , write_bytes ). tobytes ()
477483 elif b == 0xdb :
478484 typ = TYPE_RAW
479485 n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
480486 if n > self ._max_str_len :
481487 raise UnpackValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
482- obj = self ._fb_read (n , write_bytes )
488+ obj = self ._fb_read (n , write_bytes ). tobytes ()
483489 elif b == 0xdc :
484490 n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
485491 if n > self ._max_array_len :
0 commit comments