[issue5804] Add an 'offset' argument to zlib.decompress - Code Review (original) (raw)

OLD

NEW

1 /* zlibmodule.c -- gzip-compatible data compression */

1 /* zlibmodule.c -- gzip-compatible data compression */

2 /* See http://www.gzip.org/zlib/ */

2 /* See http://www.gzip.org/zlib/ */

3

3

4 /* Windows users: read Python's PCbuild\readme.txt */

4 /* Windows users: read Python's PCbuild\readme.txt */

5

5

6

6

7 #include "Python.h"

7 #include "Python.h"

8 #include "zlib.h"

8 #include "zlib.h"

9

9

10 #ifdef WITH_THREAD

10 #ifdef WITH_THREAD

(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...

179 else

179 else

180 zlib_error(zst, err, "while finishing compression");

180 zlib_error(zst, err, "while finishing compression");

181

181

182 error:

182 error:

183 free(output);

183 free(output);

184

184

185 return ReturnVal;

185 return ReturnVal;

186 }

186 }

187

187

188 PyDoc_STRVAR(decompress__doc__,

188 PyDoc_STRVAR(decompress__doc__,

189 "decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n"

189 "decompress(string[, wbits[, bufsize[, offset]]]) -- Return decompressed string. \n"

190 "\n"

190 "\n"

191 "Optional arg wbits is the window buffer size. Optional arg bufsize is\n"

191 "Optional arg wbits is the window buffer size. Optional arg bufsize is\n"

192 "the initial output buffer size.");

192 "the initial output buffer size. Optional arg offset specifies\n"

193 "the start position in the string to start decompresion and, if spceified,\n"

194 "causes the return value to be a tuple, with the second element being\n"

195 "the position in the string just afer the last piece of compressed data.");

193

196

194 static PyObject *

197 static PyObject *

195 PyZlib_decompress(PyObject *self, PyObject *args)

198 PyZlib_decompress(PyObject *self, PyObject *args, PyObject *kw)

196 {

199 {

197 PyObject *result_str;

200 PyObject *result_str;

198 Byte *input;

201 Byte *input;

199 int length, err;

202 int length, err;

200 int wsize=DEF_WBITS;

203 int wsize=DEF_WBITS;

201 Py_ssize_t r_strlen=DEFAULTALLOC;

204 Py_ssize_t r_strlen=DEFAULTALLOC;

205 Py_ssize_t offset = -1;

202 z_stream zst;

206 z_stream zst;

207 char *keywords[] = {"string", "wbits", "bufsize", "offset", 0};

203

208

204 if (!PyArg_ParseTuple(args, "s#|in:decompress",

209 if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|inn:decompress", keywords,

205 » » » &input, &length, &wsize, &r_strlen))

210 » » » &input, &length, &wsize, &r_strlen, &offset))

206 return NULL;

211 return NULL;

207

208 if (r_strlen <= 0)

212 if (r_strlen <= 0)

209 r_strlen = 1;

213 r_strlen = 1;

210

214

215 /* if specified, don't start at the beginning of the input string */

216 if (offset > 0) {

217 if (offset > length)

218 offset = length;

219 length -= offset;

220 input += offset;

221 }

222

211 zst.avail_in = length;

223 zst.avail_in = length;

212 zst.avail_out = r_strlen;

224 zst.avail_out = r_strlen;

213

225

214 if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen)))

226 if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen)))

215 return NULL;

227 return NULL;

216

228

217 zst.zalloc = (alloc_func)NULL;

229 zst.zalloc = (alloc_func)NULL;

218 zst.zfree = (free_func)Z_NULL;

230 zst.zfree = (free_func)Z_NULL;

219 zst.next_out = (Byte *)PyString_AS_STRING(result_str);

231 zst.next_out = (Byte *)PyString_AS_STRING(result_str);

220 zst.next_in = (Byte *)input;

232 zst.next_in = (Byte *)input;

(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...

272 }

284 }

273 } while (err != Z_STREAM_END);

285 } while (err != Z_STREAM_END);

274

286

275 err = inflateEnd(&zst);

287 err = inflateEnd(&zst);

276 if (err != Z_OK) {

288 if (err != Z_OK) {

277 zlib_error(zst, err, "while finishing data decompression");

289 zlib_error(zst, err, "while finishing data decompression");

278 goto error;

290 goto error;

279 }

291 }

280

292

281 _PyString_Resize(&result_str, zst.total_out);

293 _PyString_Resize(&result_str, zst.total_out);

294 if (result_str != NULL && offset >= 0) {

295 /* compute new offset to current pos */

296 offset = length-zst.avail_in+offset;

297 return Py_BuildValue("Nn", result_str, offset);

298 }

282 return result_str;

299 return result_str;

283

300

284 error:

301 error:

285 Py_XDECREF(result_str);

302 Py_XDECREF(result_str);

286 return NULL;

303 return NULL;

287 }

304 }

288

305

289 static PyObject *

306 static PyObject *

290 PyZlib_compressobj(PyObject *selfptr, PyObject *args)

307 PyZlib_compressobj(PyObject *selfptr, PyObject *args)

291 {

308 {

(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...

934 static PyMethodDef zlib_methods[] =

951 static PyMethodDef zlib_methods[] =

935 {

952 {

936 {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,

953 {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,

937 adler32__doc__},

954 adler32__doc__},

938 {"compress", (PyCFunction)PyZlib_compress, METH_VARARGS,

955 {"compress", (PyCFunction)PyZlib_compress, METH_VARARGS,

939 compress__doc__},

956 compress__doc__},

940 {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS,

957 {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS,

941 compressobj__doc__},

958 compressobj__doc__},

942 {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,

959 {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,

943 crc32__doc__},

960 crc32__doc__},

944 {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS,

961 {"decompress", (PyCFunction)PyZlib_decompress, METH_KEYWORDS,

945 decompress__doc__},

962 decompress__doc__},

946 {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS,

963 {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS,

947 decompressobj__doc__},

964 decompressobj__doc__},

948 {NULL, NULL}

965 {NULL, NULL}

949 };

966 };

950

967

951 static PyTypeObject Comptype = {

968 static PyTypeObject Comptype = {

952 PyVarObject_HEAD_INIT(0, 0)

969 PyVarObject_HEAD_INIT(0, 0)

953 "zlib.Compress",

970 "zlib.Compress",

954 sizeof(compobject),

971 sizeof(compobject),

(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...

1030 ver = PyString_FromString(ZLIB_VERSION);

1047 ver = PyString_FromString(ZLIB_VERSION);

1031 if (ver != NULL)

1048 if (ver != NULL)

1032 PyModule_AddObject(m, "ZLIB_VERSION", ver);

1049 PyModule_AddObject(m, "ZLIB_VERSION", ver);

1033

1050

1034 PyModule_AddStringConstant(m, "__version__", "1.0");

1051 PyModule_AddStringConstant(m, "__version__", "1.0");

1035

1052

1036 #ifdef WITH_THREAD

1053 #ifdef WITH_THREAD

1037 zlib_lock = PyThread_allocate_lock();

1054 zlib_lock = PyThread_allocate_lock();

1038 #endif /* WITH_THREAD */

1055 #endif /* WITH_THREAD */

1039 }

1056 }

OLD

NEW