1 /* _bz2 - Low-level Python interface to libbzip2. */
2 
3 #define PY_SSIZE_T_CLEAN
4 
5 #include "Python.h"
6 #include "structmember.h"
7 
8 #include "pythread.h"
9 
10 #include <bzlib.h>
11 #include <stdio.h>
12 
13 
14 #ifndef BZ_CONFIG_ERROR
15 #define BZ2_bzCompress bzCompress
16 #define BZ2_bzCompressInit bzCompressInit
17 #define BZ2_bzCompressEnd bzCompressEnd
18 #define BZ2_bzDecompress bzDecompress
19 #define BZ2_bzDecompressInit bzDecompressInit
20 #define BZ2_bzDecompressEnd bzDecompressEnd
21 #endif  /* ! BZ_CONFIG_ERROR */
22 
23 
24 #define ACQUIRE_LOCK(obj) do { \
25     if (!PyThread_acquire_lock((obj)->lock, 0)) { \
26         Py_BEGIN_ALLOW_THREADS \
27         PyThread_acquire_lock((obj)->lock, 1); \
28         Py_END_ALLOW_THREADS \
29     } } while (0)
30 #define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
31 
32 
33 typedef struct {
34     PyObject_HEAD
35     bz_stream bzs;
36     int flushed;
37     PyThread_type_lock lock;
38 } BZ2Compressor;
39 
40 typedef struct {
41     PyObject_HEAD
42     bz_stream bzs;
43     char eof;           /* T_BOOL expects a char */
44     PyObject *unused_data;
45     char needs_input;
46     char *input_buffer;
47     size_t input_buffer_size;
48 
49     /* bzs->avail_in is only 32 bit, so we store the true length
50        separately. Conversion and looping is encapsulated in
51        decompress_buf() */
52     size_t bzs_avail_in_real;
53     PyThread_type_lock lock;
54 } BZ2Decompressor;
55 
56 static PyTypeObject BZ2Compressor_Type;
57 static PyTypeObject BZ2Decompressor_Type;
58 
59 /* Helper functions. */
60 
61 static int
catch_bz2_error(int bzerror)62 catch_bz2_error(int bzerror)
63 {
64     switch(bzerror) {
65         case BZ_OK:
66         case BZ_RUN_OK:
67         case BZ_FLUSH_OK:
68         case BZ_FINISH_OK:
69         case BZ_STREAM_END:
70             return 0;
71 
72 #ifdef BZ_CONFIG_ERROR
73         case BZ_CONFIG_ERROR:
74             PyErr_SetString(PyExc_SystemError,
75                             "libbzip2 was not compiled correctly");
76             return 1;
77 #endif
78         case BZ_PARAM_ERROR:
79             PyErr_SetString(PyExc_ValueError,
80                             "Internal error - "
81                             "invalid parameters passed to libbzip2");
82             return 1;
83         case BZ_MEM_ERROR:
84             PyErr_NoMemory();
85             return 1;
86         case BZ_DATA_ERROR:
87         case BZ_DATA_ERROR_MAGIC:
88             PyErr_SetString(PyExc_OSError, "Invalid data stream");
89             return 1;
90         case BZ_IO_ERROR:
91             PyErr_SetString(PyExc_OSError, "Unknown I/O error");
92             return 1;
93         case BZ_UNEXPECTED_EOF:
94             PyErr_SetString(PyExc_EOFError,
95                             "Compressed file ended before the logical "
96                             "end-of-stream was detected");
97             return 1;
98         case BZ_SEQUENCE_ERROR:
99             PyErr_SetString(PyExc_RuntimeError,
100                             "Internal error - "
101                             "Invalid sequence of commands sent to libbzip2");
102             return 1;
103         default:
104             PyErr_Format(PyExc_OSError,
105                          "Unrecognized error from libbzip2: %d", bzerror);
106             return 1;
107     }
108 }
109 
110 #if BUFSIZ < 8192
111 #define INITIAL_BUFFER_SIZE 8192
112 #else
113 #define INITIAL_BUFFER_SIZE BUFSIZ
114 #endif
115 
116 static int
grow_buffer(PyObject ** buf,Py_ssize_t max_length)117 grow_buffer(PyObject **buf, Py_ssize_t max_length)
118 {
119     /* Expand the buffer by an amount proportional to the current size,
120        giving us amortized linear-time behavior. Use a less-than-double
121        growth factor to avoid excessive allocation. */
122     size_t size = PyBytes_GET_SIZE(*buf);
123     size_t new_size = size + (size >> 3) + 6;
124 
125     if (max_length > 0 && new_size > (size_t) max_length)
126         new_size = (size_t) max_length;
127 
128     if (new_size > size) {
129         return _PyBytes_Resize(buf, new_size);
130     } else {  /* overflow */
131         PyErr_SetString(PyExc_OverflowError,
132                         "Unable to allocate buffer - output too large");
133         return -1;
134     }
135 }
136 
137 
138 /* BZ2Compressor class. */
139 
140 static PyObject *
compress(BZ2Compressor * c,char * data,size_t len,int action)141 compress(BZ2Compressor *c, char *data, size_t len, int action)
142 {
143     size_t data_size = 0;
144     PyObject *result;
145 
146     result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
147     if (result == NULL)
148         return NULL;
149 
150     c->bzs.next_in = data;
151     c->bzs.avail_in = 0;
152     c->bzs.next_out = PyBytes_AS_STRING(result);
153     c->bzs.avail_out = INITIAL_BUFFER_SIZE;
154     for (;;) {
155         char *this_out;
156         int bzerror;
157 
158         /* On a 64-bit system, len might not fit in avail_in (an unsigned int).
159            Do compression in chunks of no more than UINT_MAX bytes each. */
160         if (c->bzs.avail_in == 0 && len > 0) {
161             c->bzs.avail_in = (unsigned int)Py_MIN(len, UINT_MAX);
162             len -= c->bzs.avail_in;
163         }
164 
165         /* In regular compression mode, stop when input data is exhausted. */
166         if (action == BZ_RUN && c->bzs.avail_in == 0)
167             break;
168 
169         if (c->bzs.avail_out == 0) {
170             size_t buffer_left = PyBytes_GET_SIZE(result) - data_size;
171             if (buffer_left == 0) {
172                 if (grow_buffer(&result, -1) < 0)
173                     goto error;
174                 c->bzs.next_out = PyBytes_AS_STRING(result) + data_size;
175                 buffer_left = PyBytes_GET_SIZE(result) - data_size;
176             }
177             c->bzs.avail_out = (unsigned int)Py_MIN(buffer_left, UINT_MAX);
178         }
179 
180         Py_BEGIN_ALLOW_THREADS
181         this_out = c->bzs.next_out;
182         bzerror = BZ2_bzCompress(&c->bzs, action);
183         data_size += c->bzs.next_out - this_out;
184         Py_END_ALLOW_THREADS
185         if (catch_bz2_error(bzerror))
186             goto error;
187 
188         /* In flushing mode, stop when all buffered data has been flushed. */
189         if (action == BZ_FINISH && bzerror == BZ_STREAM_END)
190             break;
191     }
192     if (data_size != (size_t)PyBytes_GET_SIZE(result))
193         if (_PyBytes_Resize(&result, data_size) < 0)
194             goto error;
195     return result;
196 
197 error:
198     Py_XDECREF(result);
199     return NULL;
200 }
201 
202 /*[clinic input]
203 module _bz2
204 class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type"
205 class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type"
206 [clinic start generated code]*/
207 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=dc7d7992a79f9cb7]*/
208 
209 #include "clinic/_bz2module.c.h"
210 
211 /*[clinic input]
212 _bz2.BZ2Compressor.compress
213 
214     data: Py_buffer
215     /
216 
217 Provide data to the compressor object.
218 
219 Returns a chunk of compressed data if possible, or b'' otherwise.
220 
221 When you have finished providing data to the compressor, call the
222 flush() method to finish the compression process.
223 [clinic start generated code]*/
224 
225 static PyObject *
_bz2_BZ2Compressor_compress_impl(BZ2Compressor * self,Py_buffer * data)226 _bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data)
227 /*[clinic end generated code: output=59365426e941fbcc input=85c963218070fc4c]*/
228 {
229     PyObject *result = NULL;
230 
231     ACQUIRE_LOCK(self);
232     if (self->flushed)
233         PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
234     else
235         result = compress(self, data->buf, data->len, BZ_RUN);
236     RELEASE_LOCK(self);
237     return result;
238 }
239 
240 /*[clinic input]
241 _bz2.BZ2Compressor.flush
242 
243 Finish the compression process.
244 
245 Returns the compressed data left in internal buffers.
246 
247 The compressor object may not be used after this method is called.
248 [clinic start generated code]*/
249 
250 static PyObject *
_bz2_BZ2Compressor_flush_impl(BZ2Compressor * self)251 _bz2_BZ2Compressor_flush_impl(BZ2Compressor *self)
252 /*[clinic end generated code: output=3ef03fc1b092a701 input=d64405d3c6f76691]*/
253 {
254     PyObject *result = NULL;
255 
256     ACQUIRE_LOCK(self);
257     if (self->flushed)
258         PyErr_SetString(PyExc_ValueError, "Repeated call to flush()");
259     else {
260         self->flushed = 1;
261         result = compress(self, NULL, 0, BZ_FINISH);
262     }
263     RELEASE_LOCK(self);
264     return result;
265 }
266 
267 static void*
BZ2_Malloc(void * ctx,int items,int size)268 BZ2_Malloc(void* ctx, int items, int size)
269 {
270     if (items < 0 || size < 0)
271         return NULL;
272     if (size != 0 && (size_t)items > (size_t)PY_SSIZE_T_MAX / (size_t)size)
273         return NULL;
274     /* PyMem_Malloc() cannot be used: compress() and decompress()
275        release the GIL */
276     return PyMem_RawMalloc((size_t)items * (size_t)size);
277 }
278 
279 static void
BZ2_Free(void * ctx,void * ptr)280 BZ2_Free(void* ctx, void *ptr)
281 {
282     PyMem_RawFree(ptr);
283 }
284 
285 /*[clinic input]
286 _bz2.BZ2Compressor.__init__
287 
288     compresslevel: int = 9
289         Compression level, as a number between 1 and 9.
290     /
291 
292 Create a compressor object for compressing data incrementally.
293 
294 For one-shot compression, use the compress() function instead.
295 [clinic start generated code]*/
296 
297 static int
_bz2_BZ2Compressor___init___impl(BZ2Compressor * self,int compresslevel)298 _bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
299 /*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/
300 {
301     int bzerror;
302 
303     if (!(1 <= compresslevel && compresslevel <= 9)) {
304         PyErr_SetString(PyExc_ValueError,
305                         "compresslevel must be between 1 and 9");
306         return -1;
307     }
308 
309     self->lock = PyThread_allocate_lock();
310     if (self->lock == NULL) {
311         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
312         return -1;
313     }
314 
315     self->bzs.opaque = NULL;
316     self->bzs.bzalloc = BZ2_Malloc;
317     self->bzs.bzfree = BZ2_Free;
318     bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0);
319     if (catch_bz2_error(bzerror))
320         goto error;
321 
322     return 0;
323 
324 error:
325     PyThread_free_lock(self->lock);
326     self->lock = NULL;
327     return -1;
328 }
329 
330 static void
BZ2Compressor_dealloc(BZ2Compressor * self)331 BZ2Compressor_dealloc(BZ2Compressor *self)
332 {
333     BZ2_bzCompressEnd(&self->bzs);
334     if (self->lock != NULL)
335         PyThread_free_lock(self->lock);
336     Py_TYPE(self)->tp_free((PyObject *)self);
337 }
338 
339 static PyMethodDef BZ2Compressor_methods[] = {
340     _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF
341     _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF
342     {NULL}
343 };
344 
345 
346 static PyTypeObject BZ2Compressor_Type = {
347     PyVarObject_HEAD_INIT(NULL, 0)
348     "_bz2.BZ2Compressor",               /* tp_name */
349     sizeof(BZ2Compressor),              /* tp_basicsize */
350     0,                                  /* tp_itemsize */
351     (destructor)BZ2Compressor_dealloc,  /* tp_dealloc */
352     0,                                  /* tp_vectorcall_offset */
353     0,                                  /* tp_getattr */
354     0,                                  /* tp_setattr */
355     0,                                  /* tp_as_async */
356     0,                                  /* tp_repr */
357     0,                                  /* tp_as_number */
358     0,                                  /* tp_as_sequence */
359     0,                                  /* tp_as_mapping */
360     0,                                  /* tp_hash  */
361     0,                                  /* tp_call */
362     0,                                  /* tp_str */
363     0,                                  /* tp_getattro */
364     0,                                  /* tp_setattro */
365     0,                                  /* tp_as_buffer */
366     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
367     _bz2_BZ2Compressor___init____doc__,  /* tp_doc */
368     0,                                  /* tp_traverse */
369     0,                                  /* tp_clear */
370     0,                                  /* tp_richcompare */
371     0,                                  /* tp_weaklistoffset */
372     0,                                  /* tp_iter */
373     0,                                  /* tp_iternext */
374     BZ2Compressor_methods,              /* tp_methods */
375     0,                                  /* tp_members */
376     0,                                  /* tp_getset */
377     0,                                  /* tp_base */
378     0,                                  /* tp_dict */
379     0,                                  /* tp_descr_get */
380     0,                                  /* tp_descr_set */
381     0,                                  /* tp_dictoffset */
382     _bz2_BZ2Compressor___init__,        /* tp_init */
383     0,                                  /* tp_alloc */
384     PyType_GenericNew,                  /* tp_new */
385 };
386 
387 
388 /* BZ2Decompressor class. */
389 
390 /* Decompress data of length d->bzs_avail_in_real in d->bzs.next_in.  The output
391    buffer is allocated dynamically and returned.  At most max_length bytes are
392    returned, so some of the input may not be consumed. d->bzs.next_in and
393    d->bzs_avail_in_real are updated to reflect the consumed input. */
394 static PyObject*
decompress_buf(BZ2Decompressor * d,Py_ssize_t max_length)395 decompress_buf(BZ2Decompressor *d, Py_ssize_t max_length)
396 {
397     /* data_size is strictly positive, but because we repeatedly have to
398        compare against max_length and PyBytes_GET_SIZE we declare it as
399        signed */
400     Py_ssize_t data_size = 0;
401     PyObject *result;
402     bz_stream *bzs = &d->bzs;
403 
404     if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE)
405         result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
406     else
407         result = PyBytes_FromStringAndSize(NULL, max_length);
408     if (result == NULL)
409         return NULL;
410 
411     bzs->next_out = PyBytes_AS_STRING(result);
412     for (;;) {
413         int bzret;
414         size_t avail;
415 
416         /* On a 64-bit system, buffer length might not fit in avail_out, so we
417            do decompression in chunks of no more than UINT_MAX bytes
418            each. Note that the expression for `avail` is guaranteed to be
419            positive, so the cast is safe. */
420         avail = (size_t) (PyBytes_GET_SIZE(result) - data_size);
421         bzs->avail_out = (unsigned int)Py_MIN(avail, UINT_MAX);
422         bzs->avail_in = (unsigned int)Py_MIN(d->bzs_avail_in_real, UINT_MAX);
423         d->bzs_avail_in_real -= bzs->avail_in;
424 
425         Py_BEGIN_ALLOW_THREADS
426         bzret = BZ2_bzDecompress(bzs);
427         data_size = bzs->next_out - PyBytes_AS_STRING(result);
428         d->bzs_avail_in_real += bzs->avail_in;
429         Py_END_ALLOW_THREADS
430         if (catch_bz2_error(bzret))
431             goto error;
432         if (bzret == BZ_STREAM_END) {
433             d->eof = 1;
434             break;
435         } else if (d->bzs_avail_in_real == 0) {
436             break;
437         } else if (bzs->avail_out == 0) {
438             if (data_size == max_length)
439                 break;
440             if (data_size == PyBytes_GET_SIZE(result) &&
441                 grow_buffer(&result, max_length) == -1)
442                 goto error;
443             bzs->next_out = PyBytes_AS_STRING(result) + data_size;
444         }
445     }
446     if (data_size != PyBytes_GET_SIZE(result))
447         if (_PyBytes_Resize(&result, data_size) == -1)
448             goto error;
449 
450     return result;
451 
452 error:
453     Py_XDECREF(result);
454     return NULL;
455 }
456 
457 
458 static PyObject *
decompress(BZ2Decompressor * d,char * data,size_t len,Py_ssize_t max_length)459 decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length)
460 {
461     char input_buffer_in_use;
462     PyObject *result;
463     bz_stream *bzs = &d->bzs;
464 
465     /* Prepend unconsumed input if necessary */
466     if (bzs->next_in != NULL) {
467         size_t avail_now, avail_total;
468 
469         /* Number of bytes we can append to input buffer */
470         avail_now = (d->input_buffer + d->input_buffer_size)
471             - (bzs->next_in + d->bzs_avail_in_real);
472 
473         /* Number of bytes we can append if we move existing
474            contents to beginning of buffer (overwriting
475            consumed input) */
476         avail_total = d->input_buffer_size - d->bzs_avail_in_real;
477 
478         if (avail_total < len) {
479             size_t offset = bzs->next_in - d->input_buffer;
480             char *tmp;
481             size_t new_size = d->input_buffer_size + len - avail_now;
482 
483             /* Assign to temporary variable first, so we don't
484                lose address of allocated buffer if realloc fails */
485             tmp = PyMem_Realloc(d->input_buffer, new_size);
486             if (tmp == NULL) {
487                 PyErr_SetNone(PyExc_MemoryError);
488                 return NULL;
489             }
490             d->input_buffer = tmp;
491             d->input_buffer_size = new_size;
492 
493             bzs->next_in = d->input_buffer + offset;
494         }
495         else if (avail_now < len) {
496             memmove(d->input_buffer, bzs->next_in,
497                     d->bzs_avail_in_real);
498             bzs->next_in = d->input_buffer;
499         }
500         memcpy((void*)(bzs->next_in + d->bzs_avail_in_real), data, len);
501         d->bzs_avail_in_real += len;
502         input_buffer_in_use = 1;
503     }
504     else {
505         bzs->next_in = data;
506         d->bzs_avail_in_real = len;
507         input_buffer_in_use = 0;
508     }
509 
510     result = decompress_buf(d, max_length);
511     if(result == NULL) {
512         bzs->next_in = NULL;
513         return NULL;
514     }
515 
516     if (d->eof) {
517         d->needs_input = 0;
518         if (d->bzs_avail_in_real > 0) {
519             Py_XSETREF(d->unused_data,
520                       PyBytes_FromStringAndSize(bzs->next_in, d->bzs_avail_in_real));
521             if (d->unused_data == NULL)
522                 goto error;
523         }
524     }
525     else if (d->bzs_avail_in_real == 0) {
526         bzs->next_in = NULL;
527         d->needs_input = 1;
528     }
529     else {
530         d->needs_input = 0;
531 
532         /* If we did not use the input buffer, we now have
533            to copy the tail from the caller's buffer into the
534            input buffer */
535         if (!input_buffer_in_use) {
536 
537             /* Discard buffer if it's too small
538                (resizing it may needlessly copy the current contents) */
539             if (d->input_buffer != NULL &&
540                 d->input_buffer_size < d->bzs_avail_in_real) {
541                 PyMem_Free(d->input_buffer);
542                 d->input_buffer = NULL;
543             }
544 
545             /* Allocate if necessary */
546             if (d->input_buffer == NULL) {
547                 d->input_buffer = PyMem_Malloc(d->bzs_avail_in_real);
548                 if (d->input_buffer == NULL) {
549                     PyErr_SetNone(PyExc_MemoryError);
550                     goto error;
551                 }
552                 d->input_buffer_size = d->bzs_avail_in_real;
553             }
554 
555             /* Copy tail */
556             memcpy(d->input_buffer, bzs->next_in, d->bzs_avail_in_real);
557             bzs->next_in = d->input_buffer;
558         }
559     }
560 
561     return result;
562 
563 error:
564     Py_XDECREF(result);
565     return NULL;
566 }
567 
568 /*[clinic input]
569 _bz2.BZ2Decompressor.decompress
570 
571     data: Py_buffer
572     max_length: Py_ssize_t=-1
573 
574 Decompress *data*, returning uncompressed data as bytes.
575 
576 If *max_length* is nonnegative, returns at most *max_length* bytes of
577 decompressed data. If this limit is reached and further output can be
578 produced, *self.needs_input* will be set to ``False``. In this case, the next
579 call to *decompress()* may provide *data* as b'' to obtain more of the output.
580 
581 If all of the input data was decompressed and returned (either because this
582 was less than *max_length* bytes, or because *max_length* was negative),
583 *self.needs_input* will be set to True.
584 
585 Attempting to decompress data after the end of stream is reached raises an
586 EOFError.  Any data found after the end of the stream is ignored and saved in
587 the unused_data attribute.
588 [clinic start generated code]*/
589 
590 static PyObject *
_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor * self,Py_buffer * data,Py_ssize_t max_length)591 _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data,
592                                      Py_ssize_t max_length)
593 /*[clinic end generated code: output=23e41045deb240a3 input=52e1ffc66a8ea624]*/
594 {
595     PyObject *result = NULL;
596 
597     ACQUIRE_LOCK(self);
598     if (self->eof)
599         PyErr_SetString(PyExc_EOFError, "End of stream already reached");
600     else
601         result = decompress(self, data->buf, data->len, max_length);
602     RELEASE_LOCK(self);
603     return result;
604 }
605 
606 /*[clinic input]
607 _bz2.BZ2Decompressor.__init__
608 
609 Create a decompressor object for decompressing data incrementally.
610 
611 For one-shot decompression, use the decompress() function instead.
612 [clinic start generated code]*/
613 
614 static int
_bz2_BZ2Decompressor___init___impl(BZ2Decompressor * self)615 _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
616 /*[clinic end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/
617 {
618     int bzerror;
619 
620     PyThread_type_lock lock = PyThread_allocate_lock();
621     if (lock == NULL) {
622         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
623         return -1;
624     }
625     if (self->lock != NULL) {
626         PyThread_free_lock(self->lock);
627     }
628     self->lock = lock;
629 
630     self->needs_input = 1;
631     self->bzs_avail_in_real = 0;
632     self->input_buffer = NULL;
633     self->input_buffer_size = 0;
634     Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0));
635     if (self->unused_data == NULL)
636         goto error;
637 
638     bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0);
639     if (catch_bz2_error(bzerror))
640         goto error;
641 
642     return 0;
643 
644 error:
645     Py_CLEAR(self->unused_data);
646     PyThread_free_lock(self->lock);
647     self->lock = NULL;
648     return -1;
649 }
650 
651 static void
BZ2Decompressor_dealloc(BZ2Decompressor * self)652 BZ2Decompressor_dealloc(BZ2Decompressor *self)
653 {
654     if(self->input_buffer != NULL)
655         PyMem_Free(self->input_buffer);
656     BZ2_bzDecompressEnd(&self->bzs);
657     Py_CLEAR(self->unused_data);
658     if (self->lock != NULL)
659         PyThread_free_lock(self->lock);
660     Py_TYPE(self)->tp_free((PyObject *)self);
661 }
662 
663 static PyMethodDef BZ2Decompressor_methods[] = {
664     _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF
665     {NULL}
666 };
667 
668 PyDoc_STRVAR(BZ2Decompressor_eof__doc__,
669 "True if the end-of-stream marker has been reached.");
670 
671 PyDoc_STRVAR(BZ2Decompressor_unused_data__doc__,
672 "Data found after the end of the compressed stream.");
673 
674 PyDoc_STRVAR(BZ2Decompressor_needs_input_doc,
675 "True if more input is needed before more decompressed data can be produced.");
676 
677 static PyMemberDef BZ2Decompressor_members[] = {
678     {"eof", T_BOOL, offsetof(BZ2Decompressor, eof),
679      READONLY, BZ2Decompressor_eof__doc__},
680     {"unused_data", T_OBJECT_EX, offsetof(BZ2Decompressor, unused_data),
681      READONLY, BZ2Decompressor_unused_data__doc__},
682     {"needs_input", T_BOOL, offsetof(BZ2Decompressor, needs_input), READONLY,
683      BZ2Decompressor_needs_input_doc},
684     {NULL}
685 };
686 
687 static PyTypeObject BZ2Decompressor_Type = {
688     PyVarObject_HEAD_INIT(NULL, 0)
689     "_bz2.BZ2Decompressor",             /* tp_name */
690     sizeof(BZ2Decompressor),            /* tp_basicsize */
691     0,                                  /* tp_itemsize */
692     (destructor)BZ2Decompressor_dealloc,/* tp_dealloc */
693     0,                                  /* tp_vectorcall_offset */
694     0,                                  /* tp_getattr */
695     0,                                  /* tp_setattr */
696     0,                                  /* tp_as_async */
697     0,                                  /* tp_repr */
698     0,                                  /* tp_as_number */
699     0,                                  /* tp_as_sequence */
700     0,                                  /* tp_as_mapping */
701     0,                                  /* tp_hash  */
702     0,                                  /* tp_call */
703     0,                                  /* tp_str */
704     0,                                  /* tp_getattro */
705     0,                                  /* tp_setattro */
706     0,                                  /* tp_as_buffer */
707     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
708     _bz2_BZ2Decompressor___init____doc__,  /* tp_doc */
709     0,                                  /* tp_traverse */
710     0,                                  /* tp_clear */
711     0,                                  /* tp_richcompare */
712     0,                                  /* tp_weaklistoffset */
713     0,                                  /* tp_iter */
714     0,                                  /* tp_iternext */
715     BZ2Decompressor_methods,            /* tp_methods */
716     BZ2Decompressor_members,            /* tp_members */
717     0,                                  /* tp_getset */
718     0,                                  /* tp_base */
719     0,                                  /* tp_dict */
720     0,                                  /* tp_descr_get */
721     0,                                  /* tp_descr_set */
722     0,                                  /* tp_dictoffset */
723     _bz2_BZ2Decompressor___init__,      /* tp_init */
724     0,                                  /* tp_alloc */
725     PyType_GenericNew,                  /* tp_new */
726 };
727 
728 
729 /* Module initialization. */
730 
731 static struct PyModuleDef _bz2module = {
732     PyModuleDef_HEAD_INIT,
733     "_bz2",
734     NULL,
735     -1,
736     NULL,
737     NULL,
738     NULL,
739     NULL,
740     NULL
741 };
742 
743 PyMODINIT_FUNC
PyInit__bz2(void)744 PyInit__bz2(void)
745 {
746     PyObject *m;
747 
748     if (PyType_Ready(&BZ2Compressor_Type) < 0)
749         return NULL;
750     if (PyType_Ready(&BZ2Decompressor_Type) < 0)
751         return NULL;
752 
753     m = PyModule_Create(&_bz2module);
754     if (m == NULL)
755         return NULL;
756 
757     Py_INCREF(&BZ2Compressor_Type);
758     PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Compressor_Type);
759 
760     Py_INCREF(&BZ2Decompressor_Type);
761     PyModule_AddObject(m, "BZ2Decompressor",
762                        (PyObject *)&BZ2Decompressor_Type);
763 
764     return m;
765 }
766