+++ /dev/null
-/* zlibmodule.c -- gzip-compatible data compression */\r
-/* See http://www.gzip.org/zlib/ */\r
-\r
-/* Windows users: read Python's PCbuild\readme.txt */\r
-\r
-\r
-#include "Python.h"\r
-#include "zlib.h"\r
-\r
-#ifdef WITH_THREAD\r
-#include "pythread.h"\r
-\r
-/* #defs ripped off from _tkinter.c, even though the situation here is much\r
- simpler, because we don't have to worry about waiting for Tcl\r
- events! And, since zlib itself is threadsafe, we don't need to worry\r
- about re-entering zlib functions.\r
-\r
- N.B.\r
-\r
- Since ENTER_ZLIB and LEAVE_ZLIB only need to be called on functions\r
- that modify the components of preexisting de/compress objects, it\r
- could prove to be a performance gain on multiprocessor machines if\r
- there was an de/compress object-specific lock. However, for the\r
- moment the ENTER_ZLIB and LEAVE_ZLIB calls are global for ALL\r
- de/compress objects.\r
- */\r
-\r
-static PyThread_type_lock zlib_lock = NULL; /* initialized on module load */\r
-\r
-#define ENTER_ZLIB \\r
- Py_BEGIN_ALLOW_THREADS \\r
- PyThread_acquire_lock(zlib_lock, 1); \\r
- Py_END_ALLOW_THREADS\r
-\r
-#define LEAVE_ZLIB \\r
- PyThread_release_lock(zlib_lock);\r
-\r
-#else\r
-\r
-#define ENTER_ZLIB\r
-#define LEAVE_ZLIB\r
-\r
-#endif\r
-\r
-/* The following parameters are copied from zutil.h, version 0.95 */\r
-#define DEFLATED 8\r
-#if MAX_MEM_LEVEL >= 8\r
-# define DEF_MEM_LEVEL 8\r
-#else\r
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL\r
-#endif\r
-#define DEF_WBITS MAX_WBITS\r
-\r
-/* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */\r
-#define DEFAULTALLOC (16*1024)\r
-#define PyInit_zlib initzlib\r
-\r
-static PyTypeObject Comptype;\r
-static PyTypeObject Decomptype;\r
-\r
-static PyObject *ZlibError;\r
-\r
-typedef struct\r
-{\r
- PyObject_HEAD\r
- z_stream zst;\r
- PyObject *unused_data;\r
- PyObject *unconsumed_tail;\r
- int is_initialised;\r
-} compobject;\r
-\r
-static void\r
-zlib_error(z_stream zst, int err, char *msg)\r
-{\r
- const char *zmsg = Z_NULL;\r
- /* In case of a version mismatch, zst.msg won't be initialized.\r
- Check for this case first, before looking at zst.msg. */\r
- if (err == Z_VERSION_ERROR)\r
- zmsg = "library version mismatch";\r
- if (zmsg == Z_NULL)\r
- zmsg = zst.msg;\r
- if (zmsg == Z_NULL) {\r
- switch (err) {\r
- case Z_BUF_ERROR:\r
- zmsg = "incomplete or truncated stream";\r
- break;\r
- case Z_STREAM_ERROR:\r
- zmsg = "inconsistent stream state";\r
- break;\r
- case Z_DATA_ERROR:\r
- zmsg = "invalid input data";\r
- break;\r
- }\r
- }\r
- if (zmsg == Z_NULL)\r
- PyErr_Format(ZlibError, "Error %d %s", err, msg);\r
- else\r
- PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zmsg);\r
-}\r
-\r
-PyDoc_STRVAR(compressobj__doc__,\r
-"compressobj([level]) -- Return a compressor object.\n"\r
-"\n"\r
-"Optional arg level is the compression level, in 0-9.");\r
-\r
-PyDoc_STRVAR(decompressobj__doc__,\r
-"decompressobj([wbits]) -- Return a decompressor object.\n"\r
-"\n"\r
-"Optional arg wbits is the window buffer size.");\r
-\r
-static compobject *\r
-newcompobject(PyTypeObject *type)\r
-{\r
- compobject *self;\r
- self = PyObject_New(compobject, type);\r
- if (self == NULL)\r
- return NULL;\r
- self->is_initialised = 0;\r
- self->unused_data = PyString_FromString("");\r
- if (self->unused_data == NULL) {\r
- Py_DECREF(self);\r
- return NULL;\r
- }\r
- self->unconsumed_tail = PyString_FromString("");\r
- if (self->unconsumed_tail == NULL) {\r
- Py_DECREF(self);\r
- return NULL;\r
- }\r
- return self;\r
-}\r
-\r
-PyDoc_STRVAR(compress__doc__,\r
-"compress(string[, level]) -- Returned compressed string.\n"\r
-"\n"\r
-"Optional arg level is the compression level, in 0-9.");\r
-\r
-static PyObject *\r
-PyZlib_compress(PyObject *self, PyObject *args)\r
-{\r
- PyObject *ReturnVal = NULL;\r
- Byte *input, *output;\r
- int length, level=Z_DEFAULT_COMPRESSION, err;\r
- z_stream zst;\r
-\r
- /* require Python string object, optional 'level' arg */\r
- if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level))\r
- return NULL;\r
-\r
- zst.avail_out = length + length/1000 + 12 + 1;\r
-\r
- output = (Byte*)malloc(zst.avail_out);\r
- if (output == NULL) {\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Can't allocate memory to compress data");\r
- return NULL;\r
- }\r
-\r
- /* Past the point of no return. From here on out, we need to make sure\r
- we clean up mallocs & INCREFs. */\r
-\r
- zst.zalloc = (alloc_func)NULL;\r
- zst.zfree = (free_func)Z_NULL;\r
- zst.next_out = (Byte *)output;\r
- zst.next_in = (Byte *)input;\r
- zst.avail_in = length;\r
- err = deflateInit(&zst, level);\r
-\r
- switch(err) {\r
- case(Z_OK):\r
- break;\r
- case(Z_MEM_ERROR):\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Out of memory while compressing data");\r
- goto error;\r
- case(Z_STREAM_ERROR):\r
- PyErr_SetString(ZlibError,\r
- "Bad compression level");\r
- goto error;\r
- default:\r
- deflateEnd(&zst);\r
- zlib_error(zst, err, "while compressing data");\r
- goto error;\r
- }\r
-\r
- Py_BEGIN_ALLOW_THREADS;\r
- err = deflate(&zst, Z_FINISH);\r
- Py_END_ALLOW_THREADS;\r
-\r
- if (err != Z_STREAM_END) {\r
- zlib_error(zst, err, "while compressing data");\r
- deflateEnd(&zst);\r
- goto error;\r
- }\r
-\r
- err=deflateEnd(&zst);\r
- if (err == Z_OK)\r
- ReturnVal = PyString_FromStringAndSize((char *)output,\r
- zst.total_out);\r
- else\r
- zlib_error(zst, err, "while finishing compression");\r
-\r
- error:\r
- free(output);\r
-\r
- return ReturnVal;\r
-}\r
-\r
-PyDoc_STRVAR(decompress__doc__,\r
-"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n"\r
-"\n"\r
-"Optional arg wbits is the window buffer size. Optional arg bufsize is\n"\r
-"the initial output buffer size.");\r
-\r
-static PyObject *\r
-PyZlib_decompress(PyObject *self, PyObject *args)\r
-{\r
- PyObject *result_str;\r
- Byte *input;\r
- int length, err;\r
- int wsize=DEF_WBITS;\r
- Py_ssize_t r_strlen=DEFAULTALLOC;\r
- z_stream zst;\r
-\r
- if (!PyArg_ParseTuple(args, "s#|in:decompress",\r
- &input, &length, &wsize, &r_strlen))\r
- return NULL;\r
-\r
- if (r_strlen <= 0)\r
- r_strlen = 1;\r
-\r
- zst.avail_in = length;\r
- zst.avail_out = r_strlen;\r
-\r
- if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen)))\r
- return NULL;\r
-\r
- zst.zalloc = (alloc_func)NULL;\r
- zst.zfree = (free_func)Z_NULL;\r
- zst.next_out = (Byte *)PyString_AS_STRING(result_str);\r
- zst.next_in = (Byte *)input;\r
- err = inflateInit2(&zst, wsize);\r
-\r
- switch(err) {\r
- case(Z_OK):\r
- break;\r
- case(Z_MEM_ERROR):\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Out of memory while decompressing data");\r
- goto error;\r
- default:\r
- inflateEnd(&zst);\r
- zlib_error(zst, err, "while preparing to decompress data");\r
- goto error;\r
- }\r
-\r
- do {\r
- Py_BEGIN_ALLOW_THREADS\r
- err=inflate(&zst, Z_FINISH);\r
- Py_END_ALLOW_THREADS\r
-\r
- switch(err) {\r
- case(Z_STREAM_END):\r
- break;\r
- case(Z_BUF_ERROR):\r
- /*\r
- * If there is at least 1 byte of room according to zst.avail_out\r
- * and we get this error, assume that it means zlib cannot\r
- * process the inflate call() due to an error in the data.\r
- */\r
- if (zst.avail_out > 0) {\r
- zlib_error(zst, err, "while decompressing data");\r
- inflateEnd(&zst);\r
- goto error;\r
- }\r
- /* fall through */\r
- case(Z_OK):\r
- /* need more memory */\r
- if (_PyString_Resize(&result_str, r_strlen << 1) < 0) {\r
- inflateEnd(&zst);\r
- goto error;\r
- }\r
- zst.next_out = (unsigned char *)PyString_AS_STRING(result_str) \\r
- + r_strlen;\r
- zst.avail_out = r_strlen;\r
- r_strlen = r_strlen << 1;\r
- break;\r
- default:\r
- inflateEnd(&zst);\r
- zlib_error(zst, err, "while decompressing data");\r
- goto error;\r
- }\r
- } while (err != Z_STREAM_END);\r
-\r
- err = inflateEnd(&zst);\r
- if (err != Z_OK) {\r
- zlib_error(zst, err, "while finishing data decompression");\r
- goto error;\r
- }\r
-\r
- _PyString_Resize(&result_str, zst.total_out);\r
- return result_str;\r
-\r
- error:\r
- Py_XDECREF(result_str);\r
- return NULL;\r
-}\r
-\r
-static PyObject *\r
-PyZlib_compressobj(PyObject *selfptr, PyObject *args)\r
-{\r
- compobject *self;\r
- int level=Z_DEFAULT_COMPRESSION, method=DEFLATED;\r
- int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err;\r
-\r
- if (!PyArg_ParseTuple(args, "|iiiii:compressobj", &level, &method, &wbits,\r
- &memLevel, &strategy))\r
- return NULL;\r
-\r
- self = newcompobject(&Comptype);\r
- if (self==NULL)\r
- return(NULL);\r
- self->zst.zalloc = (alloc_func)NULL;\r
- self->zst.zfree = (free_func)Z_NULL;\r
- self->zst.next_in = NULL;\r
- self->zst.avail_in = 0;\r
- err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy);\r
- switch(err) {\r
- case (Z_OK):\r
- self->is_initialised = 1;\r
- return (PyObject*)self;\r
- case (Z_MEM_ERROR):\r
- Py_DECREF(self);\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Can't allocate memory for compression object");\r
- return NULL;\r
- case(Z_STREAM_ERROR):\r
- Py_DECREF(self);\r
- PyErr_SetString(PyExc_ValueError, "Invalid initialization option");\r
- return NULL;\r
- default:\r
- zlib_error(self->zst, err, "while creating compression object");\r
- Py_DECREF(self);\r
- return NULL;\r
- }\r
-}\r
-\r
-static PyObject *\r
-PyZlib_decompressobj(PyObject *selfptr, PyObject *args)\r
-{\r
- int wbits=DEF_WBITS, err;\r
- compobject *self;\r
- if (!PyArg_ParseTuple(args, "|i:decompressobj", &wbits))\r
- return NULL;\r
-\r
- self = newcompobject(&Decomptype);\r
- if (self == NULL)\r
- return(NULL);\r
- self->zst.zalloc = (alloc_func)NULL;\r
- self->zst.zfree = (free_func)Z_NULL;\r
- self->zst.next_in = NULL;\r
- self->zst.avail_in = 0;\r
- err = inflateInit2(&self->zst, wbits);\r
- switch(err) {\r
- case (Z_OK):\r
- self->is_initialised = 1;\r
- return (PyObject*)self;\r
- case(Z_STREAM_ERROR):\r
- Py_DECREF(self);\r
- PyErr_SetString(PyExc_ValueError, "Invalid initialization option");\r
- return NULL;\r
- case (Z_MEM_ERROR):\r
- Py_DECREF(self);\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Can't allocate memory for decompression object");\r
- return NULL;\r
- default:\r
- zlib_error(self->zst, err, "while creating decompression object");\r
- Py_DECREF(self);\r
- return NULL;\r
- }\r
-}\r
-\r
-static void\r
-Comp_dealloc(compobject *self)\r
-{\r
- if (self->is_initialised)\r
- deflateEnd(&self->zst);\r
- Py_XDECREF(self->unused_data);\r
- Py_XDECREF(self->unconsumed_tail);\r
- PyObject_Del(self);\r
-}\r
-\r
-static void\r
-Decomp_dealloc(compobject *self)\r
-{\r
- if (self->is_initialised)\r
- inflateEnd(&self->zst);\r
- Py_XDECREF(self->unused_data);\r
- Py_XDECREF(self->unconsumed_tail);\r
- PyObject_Del(self);\r
-}\r
-\r
-PyDoc_STRVAR(comp_compress__doc__,\r
-"compress(data) -- Return a string containing data compressed.\n"\r
-"\n"\r
-"After calling this function, some of the input data may still\n"\r
-"be stored in internal buffers for later processing.\n"\r
-"Call the flush() method to clear these buffers.");\r
-\r
-\r
-static PyObject *\r
-PyZlib_objcompress(compobject *self, PyObject *args)\r
-{\r
- int err, inplen;\r
- Py_ssize_t length = DEFAULTALLOC;\r
- PyObject *RetVal;\r
- Byte *input;\r
- unsigned long start_total_out;\r
-\r
- if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen))\r
- return NULL;\r
-\r
- if (!(RetVal = PyString_FromStringAndSize(NULL, length)))\r
- return NULL;\r
-\r
- ENTER_ZLIB\r
-\r
- start_total_out = self->zst.total_out;\r
- self->zst.avail_in = inplen;\r
- self->zst.next_in = input;\r
- self->zst.avail_out = length;\r
- self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = deflate(&(self->zst), Z_NO_FLUSH);\r
- Py_END_ALLOW_THREADS\r
-\r
- /* while Z_OK and the output buffer is full, there might be more output,\r
- so extend the output buffer and try again */\r
- while (err == Z_OK && self->zst.avail_out == 0) {\r
- if (_PyString_Resize(&RetVal, length << 1) < 0)\r
- goto error;\r
- self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \\r
- + length;\r
- self->zst.avail_out = length;\r
- length = length << 1;\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = deflate(&(self->zst), Z_NO_FLUSH);\r
- Py_END_ALLOW_THREADS\r
- }\r
- /* We will only get Z_BUF_ERROR if the output buffer was full but\r
- there wasn't more output when we tried again, so it is not an error\r
- condition.\r
- */\r
-\r
- if (err != Z_OK && err != Z_BUF_ERROR) {\r
- zlib_error(self->zst, err, "while compressing");\r
- Py_DECREF(RetVal);\r
- RetVal = NULL;\r
- goto error;\r
- }\r
- _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);\r
-\r
- error:\r
- LEAVE_ZLIB\r
- return RetVal;\r
-}\r
-\r
-/* Helper for objdecompress() and unflush(). Saves any unconsumed input data in\r
- self->unused_data or self->unconsumed_tail, as appropriate. */\r
-static int\r
-save_unconsumed_input(compobject *self, int err)\r
-{\r
- if (err == Z_STREAM_END) {\r
- /* The end of the compressed data has been reached. Store the leftover\r
- input data in self->unused_data. */\r
- if (self->zst.avail_in > 0) {\r
- Py_ssize_t old_size = PyString_GET_SIZE(self->unused_data);\r
- Py_ssize_t new_size;\r
- PyObject *new_data;\r
- if (self->zst.avail_in > PY_SSIZE_T_MAX - old_size) {\r
- PyErr_NoMemory();\r
- return -1;\r
- }\r
- new_size = old_size + self->zst.avail_in;\r
- new_data = PyString_FromStringAndSize(NULL, new_size);\r
- if (new_data == NULL)\r
- return -1;\r
- Py_MEMCPY(PyString_AS_STRING(new_data),\r
- PyString_AS_STRING(self->unused_data), old_size);\r
- Py_MEMCPY(PyString_AS_STRING(new_data) + old_size,\r
- self->zst.next_in, self->zst.avail_in);\r
- Py_DECREF(self->unused_data);\r
- self->unused_data = new_data;\r
- self->zst.avail_in = 0;\r
- }\r
- }\r
- if (self->zst.avail_in > 0 || PyString_GET_SIZE(self->unconsumed_tail)) {\r
- /* This code handles two distinct cases:\r
- 1. Output limit was reached. Save leftover input in unconsumed_tail.\r
- 2. All input data was consumed. Clear unconsumed_tail. */\r
- PyObject *new_data = PyString_FromStringAndSize(\r
- (char *)self->zst.next_in, self->zst.avail_in);\r
- if (new_data == NULL)\r
- return -1;\r
- Py_DECREF(self->unconsumed_tail);\r
- self->unconsumed_tail = new_data;\r
- }\r
- return 0;\r
-}\r
-\r
-PyDoc_STRVAR(decomp_decompress__doc__,\r
-"decompress(data, max_length) -- Return a string containing the decompressed\n"\r
-"version of the data.\n"\r
-"\n"\r
-"After calling this function, some of the input data may still be stored in\n"\r
-"internal buffers for later processing.\n"\r
-"Call the flush() method to clear these buffers.\n"\r
-"If the max_length parameter is specified then the return value will be\n"\r
-"no longer than max_length. Unconsumed input data will be stored in\n"\r
-"the unconsumed_tail attribute.");\r
-\r
-static PyObject *\r
-PyZlib_objdecompress(compobject *self, PyObject *args)\r
-{\r
- int err, inplen, max_length = 0;\r
- Py_ssize_t old_length, length = DEFAULTALLOC;\r
- PyObject *RetVal;\r
- Byte *input;\r
- unsigned long start_total_out;\r
-\r
- if (!PyArg_ParseTuple(args, "s#|i:decompress", &input,\r
- &inplen, &max_length))\r
- return NULL;\r
- if (max_length < 0) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "max_length must be greater than zero");\r
- return NULL;\r
- }\r
-\r
- /* limit amount of data allocated to max_length */\r
- if (max_length && length > max_length)\r
- length = max_length;\r
- if (!(RetVal = PyString_FromStringAndSize(NULL, length)))\r
- return NULL;\r
-\r
- ENTER_ZLIB\r
-\r
- start_total_out = self->zst.total_out;\r
- self->zst.avail_in = inplen;\r
- self->zst.next_in = input;\r
- self->zst.avail_out = length;\r
- self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = inflate(&(self->zst), Z_SYNC_FLUSH);\r
- Py_END_ALLOW_THREADS\r
-\r
- /* While Z_OK and the output buffer is full, there might be more output.\r
- So extend the output buffer and try again.\r
- */\r
- while (err == Z_OK && self->zst.avail_out == 0) {\r
- /* If max_length set, don't continue decompressing if we've already\r
- reached the limit.\r
- */\r
- if (max_length && length >= max_length)\r
- break;\r
-\r
- /* otherwise, ... */\r
- old_length = length;\r
- length = length << 1;\r
- if (max_length && length > max_length)\r
- length = max_length;\r
-\r
- if (_PyString_Resize(&RetVal, length) < 0)\r
- goto error;\r
- self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \\r
- + old_length;\r
- self->zst.avail_out = length - old_length;\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = inflate(&(self->zst), Z_SYNC_FLUSH);\r
- Py_END_ALLOW_THREADS\r
- }\r
-\r
- if (save_unconsumed_input(self, err) < 0) {\r
- Py_DECREF(RetVal);\r
- RetVal = NULL;\r
- goto error;\r
- }\r
-\r
- /* This is the logical place to call inflateEnd, but the old behaviour of\r
- only calling it on flush() is preserved. */\r
-\r
- if (err != Z_STREAM_END && err != Z_OK && err != Z_BUF_ERROR) {\r
- /* We will only get Z_BUF_ERROR if the output buffer was full\r
- but there wasn't more output when we tried again, so it is\r
- not an error condition.\r
- */\r
- zlib_error(self->zst, err, "while decompressing");\r
- Py_DECREF(RetVal);\r
- RetVal = NULL;\r
- goto error;\r
- }\r
-\r
- _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);\r
-\r
- error:\r
- LEAVE_ZLIB\r
-\r
- return RetVal;\r
-}\r
-\r
-PyDoc_STRVAR(comp_flush__doc__,\r
-"flush( [mode] ) -- Return a string containing any remaining compressed data.\n"\r
-"\n"\r
-"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n"\r
-"default value used when mode is not specified is Z_FINISH.\n"\r
-"If mode == Z_FINISH, the compressor object can no longer be used after\n"\r
-"calling the flush() method. Otherwise, more data can still be compressed.");\r
-\r
-static PyObject *\r
-PyZlib_flush(compobject *self, PyObject *args)\r
-{\r
- int err, length = DEFAULTALLOC;\r
- PyObject *RetVal;\r
- int flushmode = Z_FINISH;\r
- unsigned long start_total_out;\r
-\r
- if (!PyArg_ParseTuple(args, "|i:flush", &flushmode))\r
- return NULL;\r
-\r
- /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in\r
- doing any work at all; just return an empty string. */\r
- if (flushmode == Z_NO_FLUSH) {\r
- return PyString_FromStringAndSize(NULL, 0);\r
- }\r
-\r
- if (!(RetVal = PyString_FromStringAndSize(NULL, length)))\r
- return NULL;\r
-\r
- ENTER_ZLIB\r
-\r
- start_total_out = self->zst.total_out;\r
- self->zst.avail_in = 0;\r
- self->zst.avail_out = length;\r
- self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal);\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = deflate(&(self->zst), flushmode);\r
- Py_END_ALLOW_THREADS\r
-\r
- /* while Z_OK and the output buffer is full, there might be more output,\r
- so extend the output buffer and try again */\r
- while (err == Z_OK && self->zst.avail_out == 0) {\r
- if (_PyString_Resize(&RetVal, length << 1) < 0)\r
- goto error;\r
- self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \\r
- + length;\r
- self->zst.avail_out = length;\r
- length = length << 1;\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = deflate(&(self->zst), flushmode);\r
- Py_END_ALLOW_THREADS\r
- }\r
-\r
- /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free\r
- various data structures. Note we should only get Z_STREAM_END when\r
- flushmode is Z_FINISH, but checking both for safety*/\r
- if (err == Z_STREAM_END && flushmode == Z_FINISH) {\r
- err = deflateEnd(&(self->zst));\r
- if (err != Z_OK) {\r
- zlib_error(self->zst, err, "from deflateEnd()");\r
- Py_DECREF(RetVal);\r
- RetVal = NULL;\r
- goto error;\r
- }\r
- else\r
- self->is_initialised = 0;\r
-\r
- /* We will only get Z_BUF_ERROR if the output buffer was full\r
- but there wasn't more output when we tried again, so it is\r
- not an error condition.\r
- */\r
- } else if (err!=Z_OK && err!=Z_BUF_ERROR) {\r
- zlib_error(self->zst, err, "while flushing");\r
- Py_DECREF(RetVal);\r
- RetVal = NULL;\r
- goto error;\r
- }\r
-\r
- _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);\r
-\r
- error:\r
- LEAVE_ZLIB\r
-\r
- return RetVal;\r
-}\r
-\r
-#ifdef HAVE_ZLIB_COPY\r
-PyDoc_STRVAR(comp_copy__doc__,\r
-"copy() -- Return a copy of the compression object.");\r
-\r
-static PyObject *\r
-PyZlib_copy(compobject *self)\r
-{\r
- compobject *retval = NULL;\r
- int err;\r
-\r
- retval = newcompobject(&Comptype);\r
- if (!retval) return NULL;\r
-\r
- /* Copy the zstream state\r
- * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe\r
- */\r
- ENTER_ZLIB\r
- err = deflateCopy(&retval->zst, &self->zst);\r
- switch(err) {\r
- case(Z_OK):\r
- break;\r
- case(Z_STREAM_ERROR):\r
- PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");\r
- goto error;\r
- case(Z_MEM_ERROR):\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Can't allocate memory for compression object");\r
- goto error;\r
- default:\r
- zlib_error(self->zst, err, "while copying compression object");\r
- goto error;\r
- }\r
-\r
- Py_INCREF(self->unused_data);\r
- Py_INCREF(self->unconsumed_tail);\r
- Py_XDECREF(retval->unused_data);\r
- Py_XDECREF(retval->unconsumed_tail);\r
- retval->unused_data = self->unused_data;\r
- retval->unconsumed_tail = self->unconsumed_tail;\r
-\r
- /* Mark it as being initialized */\r
- retval->is_initialised = 1;\r
-\r
- LEAVE_ZLIB\r
- return (PyObject *)retval;\r
-\r
-error:\r
- LEAVE_ZLIB\r
- Py_XDECREF(retval);\r
- return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(decomp_copy__doc__,\r
-"copy() -- Return a copy of the decompression object.");\r
-\r
-static PyObject *\r
-PyZlib_uncopy(compobject *self)\r
-{\r
- compobject *retval = NULL;\r
- int err;\r
-\r
- retval = newcompobject(&Decomptype);\r
- if (!retval) return NULL;\r
-\r
- /* Copy the zstream state\r
- * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe\r
- */\r
- ENTER_ZLIB\r
- err = inflateCopy(&retval->zst, &self->zst);\r
- switch(err) {\r
- case(Z_OK):\r
- break;\r
- case(Z_STREAM_ERROR):\r
- PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");\r
- goto error;\r
- case(Z_MEM_ERROR):\r
- PyErr_SetString(PyExc_MemoryError,\r
- "Can't allocate memory for decompression object");\r
- goto error;\r
- default:\r
- zlib_error(self->zst, err, "while copying decompression object");\r
- goto error;\r
- }\r
-\r
- Py_INCREF(self->unused_data);\r
- Py_INCREF(self->unconsumed_tail);\r
- Py_XDECREF(retval->unused_data);\r
- Py_XDECREF(retval->unconsumed_tail);\r
- retval->unused_data = self->unused_data;\r
- retval->unconsumed_tail = self->unconsumed_tail;\r
-\r
- /* Mark it as being initialized */\r
- retval->is_initialised = 1;\r
-\r
- LEAVE_ZLIB\r
- return (PyObject *)retval;\r
-\r
-error:\r
- LEAVE_ZLIB\r
- Py_XDECREF(retval);\r
- return NULL;\r
-}\r
-#endif\r
-\r
-PyDoc_STRVAR(decomp_flush__doc__,\r
-"flush( [length] ) -- Return a string containing any remaining\n"\r
-"decompressed data. length, if given, is the initial size of the\n"\r
-"output buffer.\n"\r
-"\n"\r
-"The decompressor object can no longer be used after this call.");\r
-\r
-static PyObject *\r
-PyZlib_unflush(compobject *self, PyObject *args)\r
-{\r
- int err, length = DEFAULTALLOC;\r
- PyObject * retval = NULL;\r
- unsigned long start_total_out;\r
-\r
- if (!PyArg_ParseTuple(args, "|i:flush", &length))\r
- return NULL;\r
- if (length <= 0) {\r
- PyErr_SetString(PyExc_ValueError, "length must be greater than zero");\r
- return NULL;\r
- }\r
- if (!(retval = PyString_FromStringAndSize(NULL, length)))\r
- return NULL;\r
-\r
-\r
- ENTER_ZLIB\r
-\r
- start_total_out = self->zst.total_out;\r
- self->zst.avail_in = PyString_GET_SIZE(self->unconsumed_tail);\r
- self->zst.next_in = (Byte *)PyString_AS_STRING(self->unconsumed_tail);\r
- self->zst.avail_out = length;\r
- self->zst.next_out = (Byte *)PyString_AS_STRING(retval);\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = inflate(&(self->zst), Z_FINISH);\r
- Py_END_ALLOW_THREADS\r
-\r
- /* while Z_OK and the output buffer is full, there might be more output,\r
- so extend the output buffer and try again */\r
- while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) {\r
- if (_PyString_Resize(&retval, length << 1) < 0)\r
- goto error;\r
- self->zst.next_out = (Byte *)PyString_AS_STRING(retval) + length;\r
- self->zst.avail_out = length;\r
- length = length << 1;\r
-\r
- Py_BEGIN_ALLOW_THREADS\r
- err = inflate(&(self->zst), Z_FINISH);\r
- Py_END_ALLOW_THREADS\r
- }\r
-\r
- if (save_unconsumed_input(self, err) < 0) {\r
- Py_DECREF(retval);\r
- retval = NULL;\r
- goto error;\r
- }\r
-\r
- /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free\r
- various data structures. Note we should only get Z_STREAM_END when\r
- flushmode is Z_FINISH */\r
- if (err == Z_STREAM_END) {\r
- err = inflateEnd(&(self->zst));\r
- self->is_initialised = 0;\r
- if (err != Z_OK) {\r
- zlib_error(self->zst, err, "from inflateEnd()");\r
- Py_DECREF(retval);\r
- retval = NULL;\r
- goto error;\r
- }\r
- }\r
-\r
- _PyString_Resize(&retval, self->zst.total_out - start_total_out);\r
-\r
-error:\r
-\r
- LEAVE_ZLIB\r
-\r
- return retval;\r
-}\r
-\r
-static PyMethodDef comp_methods[] =\r
-{\r
- {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS,\r
- comp_compress__doc__},\r
- {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS,\r
- comp_flush__doc__},\r
-#ifdef HAVE_ZLIB_COPY\r
- {"copy", (PyCFunction)PyZlib_copy, METH_NOARGS,\r
- comp_copy__doc__},\r
-#endif\r
- {NULL, NULL}\r
-};\r
-\r
-static PyMethodDef Decomp_methods[] =\r
-{\r
- {"decompress", (binaryfunc)PyZlib_objdecompress, METH_VARARGS,\r
- decomp_decompress__doc__},\r
- {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS,\r
- decomp_flush__doc__},\r
-#ifdef HAVE_ZLIB_COPY\r
- {"copy", (PyCFunction)PyZlib_uncopy, METH_NOARGS,\r
- decomp_copy__doc__},\r
-#endif\r
- {NULL, NULL}\r
-};\r
-\r
-static PyObject *\r
-Comp_getattr(compobject *self, char *name)\r
-{\r
- /* No ENTER/LEAVE_ZLIB is necessary because this fn doesn't touch\r
- internal data. */\r
-\r
- return Py_FindMethod(comp_methods, (PyObject *)self, name);\r
-}\r
-\r
-static PyObject *\r
-Decomp_getattr(compobject *self, char *name)\r
-{\r
- PyObject * retval;\r
-\r
- ENTER_ZLIB\r
-\r
- if (strcmp(name, "unused_data") == 0) {\r
- Py_INCREF(self->unused_data);\r
- retval = self->unused_data;\r
- } else if (strcmp(name, "unconsumed_tail") == 0) {\r
- Py_INCREF(self->unconsumed_tail);\r
- retval = self->unconsumed_tail;\r
- } else\r
- retval = Py_FindMethod(Decomp_methods, (PyObject *)self, name);\r
-\r
- LEAVE_ZLIB\r
-\r
- return retval;\r
-}\r
-\r
-PyDoc_STRVAR(adler32__doc__,\r
-"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n"\r
-"\n"\r
-"An optional starting value can be specified. The returned checksum is\n"\r
-"a signed integer.");\r
-\r
-static PyObject *\r
-PyZlib_adler32(PyObject *self, PyObject *args)\r
-{\r
- unsigned int adler32val = 1; /* adler32(0L, Z_NULL, 0) */\r
- Byte *buf;\r
- int len, signed_val;\r
-\r
- if (!PyArg_ParseTuple(args, "s#|I:adler32", &buf, &len, &adler32val))\r
- return NULL;\r
- /* In Python 2.x we return a signed integer regardless of native platform\r
- * long size (the 32bit unsigned long is treated as 32-bit signed and sign\r
- * extended into a 64-bit long inside the integer object). 3.0 does the\r
- * right thing and returns unsigned. http://bugs.python.org/issue1202 */\r
- signed_val = adler32(adler32val, buf, len);\r
- return PyInt_FromLong(signed_val);\r
-}\r
-\r
-PyDoc_STRVAR(crc32__doc__,\r
-"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n"\r
-"\n"\r
-"An optional starting value can be specified. The returned checksum is\n"\r
-"a signed integer.");\r
-\r
-static PyObject *\r
-PyZlib_crc32(PyObject *self, PyObject *args)\r
-{\r
- unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */\r
- Byte *buf;\r
- int len, signed_val;\r
-\r
- if (!PyArg_ParseTuple(args, "s#|I:crc32", &buf, &len, &crc32val))\r
- return NULL;\r
- /* In Python 2.x we return a signed integer regardless of native platform\r
- * long size (the 32bit unsigned long is treated as 32-bit signed and sign\r
- * extended into a 64-bit long inside the integer object). 3.0 does the\r
- * right thing and returns unsigned. http://bugs.python.org/issue1202 */\r
- signed_val = crc32(crc32val, buf, len);\r
- return PyInt_FromLong(signed_val);\r
-}\r
-\r
-\r
-static PyMethodDef zlib_methods[] =\r
-{\r
- {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS,\r
- adler32__doc__},\r
- {"compress", (PyCFunction)PyZlib_compress, METH_VARARGS,\r
- compress__doc__},\r
- {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS,\r
- compressobj__doc__},\r
- {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS,\r
- crc32__doc__},\r
- {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS,\r
- decompress__doc__},\r
- {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS,\r
- decompressobj__doc__},\r
- {NULL, NULL}\r
-};\r
-\r
-static PyTypeObject Comptype = {\r
- PyVarObject_HEAD_INIT(0, 0)\r
- "zlib.Compress",\r
- sizeof(compobject),\r
- 0,\r
- (destructor)Comp_dealloc, /*tp_dealloc*/\r
- 0, /*tp_print*/\r
- (getattrfunc)Comp_getattr, /*tp_getattr*/\r
- 0, /*tp_setattr*/\r
- 0, /*tp_compare*/\r
- 0, /*tp_repr*/\r
- 0, /*tp_as_number*/\r
- 0, /*tp_as_sequence*/\r
- 0, /*tp_as_mapping*/\r
-};\r
-\r
-static PyTypeObject Decomptype = {\r
- PyVarObject_HEAD_INIT(0, 0)\r
- "zlib.Decompress",\r
- sizeof(compobject),\r
- 0,\r
- (destructor)Decomp_dealloc, /*tp_dealloc*/\r
- 0, /*tp_print*/\r
- (getattrfunc)Decomp_getattr, /*tp_getattr*/\r
- 0, /*tp_setattr*/\r
- 0, /*tp_compare*/\r
- 0, /*tp_repr*/\r
- 0, /*tp_as_number*/\r
- 0, /*tp_as_sequence*/\r
- 0, /*tp_as_mapping*/\r
-};\r
-\r
-PyDoc_STRVAR(zlib_module_documentation,\r
-"The functions in this module allow compression and decompression using the\n"\r
-"zlib library, which is based on GNU zip.\n"\r
-"\n"\r
-"adler32(string[, start]) -- Compute an Adler-32 checksum.\n"\r
-"compress(string[, level]) -- Compress string, with compression level in 0-9.\n"\r
-"compressobj([level]) -- Return a compressor object.\n"\r
-"crc32(string[, start]) -- Compute a CRC-32 checksum.\n"\r
-"decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n"\r
-"decompressobj([wbits]) -- Return a decompressor object.\n"\r
-"\n"\r
-"'wbits' is window buffer size.\n"\r
-"Compressor objects support compress() and flush() methods; decompressor\n"\r
-"objects support decompress() and flush().");\r
-\r
-PyMODINIT_FUNC\r
-PyInit_zlib(void)\r
-{\r
- PyObject *m, *ver;\r
- Py_TYPE(&Comptype) = &PyType_Type;\r
- Py_TYPE(&Decomptype) = &PyType_Type;\r
- m = Py_InitModule4("zlib", zlib_methods,\r
- zlib_module_documentation,\r
- (PyObject*)NULL,PYTHON_API_VERSION);\r
- if (m == NULL)\r
- return;\r
-\r
- ZlibError = PyErr_NewException("zlib.error", NULL, NULL);\r
- if (ZlibError != NULL) {\r
- Py_INCREF(ZlibError);\r
- PyModule_AddObject(m, "error", ZlibError);\r
- }\r
- PyModule_AddIntConstant(m, "MAX_WBITS", MAX_WBITS);\r
- PyModule_AddIntConstant(m, "DEFLATED", DEFLATED);\r
- PyModule_AddIntConstant(m, "DEF_MEM_LEVEL", DEF_MEM_LEVEL);\r
- PyModule_AddIntConstant(m, "Z_BEST_SPEED", Z_BEST_SPEED);\r
- PyModule_AddIntConstant(m, "Z_BEST_COMPRESSION", Z_BEST_COMPRESSION);\r
- PyModule_AddIntConstant(m, "Z_DEFAULT_COMPRESSION", Z_DEFAULT_COMPRESSION);\r
- PyModule_AddIntConstant(m, "Z_FILTERED", Z_FILTERED);\r
- PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY);\r
- PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY);\r
-\r
- PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH);\r
- PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH);\r
- PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH);\r
- PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH);\r
-\r
- ver = PyString_FromString(ZLIB_VERSION);\r
- if (ver != NULL)\r
- PyModule_AddObject(m, "ZLIB_VERSION", ver);\r
-\r
- PyModule_AddStringConstant(m, "__version__", "1.0");\r
-\r
-#ifdef WITH_THREAD\r
- zlib_lock = PyThread_allocate_lock();\r
-#endif /* WITH_THREAD */\r
-}\r