@@ -30,7 +30,7 @@ from libc.stdint cimport UINT64_MAX, UINT32_MAX, uint32_t
30
30
from cpython.mem cimport PyMem_Malloc, PyMem_Free
31
31
from cpython.buffer cimport PyBUF_READ, PyBUF_C_CONTIGUOUS, PyObject_GetBuffer, \
32
32
PyBuffer_Release
33
-
33
+ from cpython.bytes cimport PyBytes_FromStringAndSize
34
34
35
35
36
36
cdef extern from " <Python.h>" :
@@ -413,28 +413,22 @@ cdef class Decompress:
413
413
self .eof = 0
414
414
self .is_initialised = 1
415
415
416
- cdef save_unconsumed_input(self , object data):
417
- cdef Py_ssize_t old_size, new_size, left_size, offset
418
- cdef unsigned char * data_ptr
416
+ cdef save_unconsumed_input(self , Py_buffer * data):
417
+ cdef Py_ssize_t old_size, new_size, left_size
418
+ cdef bytes new_data
419
419
if self .stream.block_state == ISAL_BLOCK_FINISH:
420
420
self .eof = 1
421
421
if self .stream.avail_in > 0 :
422
422
old_size = len (self .unused_data)
423
- data_ptr = data
424
- left_size = data_ptr + len (data) - self .stream.next_in
425
- offset = self .stream.next_in - data_ptr
426
- if offset < 0 :
427
- raise Exception ()
423
+ left_size = < unsigned char * > data.buf + data.len - self .stream.next_in
428
424
if left_size > (PY_SSIZE_T_MAX - old_size):
429
425
raise MemoryError ()
430
- self .unused_data += data[offset:]
426
+ new_data = PyBytes_FromStringAndSize(< char * > self .stream.next_in, left_size)
427
+ self .unused_data += new_data
431
428
if self .stream.avail_in > 0 or self .unconsumed_tail:
432
- data_ptr = data
433
- left_size = data_ptr + len (data) - self .stream.next_in
434
- offset = self .stream.next_in - data_ptr
435
- if offset < 0 :
436
- raise Exception ()
437
- self .unconsumed_tail = data[offset:]
429
+ left_size = < unsigned char * > data.buf + data.len - self .stream.next_in
430
+ new_data = PyBytes_FromStringAndSize(< char * > self .stream.next_in, left_size)
431
+ self .unconsumed_tail = new_data
438
432
439
433
def decompress (self , data , Py_ssize_t max_length = 0 ):
440
434
@@ -494,7 +488,7 @@ cdef class Decompress:
494
488
out.append(obuf[:bytes_written])
495
489
if self .stream.block_state == ISAL_BLOCK_FINISH or last_round:
496
490
break
497
- self .save_unconsumed_input(data )
491
+ self .save_unconsumed_input(buffer )
498
492
return b" " .join(out)
499
493
finally :
500
494
PyMem_Free(obuf)
@@ -505,14 +499,14 @@ cdef class Decompress:
505
499
raise ValueError (" Length must be greater than 0" )
506
500
if length > UINT32_MAX:
507
501
raise ValueError (" Length should not be larger than 4GB." )
508
- data = self .unconsumed_tail[:]
509
- cdef Py_ssize_t ibuflen = len (data)
510
- if ibuflen > UINT32_MAX :
511
- # This should never happen, because we check the input size in
512
- # the decompress function as well.
513
- raise IsalError( " Unconsumed tail too large. Can not flush. " )
514
- self .stream.next_in = data
515
- self .stream.avail_in = ibuflen
502
+ cdef Py_buffer buffer_data
503
+ cdef Py_buffer * buffer = & buffer_data
504
+ if PyObject_GetBuffer( self .unconsumed_tail, buffer , PyBUF_READ & PyBUF_C_CONTIGUOUS) ! = 0 :
505
+ raise TypeError ( " Failed to get buffer " )
506
+ cdef Py_ssize_t ibuflen = buffer .len
507
+ cdef unsigned char * ibuf = < unsigned char * > buffer .buf
508
+ self .stream.next_in = ibuf
509
+
516
510
cdef unsigned long total_bytes = 0
517
511
cdef unsigned long bytes_written
518
512
out = []
@@ -521,23 +515,24 @@ cdef class Decompress:
521
515
cdef Py_ssize_t unused_bytes
522
516
523
517
try :
524
- while (self .stream.block_state != ISAL_BLOCK_FINISH
525
- and self .stream.avail_in != 0 ):
526
- self .stream.next_out = obuf # Reset output buffer.
527
- self .stream.avail_out = obuflen
528
- err = isal_inflate(& self .stream)
529
- if err != ISAL_DECOMP_OK:
530
- # There is some python interacting when possible exceptions
531
- # Are raised. So we remain in pure C code if we check for
532
- # COMP_OK first.
533
- check_isal_inflate_rc(err)
534
- # Instead of output buffer resizing as the zlibmodule.c example
535
- # the data is appended to a list.
536
- # TODO: Improve this with the buffer protocol.
537
- bytes_written = obuflen - self .stream.avail_out
538
- total_bytes += bytes_written
539
- out.append(obuf[:bytes_written])
540
- self .save_unconsumed_input(data)
518
+ while self .stream.block_state != ISAL_BLOCK_FINISH and ibuflen != 0 :
519
+ arrange_input_buffer(& self .stream, & ibuflen)
520
+ while (self .stream.block_state != ISAL_BLOCK_FINISH):
521
+ self .stream.next_out = obuf # Reset output buffer.
522
+ self .stream.avail_out = obuflen
523
+ err = isal_inflate(& self .stream)
524
+ if err != ISAL_DECOMP_OK:
525
+ # There is some python interacting when possible exceptions
526
+ # Are raised. So we remain in pure C code if we check for
527
+ # COMP_OK first.
528
+ check_isal_inflate_rc(err)
529
+ # Instead of output buffer resizing as the zlibmodule.c example
530
+ # the data is appended to a list.
531
+ # TODO: Improve this with the buffer protocol.
532
+ bytes_written = obuflen - self .stream.avail_out
533
+ total_bytes += bytes_written
534
+ out.append(obuf[:bytes_written])
535
+ self .save_unconsumed_input(buffer )
541
536
return b" " .join(out)
542
537
finally :
543
538
PyMem_Free(obuf)
0 commit comments