[python] Use BrotliDecompress()

So that we can use a callback to dynamically allocate the decompression
buffer, getting rid of the optional bufsize argument to
decompress.decompress().
This commit is contained in:
Khaled Hosny 2015-03-13 23:55:03 +02:00
parent ca29aa22c2
commit e0c5df8c61

View File

@ -74,38 +74,40 @@ static PyObject* brotli_compress(PyObject *self, PyObject *args) {
return ret;
}
int output_callback(void* data, const uint8_t* buf, size_t count) {
std::vector<uint8_t> *output = (std::vector<uint8_t> *)data;
output->insert(output->end(), buf, buf + count);
return (int)count;
}
PyDoc_STRVAR(decompress__doc__,
"decompress(string[, bufsize]) -- Return decompressed string."
"\n"
"Optional arg bufsize is the initial output buffer size.");
"decompress(string) -- Return decompressed string.");
static PyObject* brotli_decompress(PyObject *self, PyObject *args) {
PyObject *ret = NULL;
uint8_t *input, *output;
size_t length, output_length = 0;
uint8_t *input;
size_t length;
int ok;
ok = PyArg_ParseTuple(args, "s#|n:decompress",
&input, &length, &output_length);
ok = PyArg_ParseTuple(args, "s#:decompress", &input, &length);
if (!ok)
return NULL;
if (output_length <= 0) {
// Just an arbitrary value, should be big enough
output_length = 4 * length;
}
BrotliMemInput memin;
BrotliInput in = BrotliInitMemInput(input, length, &memin);
output = new uint8_t[output_length];
BrotliOutput out;
std::vector<uint8_t> output;
out.cb_ = &output_callback;
out.data_ = &output;
ok = BrotliDecompressBuffer(length, input, &output_length, output);
ok = BrotliDecompress(in, out);
if (ok) {
ret = PyBytes_FromStringAndSize((char*)output, output_length);
ret = PyBytes_FromStringAndSize((char*)output.data(), output.size());
} else {
PyErr_SetString(BrotliError, "BrotliDecompressBuffer failed");
PyErr_SetString(BrotliError, "BrotliDecompress failed");
}
delete[] output;
return ret;
}