• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 PyObject *
BZ2Compressor_getstate(BZ2Compressor * self,PyObject * noargs)268 BZ2Compressor_getstate(BZ2Compressor *self, PyObject *noargs)
269 {
270     PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
271                  Py_TYPE(self)->tp_name);
272     return NULL;
273 }
274 
275 static void*
BZ2_Malloc(void * ctx,int items,int size)276 BZ2_Malloc(void* ctx, int items, int size)
277 {
278     if (items < 0 || size < 0)
279         return NULL;
280     if (size != 0 && (size_t)items > (size_t)PY_SSIZE_T_MAX / (size_t)size)
281         return NULL;
282     /* PyMem_Malloc() cannot be used: compress() and decompress()
283        release the GIL */
284     return PyMem_RawMalloc((size_t)items * (size_t)size);
285 }
286 
287 static void
BZ2_Free(void * ctx,void * ptr)288 BZ2_Free(void* ctx, void *ptr)
289 {
290     PyMem_RawFree(ptr);
291 }
292 
293 /*[clinic input]
294 _bz2.BZ2Compressor.__init__
295 
296     compresslevel: int = 9
297         Compression level, as a number between 1 and 9.
298     /
299 
300 Create a compressor object for compressing data incrementally.
301 
302 For one-shot compression, use the compress() function instead.
303 [clinic start generated code]*/
304 
305 static int
_bz2_BZ2Compressor___init___impl(BZ2Compressor * self,int compresslevel)306 _bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
307 /*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/
308 {
309     int bzerror;
310 
311     if (!(1 <= compresslevel && compresslevel <= 9)) {
312         PyErr_SetString(PyExc_ValueError,
313                         "compresslevel must be between 1 and 9");
314         return -1;
315     }
316 
317     self->lock = PyThread_allocate_lock();
318     if (self->lock == NULL) {
319         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
320         return -1;
321     }
322 
323     self->bzs.opaque = NULL;
324     self->bzs.bzalloc = BZ2_Malloc;
325     self->bzs.bzfree = BZ2_Free;
326     bzerror = BZ2_bzCompressInit(&self->bzs, compresslevel, 0, 0);
327     if (catch_bz2_error(bzerror))
328         goto error;
329 
330     return 0;
331 
332 error:
333     PyThread_free_lock(self->lock);
334     self->lock = NULL;
335     return -1;
336 }
337 
338 static void
BZ2Compressor_dealloc(BZ2Compressor * self)339 BZ2Compressor_dealloc(BZ2Compressor *self)
340 {
341     BZ2_bzCompressEnd(&self->bzs);
342     if (self->lock != NULL)
343         PyThread_free_lock(self->lock);
344     Py_TYPE(self)->tp_free((PyObject *)self);
345 }
346 
347 static PyMethodDef BZ2Compressor_methods[] = {
348     _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF
349     _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF
350     {"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS},
351     {NULL}
352 };
353 
354 
355 static PyTypeObject BZ2Compressor_Type = {
356     PyVarObject_HEAD_INIT(NULL, 0)
357     "_bz2.BZ2Compressor",               /* tp_name */
358     sizeof(BZ2Compressor),              /* tp_basicsize */
359     0,                                  /* tp_itemsize */
360     (destructor)BZ2Compressor_dealloc,  /* tp_dealloc */
361     0,                                  /* tp_print */
362     0,                                  /* tp_getattr */
363     0,                                  /* tp_setattr */
364     0,                                  /* tp_reserved */
365     0,                                  /* tp_repr */
366     0,                                  /* tp_as_number */
367     0,                                  /* tp_as_sequence */
368     0,                                  /* tp_as_mapping */
369     0,                                  /* tp_hash  */
370     0,                                  /* tp_call */
371     0,                                  /* tp_str */
372     0,                                  /* tp_getattro */
373     0,                                  /* tp_setattro */
374     0,                                  /* tp_as_buffer */
375     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
376     _bz2_BZ2Compressor___init____doc__,  /* tp_doc */
377     0,                                  /* tp_traverse */
378     0,                                  /* tp_clear */
379     0,                                  /* tp_richcompare */
380     0,                                  /* tp_weaklistoffset */
381     0,                                  /* tp_iter */
382     0,                                  /* tp_iternext */
383     BZ2Compressor_methods,              /* tp_methods */
384     0,                                  /* tp_members */
385     0,                                  /* tp_getset */
386     0,                                  /* tp_base */
387     0,                                  /* tp_dict */
388     0,                                  /* tp_descr_get */
389     0,                                  /* tp_descr_set */
390     0,                                  /* tp_dictoffset */
391     _bz2_BZ2Compressor___init__,        /* tp_init */
392     0,                                  /* tp_alloc */
393     PyType_GenericNew,                  /* tp_new */
394 };
395 
396 
397 /* BZ2Decompressor class. */
398 
399 /* Decompress data of length d->bzs_avail_in_real in d->bzs.next_in.  The output
400    buffer is allocated dynamically and returned.  At most max_length bytes are
401    returned, so some of the input may not be consumed. d->bzs.next_in and
402    d->bzs_avail_in_real are updated to reflect the consumed input. */
403 static PyObject*
decompress_buf(BZ2Decompressor * d,Py_ssize_t max_length)404 decompress_buf(BZ2Decompressor *d, Py_ssize_t max_length)
405 {
406     /* data_size is strictly positive, but because we repeatedly have to
407        compare against max_length and PyBytes_GET_SIZE we declare it as
408        signed */
409     Py_ssize_t data_size = 0;
410     PyObject *result;
411     bz_stream *bzs = &d->bzs;
412 
413     if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE)
414         result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
415     else
416         result = PyBytes_FromStringAndSize(NULL, max_length);
417     if (result == NULL)
418         return NULL;
419 
420     bzs->next_out = PyBytes_AS_STRING(result);
421     for (;;) {
422         int bzret;
423         size_t avail;
424 
425         /* On a 64-bit system, buffer length might not fit in avail_out, so we
426            do decompression in chunks of no more than UINT_MAX bytes
427            each. Note that the expression for `avail` is guaranteed to be
428            positive, so the cast is safe. */
429         avail = (size_t) (PyBytes_GET_SIZE(result) - data_size);
430         bzs->avail_out = (unsigned int)Py_MIN(avail, UINT_MAX);
431         bzs->avail_in = (unsigned int)Py_MIN(d->bzs_avail_in_real, UINT_MAX);
432         d->bzs_avail_in_real -= bzs->avail_in;
433 
434         Py_BEGIN_ALLOW_THREADS
435         bzret = BZ2_bzDecompress(bzs);
436         data_size = bzs->next_out - PyBytes_AS_STRING(result);
437         d->bzs_avail_in_real += bzs->avail_in;
438         Py_END_ALLOW_THREADS
439         if (catch_bz2_error(bzret))
440             goto error;
441         if (bzret == BZ_STREAM_END) {
442             d->eof = 1;
443             break;
444         } else if (d->bzs_avail_in_real == 0) {
445             break;
446         } else if (bzs->avail_out == 0) {
447             if (data_size == max_length)
448                 break;
449             if (data_size == PyBytes_GET_SIZE(result) &&
450                 grow_buffer(&result, max_length) == -1)
451                 goto error;
452             bzs->next_out = PyBytes_AS_STRING(result) + data_size;
453         }
454     }
455     if (data_size != PyBytes_GET_SIZE(result))
456         if (_PyBytes_Resize(&result, data_size) == -1)
457             goto error;
458 
459     return result;
460 
461 error:
462     Py_XDECREF(result);
463     return NULL;
464 }
465 
466 
467 static PyObject *
decompress(BZ2Decompressor * d,char * data,size_t len,Py_ssize_t max_length)468 decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length)
469 {
470     char input_buffer_in_use;
471     PyObject *result;
472     bz_stream *bzs = &d->bzs;
473 
474     /* Prepend unconsumed input if necessary */
475     if (bzs->next_in != NULL) {
476         size_t avail_now, avail_total;
477 
478         /* Number of bytes we can append to input buffer */
479         avail_now = (d->input_buffer + d->input_buffer_size)
480             - (bzs->next_in + d->bzs_avail_in_real);
481 
482         /* Number of bytes we can append if we move existing
483            contents to beginning of buffer (overwriting
484            consumed input) */
485         avail_total = d->input_buffer_size - d->bzs_avail_in_real;
486 
487         if (avail_total < len) {
488             size_t offset = bzs->next_in - d->input_buffer;
489             char *tmp;
490             size_t new_size = d->input_buffer_size + len - avail_now;
491 
492             /* Assign to temporary variable first, so we don't
493                lose address of allocated buffer if realloc fails */
494             tmp = PyMem_Realloc(d->input_buffer, new_size);
495             if (tmp == NULL) {
496                 PyErr_SetNone(PyExc_MemoryError);
497                 return NULL;
498             }
499             d->input_buffer = tmp;
500             d->input_buffer_size = new_size;
501 
502             bzs->next_in = d->input_buffer + offset;
503         }
504         else if (avail_now < len) {
505             memmove(d->input_buffer, bzs->next_in,
506                     d->bzs_avail_in_real);
507             bzs->next_in = d->input_buffer;
508         }
509         memcpy((void*)(bzs->next_in + d->bzs_avail_in_real), data, len);
510         d->bzs_avail_in_real += len;
511         input_buffer_in_use = 1;
512     }
513     else {
514         bzs->next_in = data;
515         d->bzs_avail_in_real = len;
516         input_buffer_in_use = 0;
517     }
518 
519     result = decompress_buf(d, max_length);
520     if(result == NULL) {
521         bzs->next_in = NULL;
522         return NULL;
523     }
524 
525     if (d->eof) {
526         d->needs_input = 0;
527         if (d->bzs_avail_in_real > 0) {
528             Py_XSETREF(d->unused_data,
529                       PyBytes_FromStringAndSize(bzs->next_in, d->bzs_avail_in_real));
530             if (d->unused_data == NULL)
531                 goto error;
532         }
533     }
534     else if (d->bzs_avail_in_real == 0) {
535         bzs->next_in = NULL;
536         d->needs_input = 1;
537     }
538     else {
539         d->needs_input = 0;
540 
541         /* If we did not use the input buffer, we now have
542            to copy the tail from the caller's buffer into the
543            input buffer */
544         if (!input_buffer_in_use) {
545 
546             /* Discard buffer if it's too small
547                (resizing it may needlessly copy the current contents) */
548             if (d->input_buffer != NULL &&
549                 d->input_buffer_size < d->bzs_avail_in_real) {
550                 PyMem_Free(d->input_buffer);
551                 d->input_buffer = NULL;
552             }
553 
554             /* Allocate if necessary */
555             if (d->input_buffer == NULL) {
556                 d->input_buffer = PyMem_Malloc(d->bzs_avail_in_real);
557                 if (d->input_buffer == NULL) {
558                     PyErr_SetNone(PyExc_MemoryError);
559                     goto error;
560                 }
561                 d->input_buffer_size = d->bzs_avail_in_real;
562             }
563 
564             /* Copy tail */
565             memcpy(d->input_buffer, bzs->next_in, d->bzs_avail_in_real);
566             bzs->next_in = d->input_buffer;
567         }
568     }
569 
570     return result;
571 
572 error:
573     Py_XDECREF(result);
574     return NULL;
575 }
576 
577 /*[clinic input]
578 _bz2.BZ2Decompressor.decompress
579 
580     data: Py_buffer
581     max_length: Py_ssize_t=-1
582 
583 Decompress *data*, returning uncompressed data as bytes.
584 
585 If *max_length* is nonnegative, returns at most *max_length* bytes of
586 decompressed data. If this limit is reached and further output can be
587 produced, *self.needs_input* will be set to ``False``. In this case, the next
588 call to *decompress()* may provide *data* as b'' to obtain more of the output.
589 
590 If all of the input data was decompressed and returned (either because this
591 was less than *max_length* bytes, or because *max_length* was negative),
592 *self.needs_input* will be set to True.
593 
594 Attempting to decompress data after the end of stream is reached raises an
595 EOFError.  Any data found after the end of the stream is ignored and saved in
596 the unused_data attribute.
597 [clinic start generated code]*/
598 
599 static PyObject *
_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor * self,Py_buffer * data,Py_ssize_t max_length)600 _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data,
601                                      Py_ssize_t max_length)
602 /*[clinic end generated code: output=23e41045deb240a3 input=52e1ffc66a8ea624]*/
603 {
604     PyObject *result = NULL;
605 
606     ACQUIRE_LOCK(self);
607     if (self->eof)
608         PyErr_SetString(PyExc_EOFError, "End of stream already reached");
609     else
610         result = decompress(self, data->buf, data->len, max_length);
611     RELEASE_LOCK(self);
612     return result;
613 }
614 
615 static PyObject *
BZ2Decompressor_getstate(BZ2Decompressor * self,PyObject * noargs)616 BZ2Decompressor_getstate(BZ2Decompressor *self, PyObject *noargs)
617 {
618     PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
619                  Py_TYPE(self)->tp_name);
620     return NULL;
621 }
622 
623 /*[clinic input]
624 _bz2.BZ2Decompressor.__init__
625 
626 Create a decompressor object for decompressing data incrementally.
627 
628 For one-shot decompression, use the decompress() function instead.
629 [clinic start generated code]*/
630 
631 static int
_bz2_BZ2Decompressor___init___impl(BZ2Decompressor * self)632 _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
633 /*[clinic end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/
634 {
635     int bzerror;
636 
637     PyThread_type_lock lock = PyThread_allocate_lock();
638     if (lock == NULL) {
639         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
640         return -1;
641     }
642     if (self->lock != NULL) {
643         PyThread_free_lock(self->lock);
644     }
645     self->lock = lock;
646 
647     self->needs_input = 1;
648     self->bzs_avail_in_real = 0;
649     self->input_buffer = NULL;
650     self->input_buffer_size = 0;
651     Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0));
652     if (self->unused_data == NULL)
653         goto error;
654 
655     bzerror = BZ2_bzDecompressInit(&self->bzs, 0, 0);
656     if (catch_bz2_error(bzerror))
657         goto error;
658 
659     return 0;
660 
661 error:
662     Py_CLEAR(self->unused_data);
663     PyThread_free_lock(self->lock);
664     self->lock = NULL;
665     return -1;
666 }
667 
668 static void
BZ2Decompressor_dealloc(BZ2Decompressor * self)669 BZ2Decompressor_dealloc(BZ2Decompressor *self)
670 {
671     if(self->input_buffer != NULL)
672         PyMem_Free(self->input_buffer);
673     BZ2_bzDecompressEnd(&self->bzs);
674     Py_CLEAR(self->unused_data);
675     if (self->lock != NULL)
676         PyThread_free_lock(self->lock);
677     Py_TYPE(self)->tp_free((PyObject *)self);
678 }
679 
680 static PyMethodDef BZ2Decompressor_methods[] = {
681     _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF
682     {"__getstate__", (PyCFunction)BZ2Decompressor_getstate, METH_NOARGS},
683     {NULL}
684 };
685 
686 PyDoc_STRVAR(BZ2Decompressor_eof__doc__,
687 "True if the end-of-stream marker has been reached.");
688 
689 PyDoc_STRVAR(BZ2Decompressor_unused_data__doc__,
690 "Data found after the end of the compressed stream.");
691 
692 PyDoc_STRVAR(BZ2Decompressor_needs_input_doc,
693 "True if more input is needed before more decompressed data can be produced.");
694 
695 static PyMemberDef BZ2Decompressor_members[] = {
696     {"eof", T_BOOL, offsetof(BZ2Decompressor, eof),
697      READONLY, BZ2Decompressor_eof__doc__},
698     {"unused_data", T_OBJECT_EX, offsetof(BZ2Decompressor, unused_data),
699      READONLY, BZ2Decompressor_unused_data__doc__},
700     {"needs_input", T_BOOL, offsetof(BZ2Decompressor, needs_input), READONLY,
701      BZ2Decompressor_needs_input_doc},
702     {NULL}
703 };
704 
705 static PyTypeObject BZ2Decompressor_Type = {
706     PyVarObject_HEAD_INIT(NULL, 0)
707     "_bz2.BZ2Decompressor",             /* tp_name */
708     sizeof(BZ2Decompressor),            /* tp_basicsize */
709     0,                                  /* tp_itemsize */
710     (destructor)BZ2Decompressor_dealloc,/* tp_dealloc */
711     0,                                  /* tp_print */
712     0,                                  /* tp_getattr */
713     0,                                  /* tp_setattr */
714     0,                                  /* tp_reserved */
715     0,                                  /* tp_repr */
716     0,                                  /* tp_as_number */
717     0,                                  /* tp_as_sequence */
718     0,                                  /* tp_as_mapping */
719     0,                                  /* tp_hash  */
720     0,                                  /* tp_call */
721     0,                                  /* tp_str */
722     0,                                  /* tp_getattro */
723     0,                                  /* tp_setattro */
724     0,                                  /* tp_as_buffer */
725     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
726     _bz2_BZ2Decompressor___init____doc__,  /* tp_doc */
727     0,                                  /* tp_traverse */
728     0,                                  /* tp_clear */
729     0,                                  /* tp_richcompare */
730     0,                                  /* tp_weaklistoffset */
731     0,                                  /* tp_iter */
732     0,                                  /* tp_iternext */
733     BZ2Decompressor_methods,            /* tp_methods */
734     BZ2Decompressor_members,            /* tp_members */
735     0,                                  /* tp_getset */
736     0,                                  /* tp_base */
737     0,                                  /* tp_dict */
738     0,                                  /* tp_descr_get */
739     0,                                  /* tp_descr_set */
740     0,                                  /* tp_dictoffset */
741     _bz2_BZ2Decompressor___init__,      /* tp_init */
742     0,                                  /* tp_alloc */
743     PyType_GenericNew,                  /* tp_new */
744 };
745 
746 
747 /* Module initialization. */
748 
749 static struct PyModuleDef _bz2module = {
750     PyModuleDef_HEAD_INIT,
751     "_bz2",
752     NULL,
753     -1,
754     NULL,
755     NULL,
756     NULL,
757     NULL,
758     NULL
759 };
760 
761 PyMODINIT_FUNC
PyInit__bz2(void)762 PyInit__bz2(void)
763 {
764     PyObject *m;
765 
766     if (PyType_Ready(&BZ2Compressor_Type) < 0)
767         return NULL;
768     if (PyType_Ready(&BZ2Decompressor_Type) < 0)
769         return NULL;
770 
771     m = PyModule_Create(&_bz2module);
772     if (m == NULL)
773         return NULL;
774 
775     Py_INCREF(&BZ2Compressor_Type);
776     PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Compressor_Type);
777 
778     Py_INCREF(&BZ2Decompressor_Type);
779     PyModule_AddObject(m, "BZ2Decompressor",
780                        (PyObject *)&BZ2Decompressor_Type);
781 
782     return m;
783 }
784