comparison contrib/python-zstandard/c-ext/decompressobj.c @ 40121:73fef626dae3

zstandard: vendor python-zstandard 0.10.1 This was just released. The upstream source distribution from PyPI was extracted. Unwanted files were removed. The clang-format ignore list was updated to reflect the new source of files. setup.py was updated to pass a new argument to python-zstandard's function for returning an Extension instance. Upstream had to change to use relative paths because Python 3.7's packaging doesn't seem to like absolute paths when defining sources, includes, etc. The default relative path calculation is relative to setup_zstd.py which is different from the directory of Mercurial's setup.py. The project contains a vendored copy of zstandard 1.3.6. The old version was 1.3.4. The API should be backwards compatible and nothing in core should need adjusted. However, there is a new "chunker" API that we may find useful in places where we want to emit compressed chunks of a fixed size. There are a pair of bug fixes in 0.10.0 with regards to compressobj() and decompressobj() when block flushing is used. I actually found these bugs when introducing these APIs in Mercurial! But existing Mercurial code is not affected because we don't perform block flushing. # no-check-commit because 3rd party code has different style guidelines Differential Revision: https://phab.mercurial-scm.org/D4911
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 08 Oct 2018 16:27:40 -0700
parents b1fb341d8a61
children 675775c33ab6
comparison
equal deleted inserted replaced
40120:89742f1fa6cb 40121:73fef626dae3
31 ZSTD_inBuffer input; 31 ZSTD_inBuffer input;
32 ZSTD_outBuffer output; 32 ZSTD_outBuffer output;
33 PyObject* result = NULL; 33 PyObject* result = NULL;
34 Py_ssize_t resultSize = 0; 34 Py_ssize_t resultSize = 0;
35 35
36 output.dst = NULL;
37
36 if (self->finished) { 38 if (self->finished) {
37 PyErr_SetString(ZstdError, "cannot use a decompressobj multiple times"); 39 PyErr_SetString(ZstdError, "cannot use a decompressobj multiple times");
38 return NULL; 40 return NULL;
39 } 41 }
40 42
51 PyErr_SetString(PyExc_ValueError, 53 PyErr_SetString(PyExc_ValueError,
52 "data buffer should be contiguous and have at most one dimension"); 54 "data buffer should be contiguous and have at most one dimension");
53 goto finally; 55 goto finally;
54 } 56 }
55 57
58 /* Special case of empty input. Output will always be empty. */
59 if (source.len == 0) {
60 result = PyBytes_FromString("");
61 goto finally;
62 }
63
56 input.src = source.buf; 64 input.src = source.buf;
57 input.size = source.len; 65 input.size = source.len;
58 input.pos = 0; 66 input.pos = 0;
59 67
60 output.dst = PyMem_Malloc(self->outSize); 68 output.dst = PyMem_Malloc(self->outSize);
63 goto except; 71 goto except;
64 } 72 }
65 output.size = self->outSize; 73 output.size = self->outSize;
66 output.pos = 0; 74 output.pos = 0;
67 75
68 /* Read input until exhausted. */ 76 while (1) {
69 while (input.pos < input.size) {
70 Py_BEGIN_ALLOW_THREADS 77 Py_BEGIN_ALLOW_THREADS
71 zresult = ZSTD_decompress_generic(self->decompressor->dctx, &output, &input); 78 zresult = ZSTD_decompress_generic(self->decompressor->dctx, &output, &input);
72 Py_END_ALLOW_THREADS 79 Py_END_ALLOW_THREADS
73 80
74 if (ZSTD_isError(zresult)) { 81 if (ZSTD_isError(zresult)) {
96 result = PyBytes_FromStringAndSize(output.dst, output.pos); 103 result = PyBytes_FromStringAndSize(output.dst, output.pos);
97 if (!result) { 104 if (!result) {
98 goto except; 105 goto except;
99 } 106 }
100 } 107 }
108 }
101 109
102 output.pos = 0; 110 if (zresult == 0 || (input.pos == input.size && output.pos == 0)) {
111 break;
103 } 112 }
113
114 output.pos = 0;
104 } 115 }
105 116
106 if (!result) { 117 if (!result) {
107 result = PyBytes_FromString(""); 118 result = PyBytes_FromString("");
108 } 119 }