@@ -68,6 +68,7 @@ typedef struct
68
68
z_stream zst ;
69
69
PyObject * unused_data ;
70
70
PyObject * unconsumed_tail ;
71
+ PyObject * status ;
71
72
int is_initialised ;
72
73
73
74
#ifdef WITH_THREAD
@@ -100,18 +101,19 @@ newcompobject(PyTypeObject *type)
100
101
compobject * self ;
101
102
self = PyObject_New (compobject , type );
102
103
if (self == NULL )
103
- return NULL ;
104
+ return NULL ;
104
105
self -> is_initialised = 0 ;
105
106
self -> unused_data = PyString_FromString ("" );
106
107
if (self -> unused_data == NULL ) {
107
- Py_DECREF (self );
108
- return NULL ;
108
+ Py_DECREF (self );
109
+ return NULL ;
109
110
}
110
111
self -> unconsumed_tail = PyString_FromString ("" );
111
112
if (self -> unconsumed_tail == NULL ) {
112
- Py_DECREF (self );
113
- return NULL ;
113
+ Py_DECREF (self );
114
+ return NULL ;
114
115
}
116
+ self -> status = PyLong_FromLong (~0 );
115
117
116
118
#ifdef WITH_THREAD
117
119
self -> zlib_lock = PyThread_allocate_lock ();
@@ -378,6 +380,7 @@ Comp_dealloc(compobject *self)
378
380
deflateEnd (& self -> zst );
379
381
Py_XDECREF (self -> unused_data );
380
382
Py_XDECREF (self -> unconsumed_tail );
383
+ Py_XDECREF (self -> status );
381
384
382
385
#ifdef WITH_THREAD
383
386
PyThread_free_lock (self -> zlib_lock );
@@ -393,6 +396,7 @@ Decomp_dealloc(compobject *self)
393
396
inflateEnd (& self -> zst );
394
397
Py_XDECREF (self -> unused_data );
395
398
Py_XDECREF (self -> unconsumed_tail );
399
+ Py_XDECREF (self -> status );
396
400
397
401
#ifdef WITH_THREAD
398
402
PyThread_free_lock (self -> zlib_lock );
@@ -438,27 +442,32 @@ PyZlib_objcompress(compobject *self, PyObject *args)
438
442
/* while Z_OK and the output buffer is full, there might be more output,
439
443
so extend the output buffer and try again */
440
444
while (err == Z_OK && self -> zst .avail_out == 0 ) {
441
- if (_PyString_Resize (& RetVal , length << 1 ) < 0 )
442
- goto error ;
443
- self -> zst .next_out = (unsigned char * )PyString_AS_STRING (RetVal ) \
444
- + length ;
445
- self -> zst .avail_out = length ;
446
- length = length << 1 ;
447
-
448
- Py_BEGIN_ALLOW_THREADS
449
- err = deflate (& (self -> zst ), Z_NO_FLUSH );
450
- Py_END_ALLOW_THREADS
445
+ if (_PyString_Resize (& RetVal , length << 1 ) < 0 )
446
+ goto error ;
447
+ self -> zst .next_out = (unsigned char * )PyString_AS_STRING (RetVal ) \
448
+ + length ;
449
+ self -> zst .avail_out = length ;
450
+ length = length << 1 ;
451
+
452
+ Py_BEGIN_ALLOW_THREADS
453
+ err = deflate (& (self -> zst ), Z_NO_FLUSH );
454
+ Py_END_ALLOW_THREADS
451
455
}
456
+
457
+ // Set status
458
+ Py_DECREF (self -> status );
459
+ self -> status = PyLong_FromLong (err );
460
+
452
461
/* We will only get Z_BUF_ERROR if the output buffer was full but
453
462
there wasn't more output when we tried again, so it is not an error
454
463
condition.
455
464
*/
456
465
457
466
if (err != Z_OK && err != Z_BUF_ERROR ) {
458
- zlib_error (self -> zst , err , "while compressing" );
459
- Py_DECREF (RetVal );
460
- RetVal = NULL ;
461
- goto error ;
467
+ zlib_error (self -> zst , err , "while compressing" );
468
+ Py_DECREF (RetVal );
469
+ RetVal = NULL ;
470
+ goto error ;
462
471
}
463
472
_PyString_Resize (& RetVal , self -> zst .total_out - start_total_out );
464
473
@@ -541,6 +550,10 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
541
550
Py_END_ALLOW_THREADS
542
551
}
543
552
553
+ // Set status
554
+ Py_DECREF (self -> status );
555
+ self -> status = PyLong_FromLong (err );
556
+
544
557
/* Not all of the compressed data could be accommodated in the output buffer
545
558
of specified size. Return the unconsumed tail in an attribute.*/
546
559
if (max_length ) {
@@ -640,6 +653,10 @@ PyZlib_flush(compobject *self, PyObject *args)
640
653
err = deflate (& (self -> zst ), flushmode );
641
654
Py_END_ALLOW_THREADS
642
655
}
656
+
657
+ // update final status
658
+ Py_DECREF (self -> status );
659
+ self -> status = PyLong_FromLong (err );
643
660
644
661
/* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
645
662
various data structures. Note we should only get Z_STREAM_END when
@@ -709,10 +726,13 @@ PyZlib_copy(compobject *self)
709
726
710
727
Py_INCREF (self -> unused_data );
711
728
Py_INCREF (self -> unconsumed_tail );
729
+ Py_INCREF (self -> status );
712
730
Py_XDECREF (retval -> unused_data );
713
731
Py_XDECREF (retval -> unconsumed_tail );
732
+ Py_XDECREF (retval -> status );
714
733
retval -> unused_data = self -> unused_data ;
715
734
retval -> unconsumed_tail = self -> unconsumed_tail ;
735
+ retval -> status = self -> status ;
716
736
717
737
/* Mark it as being initialized */
718
738
retval -> is_initialised = 1 ;
@@ -760,10 +780,13 @@ PyZlib_uncopy(compobject *self)
760
780
761
781
Py_INCREF (self -> unused_data );
762
782
Py_INCREF (self -> unconsumed_tail );
783
+ Py_INCREF (self -> status );
763
784
Py_XDECREF (retval -> unused_data );
764
785
Py_XDECREF (retval -> unconsumed_tail );
786
+ Py_XDECREF (retval -> status );
765
787
retval -> unused_data = self -> unused_data ;
766
788
retval -> unconsumed_tail = self -> unconsumed_tail ;
789
+ retval -> status = self -> status ;
767
790
768
791
/* Mark it as being initialized */
769
792
retval -> is_initialised = 1 ;
@@ -877,10 +900,20 @@ static PyMethodDef Decomp_methods[] =
877
900
static PyObject *
878
901
Comp_getattr (compobject * self , char * name )
879
902
{
880
- /* No ENTER/LEAVE_ZLIB is necessary because this fn doesn't touch
881
- internal data. */
903
+ PyObject * retval ;
904
+
905
+ ENTER_ZLIB
882
906
883
- return Py_FindMethod (comp_methods , (PyObject * )self , name );
907
+ if (strcmp (name , "status ") == 0 ) {
908
+ Py_INCREF (self -> status );
909
+ retval = self -> status ;
910
+ } else {
911
+ retval = Py_FindMethod (comp_methods , (PyObject * )self , name );
912
+ }
913
+
914
+ LEAVE_ZLIB
915
+
916
+ return retval ;
884
917
}
885
918
886
919
static PyObject *
@@ -891,13 +924,17 @@ Decomp_getattr(compobject *self, char *name)
891
924
ENTER_ZLIB
892
925
893
926
if (strcmp (name , "unused_data ") == 0 ) {
894
- Py_INCREF (self -> unused_data );
895
- retval = self -> unused_data ;
927
+ Py_INCREF (self -> unused_data );
928
+ retval = self -> unused_data ;
896
929
} else if (strcmp (name , "unconsumed_tail ") == 0 ) {
897
- Py_INCREF (self -> unconsumed_tail );
898
- retval = self -> unconsumed_tail ;
899
- } else
900
- retval = Py_FindMethod (Decomp_methods , (PyObject * )self , name );
930
+ Py_INCREF (self -> unconsumed_tail );
931
+ retval = self -> unconsumed_tail ;
932
+ } else if (strcmp (name , "status" ) == 0 ) {
933
+ Py_INCREF (self -> status );
934
+ retval = self -> status ;
935
+ } else {
936
+ retval = Py_FindMethod (Decomp_methods , (PyObject * )self , name );
937
+ }
901
938
902
939
LEAVE_ZLIB
903
940
@@ -1047,6 +1084,18 @@ PyInit_zlib(void)
1047
1084
PyModule_AddIntConstant (m , "Z_SYNC_FLUSH" , Z_SYNC_FLUSH );
1048
1085
PyModule_AddIntConstant (m , "Z_FULL_FLUSH" , Z_FULL_FLUSH );
1049
1086
1087
+ // error codes
1088
+ PyModule_AddIntConstant (m , "Z_STATUS_UNSET" , ~0 );
1089
+ PyModule_AddIntConstant (m , "Z_OK" , Z_OK );
1090
+ PyModule_AddIntConstant (m , "Z_STREAM_END" , Z_STREAM_END );
1091
+ PyModule_AddIntConstant (m , "Z_NEED_DICT" , Z_NEED_DICT );
1092
+ PyModule_AddIntConstant (m , "Z_ERRNO" , Z_ERRNO );
1093
+ PyModule_AddIntConstant (m , "Z_STREAM_ERROR" , Z_STREAM_ERROR );
1094
+ PyModule_AddIntConstant (m , "Z_DATA_ERROR" , Z_DATA_ERROR );
1095
+ PyModule_AddIntConstant (m , "Z_MEM_ERROR" , Z_MEM_ERROR );
1096
+ PyModule_AddIntConstant (m , "Z_BUF_ERROR" , Z_BUF_ERROR );
1097
+ PyModule_AddIntConstant (m , "Z_VERSION_ERROR" , Z_VERSION_ERROR );
1098
+
1050
1099
ver = PyString_FromString (ZLIB_VERSION );
1051
1100
if (ver != NULL )
1052
1101
PyModule_AddObject (m , "ZLIB_VERSION" , ver );
0 commit comments