@@ -373,19 +373,13 @@ cdef class Decompress:
373
373
if err != COMP_OK:
374
374
check_isal_deflate_rc(err)
375
375
self .obuflen = DEF_BUF_SIZE
376
- self .obuf = < unsigned char * > PyMem_Malloc(self .obuflen * sizeof(char ))
377
376
self .unused_data = b" "
378
377
self .unconsumed_tail = b" "
379
378
self .eof = 0
380
379
self .is_initialised = 1
381
380
382
- def __dealloc__ (self ):
383
- if self .obuf is not NULL :
384
- PyMem_Free(self .obuf)
385
-
386
381
def decompress (self , data , Py_ssize_t max_length = 0 ):
387
- # Initialise output buffer
388
- out = []
382
+
389
383
cdef Py_ssize_t total_bytes = 0
390
384
if max_length > UINT32_MAX:
391
385
raise OverflowError (" A maximum of 4 GB is allowed for the max "
@@ -395,8 +389,6 @@ cdef class Decompress:
395
389
elif max_length < 0 :
396
390
raise ValueError (" max_length can not be smaller than 0" )
397
391
398
- if data == b" " :
399
- data = self .unconsumed_tail
400
392
cdef Py_ssize_t total_length = len (data)
401
393
if total_length > UINT32_MAX:
402
394
# Zlib allows a maximum of 64 KB (16-bit length) and python has
@@ -412,52 +404,60 @@ cdef class Decompress:
412
404
cdef unsigned long bytes_written
413
405
cdef Py_ssize_t unused_bytes
414
406
cdef int err
407
+
408
+ # Initialise output buffer
409
+ cdef unsigned char * obuf = < unsigned char * > PyMem_Malloc(self .obuflen * sizeof(char ))
410
+ out = []
411
+
415
412
cdef bint last_round = 0
416
- # This loop reads all the input bytes. If there are no input bytes
417
- # anymore the output is written.
418
- while (self .stream.avail_out == 0
419
- or self .stream.avail_in != 0 ):
420
- self .stream.next_out = self .obuf # Reset output buffer.
421
- if total_bytes >= max_length:
422
- break
423
- elif total_bytes + self .obuflen >= max_length:
424
- self .stream.avail_out = max_length - total_bytes
425
- # The inflate process may not fill all available bytes so
426
- # we make sure this is the last round.
427
- last_round = 1
428
- else :
429
- self .stream.avail_out = self .obuflen
430
- prev_avail_out = self .stream.avail_out
431
- err = isal_inflate(& self .stream)
432
- if err != ISAL_DECOMP_OK:
433
- # There is some python interacting when possible exceptions
434
- # Are raised. So we remain in pure C code if we check for
435
- # COMP_OK first.
436
- check_isal_inflate_rc(err)
437
- bytes_written = prev_avail_out - self .stream.avail_out
438
- total_bytes += bytes_written
439
- out.append(self .obuf[:bytes_written])
440
- if self .stream.block_state == ISAL_BLOCK_FINISH or last_round:
441
- break
442
- # Save unconsumed input implementation from zlibmodule.c
443
- if self .stream.block_state == ISAL_BLOCK_FINISH:
444
- # The end of the compressed data has been reached. Store the
445
- # leftover input data in self->unused_data.
446
- self .eof = 1
447
- if self .stream.avail_in > 0 :
413
+ try :
414
+ # This loop reads all the input bytes. If there are no input bytes
415
+ # anymore the output is written.
416
+ while (self .stream.avail_out == 0
417
+ or self .stream.avail_in != 0 ):
418
+ self .stream.next_out = obuf # Reset output buffer.
419
+ if total_bytes >= max_length:
420
+ break
421
+ elif total_bytes + self .obuflen >= max_length:
422
+ self .stream.avail_out = max_length - total_bytes
423
+ # The inflate process may not fill all available bytes so
424
+ # we make sure this is the last round.
425
+ last_round = 1
426
+ else :
427
+ self .stream.avail_out = self .obuflen
428
+ prev_avail_out = self .stream.avail_out
429
+ err = isal_inflate(& self .stream)
430
+ if err != ISAL_DECOMP_OK:
431
+ # There is some python interacting when possible exceptions
432
+ # Are raised. So we remain in pure C code if we check for
433
+ # COMP_OK first.
434
+ check_isal_inflate_rc(err)
435
+ bytes_written = prev_avail_out - self .stream.avail_out
436
+ total_bytes += bytes_written
437
+ out.append(obuf[:bytes_written])
438
+ if self .stream.block_state == ISAL_BLOCK_FINISH or last_round:
439
+ break
440
+ # Save unconsumed input implementation from zlibmodule.c
441
+ if self .stream.block_state == ISAL_BLOCK_FINISH:
442
+ # The end of the compressed data has been reached. Store the
443
+ # leftover input data in self->unused_data.
444
+ self .eof = 1
445
+ if self .stream.avail_in > 0 :
446
+ unused_bytes = self .stream.avail_in
447
+ self .unused_data = data[- unused_bytes:]
448
+ self .stream.avail_in = 0
449
+ if self .stream.avail_in > 0 or self .unconsumed_tail:
450
+ # This code handles two distinct cases:
451
+ # 1. Output limit was reached. Save leftover input in unconsumed_tail.
452
+ # 2. All input data was consumed. Clear unconsumed_tail.
448
453
unused_bytes = self .stream.avail_in
449
- self .unused_data = data[- unused_bytes:]
450
- self .stream.avail_in = 0
451
- if self .stream.avail_in > 0 or self .unconsumed_tail:
452
- # This code handles two distinct cases:
453
- # 1. Output limit was reached. Save leftover input in unconsumed_tail.
454
- # 2. All input data was consumed. Clear unconsumed_tail.
455
- unused_bytes = self .stream.avail_in
456
- if unused_bytes == 0 :
457
- self .unconsumed_tail = b" "
458
- else :
459
- self .unconsumed_tail = data[- unused_bytes:]
460
- return b" " .join(out)
454
+ if unused_bytes == 0 :
455
+ self .unconsumed_tail = b" "
456
+ else :
457
+ self .unconsumed_tail = data[- unused_bytes:]
458
+ return b" " .join(out)
459
+ finally :
460
+ PyMem_Free(obuf)
461
461
462
462
def flush (self , Py_ssize_t length = DEF_BUF_SIZE):
463
463
if length <= 0 :
0 commit comments