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;
}
Esempio n. 3
0
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;
}