PyObject *pylzma_decompressobj_compat(PyObject *self, PyObject *args) { CCompatDecompressionObject *result=NULL; if (!PyArg_ParseTuple(args, "")) goto exit; result = PyObject_New(CCompatDecompressionObject, &CompatDecompressionObject_Type); CHECK_NULL(result); result->unconsumed_tail = NULL; result->unconsumed_length = 0; result->unused_data = PyBytes_FromString(""); if (result->unused_data == NULL) { PyErr_NoMemory(); PyObject_Del(result); result = NULL; goto exit; } memset(&result->stream, 0, sizeof(result->stream)); lzmaCompatInit(&result->stream); exit: return (PyObject *)result; }
static PyObject *pylzma_decomp_reset(CCompatDecompressionObject *self, PyObject *args) { PyObject *result=NULL; if (!PyArg_ParseTuple(args, "")) return NULL; lzmaCompatInit(&self->stream); FREE_AND_NULL(self->unconsumed_tail); self->unconsumed_length = 0; Py_DECREF(self->unused_data); self->unused_data = PyBytes_FromString(""); CHECK_NULL(self->unused_data); result = Py_None; Py_XINCREF(result); exit: return result; }
PyObject *pylzma_decompress_compat(PyObject *self, PyObject *args) { char *data; int length, blocksize=BLOCK_SIZE; PyObject *result = NULL; lzma_stream stream; int res; char *output; if (!PyArg_ParseTuple(args, "s#|i", &data, &length, &blocksize)) return NULL; memset(&stream, 0, sizeof(stream)); if (!(output = (char *)malloc(blocksize))) { PyErr_NoMemory(); goto exit; } lzmaCompatInit(&stream); stream.next_in = (Byte *)data; stream.avail_in = length; stream.next_out = (Byte *)output; stream.avail_out = blocksize; // decompress data while (1) { Py_BEGIN_ALLOW_THREADS res = lzmaCompatDecode(&stream); Py_END_ALLOW_THREADS if (res == LZMA_STREAM_END) { break; } else if (res == LZMA_NOT_ENOUGH_MEM) { // out of memory during decompression PyErr_NoMemory(); goto exit; } else if (res == LZMA_DATA_ERROR) { PyErr_SetString(PyExc_ValueError, "data error during decompression"); goto exit; } else if (res == LZMA_OK) { // check if we need to adjust the output buffer if (stream.avail_out == 0) { output = (char *)realloc(output, blocksize+BLOCK_SIZE); stream.avail_out = BLOCK_SIZE; stream.next_out = (Byte *)&output[blocksize]; blocksize += BLOCK_SIZE; }; } else { PyErr_Format(PyExc_ValueError, "unknown return code from lzmaDecode: %d", res); goto exit; } // if we exit here, decompression finished without returning LZMA_STREAM_END // XXX: why is this sometimes? if (stream.avail_in == 0) break; } result = PyBytes_FromStringAndSize(output, stream.totalOut); exit: free_lzma_stream(&stream); if (output != NULL) free(output); return result; }