equal
deleted
inserted
replaced
24 PyBuffer_Release(self->buffer); |
24 PyBuffer_Release(self->buffer); |
25 PyMem_FREE(self->buffer); |
25 PyMem_FREE(self->buffer); |
26 self->buffer = NULL; |
26 self->buffer = NULL; |
27 } |
27 } |
28 |
28 |
29 if (self->dstream) { |
|
30 ZSTD_freeDStream(self->dstream); |
|
31 self->dstream = NULL; |
|
32 } |
|
33 |
|
34 if (self->input.src) { |
29 if (self->input.src) { |
35 PyMem_Free((void*)self->input.src); |
30 PyMem_Free((void*)self->input.src); |
36 self->input.src = NULL; |
31 self->input.src = NULL; |
37 } |
32 } |
38 |
33 |
48 size_t zresult; |
43 size_t zresult; |
49 PyObject* chunk; |
44 PyObject* chunk; |
50 DecompressorIteratorResult result; |
45 DecompressorIteratorResult result; |
51 size_t oldInputPos = self->input.pos; |
46 size_t oldInputPos = self->input.pos; |
52 |
47 |
|
48 assert(self->decompressor->dstream); |
|
49 |
53 result.chunk = NULL; |
50 result.chunk = NULL; |
54 |
51 |
55 chunk = PyBytes_FromStringAndSize(NULL, self->outSize); |
52 chunk = PyBytes_FromStringAndSize(NULL, self->outSize); |
56 if (!chunk) { |
53 if (!chunk) { |
57 result.errored = 1; |
54 result.errored = 1; |
61 self->output.dst = PyBytes_AsString(chunk); |
58 self->output.dst = PyBytes_AsString(chunk); |
62 self->output.size = self->outSize; |
59 self->output.size = self->outSize; |
63 self->output.pos = 0; |
60 self->output.pos = 0; |
64 |
61 |
65 Py_BEGIN_ALLOW_THREADS |
62 Py_BEGIN_ALLOW_THREADS |
66 zresult = ZSTD_decompressStream(self->dstream, &self->output, &self->input); |
63 zresult = ZSTD_decompressStream(self->decompressor->dstream, &self->output, &self->input); |
67 Py_END_ALLOW_THREADS |
64 Py_END_ALLOW_THREADS |
68 |
65 |
69 /* We're done with the pointer. Nullify to prevent anyone from getting a |
66 /* We're done with the pointer. Nullify to prevent anyone from getting a |
70 handle on a Python object. */ |
67 handle on a Python object. */ |
71 self->output.dst = NULL; |
68 self->output.dst = NULL; |
158 assert(self->skipBytes < self->inSize); |
155 assert(self->skipBytes < self->inSize); |
159 if ((Py_ssize_t)self->skipBytes >= readSize) { |
156 if ((Py_ssize_t)self->skipBytes >= readSize) { |
160 PyErr_SetString(PyExc_ValueError, |
157 PyErr_SetString(PyExc_ValueError, |
161 "skip_bytes larger than first input chunk; " |
158 "skip_bytes larger than first input chunk; " |
162 "this scenario is currently unsupported"); |
159 "this scenario is currently unsupported"); |
163 Py_DecRef(readResult); |
160 Py_XDECREF(readResult); |
164 return NULL; |
161 return NULL; |
165 } |
162 } |
166 |
163 |
167 readBuffer = readBuffer + self->skipBytes; |
164 readBuffer = readBuffer + self->skipBytes; |
168 readSize -= self->skipBytes; |
165 readSize -= self->skipBytes; |
177 } |
174 } |
178 /* No bytes on first read must mean an empty input stream. */ |
175 /* No bytes on first read must mean an empty input stream. */ |
179 else if (!self->readCount) { |
176 else if (!self->readCount) { |
180 self->finishedInput = 1; |
177 self->finishedInput = 1; |
181 self->finishedOutput = 1; |
178 self->finishedOutput = 1; |
182 Py_DecRef(readResult); |
179 Py_XDECREF(readResult); |
183 PyErr_SetString(PyExc_StopIteration, "empty input"); |
180 PyErr_SetString(PyExc_StopIteration, "empty input"); |
184 return NULL; |
181 return NULL; |
185 } |
182 } |
186 else { |
183 else { |
187 self->finishedInput = 1; |
184 self->finishedInput = 1; |
188 } |
185 } |
189 |
186 |
190 /* We've copied the data managed by memory. Discard the Python object. */ |
187 /* We've copied the data managed by memory. Discard the Python object. */ |
191 Py_DecRef(readResult); |
188 Py_XDECREF(readResult); |
192 } |
189 } |
193 |
190 |
194 result = read_decompressor_iterator(self); |
191 result = read_decompressor_iterator(self); |
195 if (result.errored || result.chunk) { |
192 if (result.errored || result.chunk) { |
196 return result.chunk; |
193 return result.chunk; |