Mercurial > hg
comparison contrib/python-zstandard/c-ext/decompressionwriter.c @ 37495:b1fb341d8a61
zstandard: vendor python-zstandard 0.9.0
This was just released. It features a number of goodies. More info at
https://gregoryszorc.com/blog/2018/04/09/release-of-python-zstandard-0.9/.
The clang-format ignore list was updated to reflect the new source
of files.
The project contains a vendored copy of zstandard 1.3.4. The old
version was 1.1.3. One of the changes between those versions is that
zstandard is now dual licensed BSD + GPLv2 and the patent rights grant
has been removed. Good riddance.
The API should be backwards compatible. So no changes in core
should be needed. However, there were a number of changes in the
library that we'll want to adapt to. Those will be addressed in
subsequent commits.
Differential Revision: https://phab.mercurial-scm.org/D3198
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 09 Apr 2018 10:13:29 -0700 |
parents | e0dc40530c5a |
children | 675775c33ab6 |
comparison
equal
deleted
inserted
replaced
37494:1ce7a55b09d1 | 37495:b1fb341d8a61 |
---|---|
25 if (self->entered) { | 25 if (self->entered) { |
26 PyErr_SetString(ZstdError, "cannot __enter__ multiple times"); | 26 PyErr_SetString(ZstdError, "cannot __enter__ multiple times"); |
27 return NULL; | 27 return NULL; |
28 } | 28 } |
29 | 29 |
30 if (0 != init_dstream(self->decompressor)) { | 30 if (ensure_dctx(self->decompressor, 1)) { |
31 return NULL; | 31 return NULL; |
32 } | 32 } |
33 | 33 |
34 self->entered = 1; | 34 self->entered = 1; |
35 | 35 |
42 | 42 |
43 Py_RETURN_FALSE; | 43 Py_RETURN_FALSE; |
44 } | 44 } |
45 | 45 |
46 static PyObject* ZstdDecompressionWriter_memory_size(ZstdDecompressionWriter* self) { | 46 static PyObject* ZstdDecompressionWriter_memory_size(ZstdDecompressionWriter* self) { |
47 if (!self->decompressor->dstream) { | 47 return PyLong_FromSize_t(ZSTD_sizeof_DCtx(self->decompressor->dctx)); |
48 PyErr_SetString(ZstdError, "cannot determine size of inactive decompressor; " | |
49 "call when context manager is active"); | |
50 return NULL; | |
51 } | |
52 | |
53 return PyLong_FromSize_t(ZSTD_sizeof_DStream(self->decompressor->dstream)); | |
54 } | 48 } |
55 | 49 |
56 static PyObject* ZstdDecompressionWriter_write(ZstdDecompressionWriter* self, PyObject* args) { | 50 static PyObject* ZstdDecompressionWriter_write(ZstdDecompressionWriter* self, PyObject* args, PyObject* kwargs) { |
57 const char* source; | 51 static char* kwlist[] = { |
58 Py_ssize_t sourceSize; | 52 "data", |
53 NULL | |
54 }; | |
55 | |
56 PyObject* result = NULL; | |
57 Py_buffer source; | |
59 size_t zresult = 0; | 58 size_t zresult = 0; |
60 ZSTD_inBuffer input; | 59 ZSTD_inBuffer input; |
61 ZSTD_outBuffer output; | 60 ZSTD_outBuffer output; |
62 PyObject* res; | 61 PyObject* res; |
63 Py_ssize_t totalWrite = 0; | 62 Py_ssize_t totalWrite = 0; |
64 | 63 |
65 #if PY_MAJOR_VERSION >= 3 | 64 #if PY_MAJOR_VERSION >= 3 |
66 if (!PyArg_ParseTuple(args, "y#:write", &source, &sourceSize)) { | 65 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*:write", |
67 #else | 66 #else |
68 if (!PyArg_ParseTuple(args, "s#:write", &source, &sourceSize)) { | 67 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*:write", |
69 #endif | 68 #endif |
69 kwlist, &source)) { | |
70 return NULL; | 70 return NULL; |
71 } | |
72 | |
73 if (!PyBuffer_IsContiguous(&source, 'C') || source.ndim > 1) { | |
74 PyErr_SetString(PyExc_ValueError, | |
75 "data buffer should be contiguous and have at most one dimension"); | |
76 goto finally; | |
71 } | 77 } |
72 | 78 |
73 if (!self->entered) { | 79 if (!self->entered) { |
74 PyErr_SetString(ZstdError, "write must be called from an active context manager"); | 80 PyErr_SetString(ZstdError, "write must be called from an active context manager"); |
75 return NULL; | 81 goto finally; |
76 } | 82 } |
77 | |
78 assert(self->decompressor->dstream); | |
79 | 83 |
80 output.dst = PyMem_Malloc(self->outSize); | 84 output.dst = PyMem_Malloc(self->outSize); |
81 if (!output.dst) { | 85 if (!output.dst) { |
82 return PyErr_NoMemory(); | 86 PyErr_NoMemory(); |
87 goto finally; | |
83 } | 88 } |
84 output.size = self->outSize; | 89 output.size = self->outSize; |
85 output.pos = 0; | 90 output.pos = 0; |
86 | 91 |
87 input.src = source; | 92 input.src = source.buf; |
88 input.size = sourceSize; | 93 input.size = source.len; |
89 input.pos = 0; | 94 input.pos = 0; |
90 | 95 |
91 while ((ssize_t)input.pos < sourceSize) { | 96 while ((ssize_t)input.pos < source.len) { |
92 Py_BEGIN_ALLOW_THREADS | 97 Py_BEGIN_ALLOW_THREADS |
93 zresult = ZSTD_decompressStream(self->decompressor->dstream, &output, &input); | 98 zresult = ZSTD_decompress_generic(self->decompressor->dctx, &output, &input); |
94 Py_END_ALLOW_THREADS | 99 Py_END_ALLOW_THREADS |
95 | 100 |
96 if (ZSTD_isError(zresult)) { | 101 if (ZSTD_isError(zresult)) { |
97 PyMem_Free(output.dst); | 102 PyMem_Free(output.dst); |
98 PyErr_Format(ZstdError, "zstd decompress error: %s", | 103 PyErr_Format(ZstdError, "zstd decompress error: %s", |
99 ZSTD_getErrorName(zresult)); | 104 ZSTD_getErrorName(zresult)); |
100 return NULL; | 105 goto finally; |
101 } | 106 } |
102 | 107 |
103 if (output.pos) { | 108 if (output.pos) { |
104 #if PY_MAJOR_VERSION >= 3 | 109 #if PY_MAJOR_VERSION >= 3 |
105 res = PyObject_CallMethod(self->writer, "write", "y#", | 110 res = PyObject_CallMethod(self->writer, "write", "y#", |
113 } | 118 } |
114 } | 119 } |
115 | 120 |
116 PyMem_Free(output.dst); | 121 PyMem_Free(output.dst); |
117 | 122 |
118 return PyLong_FromSsize_t(totalWrite); | 123 result = PyLong_FromSsize_t(totalWrite); |
124 | |
125 finally: | |
126 PyBuffer_Release(&source); | |
127 return result; | |
119 } | 128 } |
120 | 129 |
121 static PyMethodDef ZstdDecompressionWriter_methods[] = { | 130 static PyMethodDef ZstdDecompressionWriter_methods[] = { |
122 { "__enter__", (PyCFunction)ZstdDecompressionWriter_enter, METH_NOARGS, | 131 { "__enter__", (PyCFunction)ZstdDecompressionWriter_enter, METH_NOARGS, |
123 PyDoc_STR("Enter a decompression context.") }, | 132 PyDoc_STR("Enter a decompression context.") }, |
124 { "__exit__", (PyCFunction)ZstdDecompressionWriter_exit, METH_VARARGS, | 133 { "__exit__", (PyCFunction)ZstdDecompressionWriter_exit, METH_VARARGS, |
125 PyDoc_STR("Exit a decompression context.") }, | 134 PyDoc_STR("Exit a decompression context.") }, |
126 { "memory_size", (PyCFunction)ZstdDecompressionWriter_memory_size, METH_NOARGS, | 135 { "memory_size", (PyCFunction)ZstdDecompressionWriter_memory_size, METH_NOARGS, |
127 PyDoc_STR("Obtain the memory size in bytes of the underlying decompressor.") }, | 136 PyDoc_STR("Obtain the memory size in bytes of the underlying decompressor.") }, |
128 { "write", (PyCFunction)ZstdDecompressionWriter_write, METH_VARARGS, | 137 { "write", (PyCFunction)ZstdDecompressionWriter_write, METH_VARARGS | METH_KEYWORDS, |
129 PyDoc_STR("Compress data") }, | 138 PyDoc_STR("Compress data") }, |
130 { NULL, NULL } | 139 { NULL, NULL } |
131 }; | 140 }; |
132 | 141 |
133 PyTypeObject ZstdDecompressionWriterType = { | 142 PyTypeObject ZstdDecompressionWriterType = { |