aboutsummaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorEugene Kliuchnikov <eustas@google.com>2017-08-28 11:31:29 +0200
committerGitHub <noreply@github.com>2017-08-28 11:31:29 +0200
commita629289e3297bcfd25648293df3e1d6dfd59df24 (patch)
treecd6f2caf185267b717f4927bf8752eaecf269c75 /python
parent653543541319e2318d2fc572cf5c7f3275b9c12c (diff)
downloadbrotli-a629289e3297bcfd25648293df3e1d6dfd59df24.zip
brotli-a629289e3297bcfd25648293df3e1d6dfd59df24.tar.gz
brotli-a629289e3297bcfd25648293df3e1d6dfd59df24.tar.bz2
Update (#590)
* add transpiled JS decoder * make PY wrapper accept memview * fix dictionary generator * speedup compression of RLEish data
Diffstat (limited to 'python')
-rw-r--r--python/README.md2
-rw-r--r--python/_brotli.cc54
2 files changed, 39 insertions, 17 deletions
diff --git a/python/README.md b/python/README.md
index 3b0d8b2..6a9068a 100644
--- a/python/README.md
+++ b/python/README.md
@@ -1,6 +1,8 @@
This directory contains the code for the Python `brotli` module,
`bro.py` tool, and roundtrip tests.
+Only Python 2.7+ is supported.
+
We provide a `Makefile` to simplify common development commands.
### Installation
diff --git a/python/_brotli.cc b/python/_brotli.cc
index d17b90d..a6f925e 100644
--- a/python/_brotli.cc
+++ b/python/_brotli.cc
@@ -88,7 +88,8 @@ static int lgblock_convertor(PyObject *o, int *lgblock) {
}
static BROTLI_BOOL compress_stream(BrotliEncoderState* enc, BrotliEncoderOperation op,
- std::vector<uint8_t>* output, uint8_t* input, size_t input_length) {
+ std::vector<uint8_t>* output,
+ uint8_t* input, size_t input_length) {
BROTLI_BOOL ok = BROTLI_TRUE;
Py_BEGIN_ALLOW_THREADS
@@ -222,11 +223,15 @@ PyDoc_STRVAR(brotli_Compressor_process_doc,
static PyObject* brotli_Compressor_process(brotli_Compressor *self, PyObject *args) {
PyObject* ret = NULL;
std::vector<uint8_t> output;
- uint8_t* input;
- size_t input_length;
+ Py_buffer input;
BROTLI_BOOL ok = BROTLI_TRUE;
- ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "s#:process", &input, &input_length);
+#if PY_MAJOR_VERSION >= 3
+ ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "y*:process", &input);
+#else
+ ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "s*:process", &input);
+#endif
+
if (!ok)
return NULL;
@@ -236,9 +241,10 @@ static PyObject* brotli_Compressor_process(brotli_Compressor *self, PyObject *ar
}
ok = compress_stream(self->enc, BROTLI_OPERATION_PROCESS,
- &output, input, input_length);
+ &output, static_cast<uint8_t*>(input.buf), input.len);
end:
+ PyBuffer_Release(&input);
if (ok) {
ret = PyBytes_FromStringAndSize((char*)(output.size() ? &output[0] : NULL), output.size());
} else {
@@ -387,7 +393,8 @@ static PyTypeObject brotli_CompressorType = {
};
static BROTLI_BOOL decompress_stream(BrotliDecoderState* dec,
- std::vector<uint8_t>* output, uint8_t* input, size_t input_length) {
+ std::vector<uint8_t>* output,
+ uint8_t* input, size_t input_length) {
BROTLI_BOOL ok = BROTLI_TRUE;
Py_BEGIN_ALLOW_THREADS
@@ -485,11 +492,15 @@ PyDoc_STRVAR(brotli_Decompressor_process_doc,
static PyObject* brotli_Decompressor_process(brotli_Decompressor *self, PyObject *args) {
PyObject* ret = NULL;
std::vector<uint8_t> output;
- uint8_t* input;
- size_t input_length;
+ Py_buffer input;
BROTLI_BOOL ok = BROTLI_TRUE;
- ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "s#:process", &input, &input_length);
+#if PY_MAJOR_VERSION >= 3
+ ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "y*:process", &input);
+#else
+ ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "s*:process", &input);
+#endif
+
if (!ok)
return NULL;
@@ -498,10 +509,10 @@ static PyObject* brotli_Decompressor_process(brotli_Decompressor *self, PyObject
goto end;
}
- ok = decompress_stream(self->dec,
- &output, input, input_length);
+ ok = decompress_stream(self->dec, &output, static_cast<uint8_t*>(input.buf), input.len);
end:
+ PyBuffer_Release(&input);
if (ok) {
ret = PyBytes_FromStringAndSize((char*)(output.empty() ? NULL : &output[0]), output.size());
} else {
@@ -625,15 +636,21 @@ PyDoc_STRVAR(brotli_decompress__doc__,
static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *keywds) {
PyObject *ret = NULL;
- const uint8_t *input;
- size_t length;
+ Py_buffer input;
+ const uint8_t* next_in;
+ size_t available_in;
int ok;
static const char *kwlist[] = {"string", NULL};
- ok = PyArg_ParseTupleAndKeywords(args, keywds, "s#|:decompress",
- const_cast<char **>(kwlist),
- &input, &length);
+#if PY_MAJOR_VERSION >= 3
+ ok = PyArg_ParseTupleAndKeywords(args, keywds, "y*|:decompress",
+ const_cast<char **>(kwlist), &input);
+#else
+ ok = PyArg_ParseTupleAndKeywords(args, keywds, "s*|:decompress",
+ const_cast<char **>(kwlist), &input);
+#endif
+
if (!ok)
return NULL;
@@ -645,9 +662,11 @@ static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *key
BrotliDecoderState* state = BrotliDecoderCreateInstance(0, 0, 0);
BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;
+ next_in = static_cast<uint8_t*>(input.buf);
+ available_in = input.len;
while (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
size_t available_out = 0;
- result = BrotliDecoderDecompressStream(state, &length, &input,
+ result = BrotliDecoderDecompressStream(state, &available_in, &next_in,
&available_out, 0, 0);
const uint8_t* next_out = BrotliDecoderTakeOutput(state, &available_out);
if (available_out != 0)
@@ -659,6 +678,7 @@ static PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *key
Py_END_ALLOW_THREADS
/* <<< Pure C block end. Python GIL reacquired. */
+ PyBuffer_Release(&input);
if (ok) {
ret = PyBytes_FromStringAndSize((char*)(output.size() ? &output[0] : NULL), output.size());
} else {