예제 #1
0
static void pylzma_decomp_dealloc(CCompatDecompressionObject *self)
{
    free_lzma_stream(&self->stream);
    FREE_AND_NULL(self->unconsumed_tail);
    DEC_AND_NULL(self->unused_data);
    PyObject_Del(self);
}
예제 #2
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;
}