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