17db96d56Sopenharmony_ci/* zlibmodule.c -- gzip-compatible data compression */ 27db96d56Sopenharmony_ci/* See http://zlib.net/ */ 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci/* Windows users: read Python's PCbuild\readme.txt */ 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci#include "Python.h" 97db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 107db96d56Sopenharmony_ci#include "zlib.h" 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci// Blocks output buffer wrappers 137db96d56Sopenharmony_ci#include "pycore_blocks_output_buffer.h" 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci#if OUTPUT_BUFFER_MAX_BLOCK_SIZE > UINT32_MAX 167db96d56Sopenharmony_ci #error "The maximum block size accepted by zlib is UINT32_MAX." 177db96d56Sopenharmony_ci#endif 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci/* On success, return value >= 0 207db96d56Sopenharmony_ci On failure, return -1 */ 217db96d56Sopenharmony_cistatic inline Py_ssize_t 227db96d56Sopenharmony_ciOutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, Py_ssize_t max_length, 237db96d56Sopenharmony_ci Bytef **next_out, uint32_t *avail_out) 247db96d56Sopenharmony_ci{ 257db96d56Sopenharmony_ci Py_ssize_t allocated; 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci allocated = _BlocksOutputBuffer_InitAndGrow( 287db96d56Sopenharmony_ci buffer, max_length, (void**) next_out); 297db96d56Sopenharmony_ci *avail_out = (uint32_t) allocated; 307db96d56Sopenharmony_ci return allocated; 317db96d56Sopenharmony_ci} 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci/* On success, return value >= 0 347db96d56Sopenharmony_ci On failure, return -1 */ 357db96d56Sopenharmony_cistatic inline Py_ssize_t 367db96d56Sopenharmony_ciOutputBuffer_Grow(_BlocksOutputBuffer *buffer, 377db96d56Sopenharmony_ci Bytef **next_out, uint32_t *avail_out) 387db96d56Sopenharmony_ci{ 397db96d56Sopenharmony_ci Py_ssize_t allocated; 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci allocated = _BlocksOutputBuffer_Grow( 427db96d56Sopenharmony_ci buffer, (void**) next_out, (Py_ssize_t) *avail_out); 437db96d56Sopenharmony_ci *avail_out = (uint32_t) allocated; 447db96d56Sopenharmony_ci return allocated; 457db96d56Sopenharmony_ci} 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_cistatic inline Py_ssize_t 487db96d56Sopenharmony_ciOutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, uint32_t avail_out) 497db96d56Sopenharmony_ci{ 507db96d56Sopenharmony_ci return _BlocksOutputBuffer_GetDataSize(buffer, (Py_ssize_t) avail_out); 517db96d56Sopenharmony_ci} 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_cistatic inline PyObject * 547db96d56Sopenharmony_ciOutputBuffer_Finish(_BlocksOutputBuffer *buffer, uint32_t avail_out) 557db96d56Sopenharmony_ci{ 567db96d56Sopenharmony_ci return _BlocksOutputBuffer_Finish(buffer, (Py_ssize_t) avail_out); 577db96d56Sopenharmony_ci} 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_cistatic inline void 607db96d56Sopenharmony_ciOutputBuffer_OnError(_BlocksOutputBuffer *buffer) 617db96d56Sopenharmony_ci{ 627db96d56Sopenharmony_ci _BlocksOutputBuffer_OnError(buffer); 637db96d56Sopenharmony_ci} 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci/* The max buffer size accepted by zlib is UINT32_MAX, the initial buffer size 667db96d56Sopenharmony_ci `init_size` may > it in 64-bit build. These wrapper functions maintain an 677db96d56Sopenharmony_ci UINT32_MAX sliding window for the first block: 687db96d56Sopenharmony_ci 1. OutputBuffer_WindowInitWithSize() 697db96d56Sopenharmony_ci 2. OutputBuffer_WindowGrow() 707db96d56Sopenharmony_ci 3. OutputBuffer_WindowFinish() 717db96d56Sopenharmony_ci 4. OutputBuffer_WindowOnError() 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci ==== is the sliding window: 747db96d56Sopenharmony_ci 1. ====------ 757db96d56Sopenharmony_ci ^ next_posi, left_bytes is 6 767db96d56Sopenharmony_ci 2. ----====-- 777db96d56Sopenharmony_ci ^ next_posi, left_bytes is 2 787db96d56Sopenharmony_ci 3. --------== 797db96d56Sopenharmony_ci ^ next_posi, left_bytes is 0 */ 807db96d56Sopenharmony_citypedef struct { 817db96d56Sopenharmony_ci Py_ssize_t left_bytes; 827db96d56Sopenharmony_ci Bytef *next_posi; 837db96d56Sopenharmony_ci} _Uint32Window; 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci/* Initialize the buffer with an initial buffer size. 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci On success, return value >= 0 887db96d56Sopenharmony_ci On failure, return value < 0 */ 897db96d56Sopenharmony_cistatic inline Py_ssize_t 907db96d56Sopenharmony_ciOutputBuffer_WindowInitWithSize(_BlocksOutputBuffer *buffer, _Uint32Window *window, 917db96d56Sopenharmony_ci Py_ssize_t init_size, 927db96d56Sopenharmony_ci Bytef **next_out, uint32_t *avail_out) 937db96d56Sopenharmony_ci{ 947db96d56Sopenharmony_ci Py_ssize_t allocated = _BlocksOutputBuffer_InitWithSize( 957db96d56Sopenharmony_ci buffer, init_size, (void**) next_out); 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci if (allocated >= 0) { 987db96d56Sopenharmony_ci // the UINT32_MAX sliding window 997db96d56Sopenharmony_ci Py_ssize_t window_size = Py_MIN((size_t)allocated, UINT32_MAX); 1007db96d56Sopenharmony_ci *avail_out = (uint32_t) window_size; 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci window->left_bytes = allocated - window_size; 1037db96d56Sopenharmony_ci window->next_posi = *next_out + window_size; 1047db96d56Sopenharmony_ci } 1057db96d56Sopenharmony_ci return allocated; 1067db96d56Sopenharmony_ci} 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci/* Grow the buffer. 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci On success, return value >= 0 1117db96d56Sopenharmony_ci On failure, return value < 0 */ 1127db96d56Sopenharmony_cistatic inline Py_ssize_t 1137db96d56Sopenharmony_ciOutputBuffer_WindowGrow(_BlocksOutputBuffer *buffer, _Uint32Window *window, 1147db96d56Sopenharmony_ci Bytef **next_out, uint32_t *avail_out) 1157db96d56Sopenharmony_ci{ 1167db96d56Sopenharmony_ci Py_ssize_t allocated; 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci /* ensure no gaps in the data. 1197db96d56Sopenharmony_ci if inlined, this check could be optimized away.*/ 1207db96d56Sopenharmony_ci if (*avail_out != 0) { 1217db96d56Sopenharmony_ci PyErr_SetString(PyExc_SystemError, 1227db96d56Sopenharmony_ci "*avail_out != 0 in OutputBuffer_WindowGrow()."); 1237db96d56Sopenharmony_ci return -1; 1247db96d56Sopenharmony_ci } 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci // slide the UINT32_MAX sliding window 1277db96d56Sopenharmony_ci if (window->left_bytes > 0) { 1287db96d56Sopenharmony_ci Py_ssize_t window_size = Py_MIN((size_t)window->left_bytes, UINT32_MAX); 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci *next_out = window->next_posi; 1317db96d56Sopenharmony_ci *avail_out = (uint32_t) window_size; 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci window->left_bytes -= window_size; 1347db96d56Sopenharmony_ci window->next_posi += window_size; 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci return window_size; 1377db96d56Sopenharmony_ci } 1387db96d56Sopenharmony_ci assert(window->left_bytes == 0); 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci // only the first block may > UINT32_MAX 1417db96d56Sopenharmony_ci allocated = _BlocksOutputBuffer_Grow( 1427db96d56Sopenharmony_ci buffer, (void**) next_out, (Py_ssize_t) *avail_out); 1437db96d56Sopenharmony_ci *avail_out = (uint32_t) allocated; 1447db96d56Sopenharmony_ci return allocated; 1457db96d56Sopenharmony_ci} 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci/* Finish the buffer. 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci On success, return a bytes object 1507db96d56Sopenharmony_ci On failure, return NULL */ 1517db96d56Sopenharmony_cistatic inline PyObject * 1527db96d56Sopenharmony_ciOutputBuffer_WindowFinish(_BlocksOutputBuffer *buffer, _Uint32Window *window, 1537db96d56Sopenharmony_ci uint32_t avail_out) 1547db96d56Sopenharmony_ci{ 1557db96d56Sopenharmony_ci Py_ssize_t real_avail_out = (Py_ssize_t) avail_out + window->left_bytes; 1567db96d56Sopenharmony_ci return _BlocksOutputBuffer_Finish(buffer, real_avail_out); 1577db96d56Sopenharmony_ci} 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_cistatic inline void 1607db96d56Sopenharmony_ciOutputBuffer_WindowOnError(_BlocksOutputBuffer *buffer, _Uint32Window *window) 1617db96d56Sopenharmony_ci{ 1627db96d56Sopenharmony_ci _BlocksOutputBuffer_OnError(buffer); 1637db96d56Sopenharmony_ci} 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_ci#define ENTER_ZLIB(obj) do { \ 1677db96d56Sopenharmony_ci if (!PyThread_acquire_lock((obj)->lock, 0)) { \ 1687db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS \ 1697db96d56Sopenharmony_ci PyThread_acquire_lock((obj)->lock, 1); \ 1707db96d56Sopenharmony_ci Py_END_ALLOW_THREADS \ 1717db96d56Sopenharmony_ci } } while (0) 1727db96d56Sopenharmony_ci#define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock); 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221 1757db96d56Sopenharmony_ci# define AT_LEAST_ZLIB_1_2_2_1 1767db96d56Sopenharmony_ci#endif 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci/* The following parameters are copied from zutil.h, version 0.95 */ 1797db96d56Sopenharmony_ci#define DEFLATED 8 1807db96d56Sopenharmony_ci#if MAX_MEM_LEVEL >= 8 1817db96d56Sopenharmony_ci# define DEF_MEM_LEVEL 8 1827db96d56Sopenharmony_ci#else 1837db96d56Sopenharmony_ci# define DEF_MEM_LEVEL MAX_MEM_LEVEL 1847db96d56Sopenharmony_ci#endif 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci/* Initial buffer size. */ 1877db96d56Sopenharmony_ci#define DEF_BUF_SIZE (16*1024) 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_cistatic PyModuleDef zlibmodule; 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_citypedef struct { 1927db96d56Sopenharmony_ci PyTypeObject *Comptype; 1937db96d56Sopenharmony_ci PyTypeObject *Decomptype; 1947db96d56Sopenharmony_ci PyObject *ZlibError; 1957db96d56Sopenharmony_ci} zlibstate; 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_cistatic inline zlibstate* 1987db96d56Sopenharmony_ciget_zlib_state(PyObject *module) 1997db96d56Sopenharmony_ci{ 2007db96d56Sopenharmony_ci void *state = PyModule_GetState(module); 2017db96d56Sopenharmony_ci assert(state != NULL); 2027db96d56Sopenharmony_ci return (zlibstate *)state; 2037db96d56Sopenharmony_ci} 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_citypedef struct 2067db96d56Sopenharmony_ci{ 2077db96d56Sopenharmony_ci PyObject_HEAD 2087db96d56Sopenharmony_ci z_stream zst; 2097db96d56Sopenharmony_ci PyObject *unused_data; 2107db96d56Sopenharmony_ci PyObject *unconsumed_tail; 2117db96d56Sopenharmony_ci char eof; 2127db96d56Sopenharmony_ci int is_initialised; 2137db96d56Sopenharmony_ci PyObject *zdict; 2147db96d56Sopenharmony_ci PyThread_type_lock lock; 2157db96d56Sopenharmony_ci} compobject; 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_cistatic void 2187db96d56Sopenharmony_cizlib_error(zlibstate *state, z_stream zst, int err, const char *msg) 2197db96d56Sopenharmony_ci{ 2207db96d56Sopenharmony_ci const char *zmsg = Z_NULL; 2217db96d56Sopenharmony_ci /* In case of a version mismatch, zst.msg won't be initialized. 2227db96d56Sopenharmony_ci Check for this case first, before looking at zst.msg. */ 2237db96d56Sopenharmony_ci if (err == Z_VERSION_ERROR) 2247db96d56Sopenharmony_ci zmsg = "library version mismatch"; 2257db96d56Sopenharmony_ci if (zmsg == Z_NULL) 2267db96d56Sopenharmony_ci zmsg = zst.msg; 2277db96d56Sopenharmony_ci if (zmsg == Z_NULL) { 2287db96d56Sopenharmony_ci switch (err) { 2297db96d56Sopenharmony_ci case Z_BUF_ERROR: 2307db96d56Sopenharmony_ci zmsg = "incomplete or truncated stream"; 2317db96d56Sopenharmony_ci break; 2327db96d56Sopenharmony_ci case Z_STREAM_ERROR: 2337db96d56Sopenharmony_ci zmsg = "inconsistent stream state"; 2347db96d56Sopenharmony_ci break; 2357db96d56Sopenharmony_ci case Z_DATA_ERROR: 2367db96d56Sopenharmony_ci zmsg = "invalid input data"; 2377db96d56Sopenharmony_ci break; 2387db96d56Sopenharmony_ci } 2397db96d56Sopenharmony_ci } 2407db96d56Sopenharmony_ci if (zmsg == Z_NULL) 2417db96d56Sopenharmony_ci PyErr_Format(state->ZlibError, "Error %d %s", err, msg); 2427db96d56Sopenharmony_ci else 2437db96d56Sopenharmony_ci PyErr_Format(state->ZlibError, "Error %d %s: %.200s", err, msg, zmsg); 2447db96d56Sopenharmony_ci} 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci/*[clinic input] 2477db96d56Sopenharmony_cimodule zlib 2487db96d56Sopenharmony_ciclass zlib.Compress "compobject *" "&Comptype" 2497db96d56Sopenharmony_ciclass zlib.Decompress "compobject *" "&Decomptype" 2507db96d56Sopenharmony_ci[clinic start generated code]*/ 2517db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=093935115c3e3158]*/ 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_cistatic compobject * 2547db96d56Sopenharmony_cinewcompobject(PyTypeObject *type) 2557db96d56Sopenharmony_ci{ 2567db96d56Sopenharmony_ci compobject *self; 2577db96d56Sopenharmony_ci self = PyObject_New(compobject, type); 2587db96d56Sopenharmony_ci if (self == NULL) 2597db96d56Sopenharmony_ci return NULL; 2607db96d56Sopenharmony_ci self->eof = 0; 2617db96d56Sopenharmony_ci self->is_initialised = 0; 2627db96d56Sopenharmony_ci self->zdict = NULL; 2637db96d56Sopenharmony_ci self->unused_data = PyBytes_FromStringAndSize("", 0); 2647db96d56Sopenharmony_ci if (self->unused_data == NULL) { 2657db96d56Sopenharmony_ci Py_DECREF(self); 2667db96d56Sopenharmony_ci return NULL; 2677db96d56Sopenharmony_ci } 2687db96d56Sopenharmony_ci self->unconsumed_tail = PyBytes_FromStringAndSize("", 0); 2697db96d56Sopenharmony_ci if (self->unconsumed_tail == NULL) { 2707db96d56Sopenharmony_ci Py_DECREF(self); 2717db96d56Sopenharmony_ci return NULL; 2727db96d56Sopenharmony_ci } 2737db96d56Sopenharmony_ci self->lock = PyThread_allocate_lock(); 2747db96d56Sopenharmony_ci if (self->lock == NULL) { 2757db96d56Sopenharmony_ci Py_DECREF(self); 2767db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); 2777db96d56Sopenharmony_ci return NULL; 2787db96d56Sopenharmony_ci } 2797db96d56Sopenharmony_ci return self; 2807db96d56Sopenharmony_ci} 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_cistatic void* 2837db96d56Sopenharmony_ciPyZlib_Malloc(voidpf ctx, uInt items, uInt size) 2847db96d56Sopenharmony_ci{ 2857db96d56Sopenharmony_ci if (size != 0 && items > (size_t)PY_SSIZE_T_MAX / size) 2867db96d56Sopenharmony_ci return NULL; 2877db96d56Sopenharmony_ci /* PyMem_Malloc() cannot be used: the GIL is not held when 2887db96d56Sopenharmony_ci inflate() and deflate() are called */ 2897db96d56Sopenharmony_ci return PyMem_RawMalloc((size_t)items * (size_t)size); 2907db96d56Sopenharmony_ci} 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_cistatic void 2937db96d56Sopenharmony_ciPyZlib_Free(voidpf ctx, void *ptr) 2947db96d56Sopenharmony_ci{ 2957db96d56Sopenharmony_ci PyMem_RawFree(ptr); 2967db96d56Sopenharmony_ci} 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_cistatic void 2997db96d56Sopenharmony_ciarrange_input_buffer(z_stream *zst, Py_ssize_t *remains) 3007db96d56Sopenharmony_ci{ 3017db96d56Sopenharmony_ci zst->avail_in = (uInt)Py_MIN((size_t)*remains, UINT_MAX); 3027db96d56Sopenharmony_ci *remains -= zst->avail_in; 3037db96d56Sopenharmony_ci} 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci/*[clinic input] 3067db96d56Sopenharmony_cizlib.compress 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci data: Py_buffer 3097db96d56Sopenharmony_ci Binary data to be compressed. 3107db96d56Sopenharmony_ci / 3117db96d56Sopenharmony_ci level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION 3127db96d56Sopenharmony_ci Compression level, in 0-9 or -1. 3137db96d56Sopenharmony_ci wbits: int(c_default="MAX_WBITS") = MAX_WBITS 3147db96d56Sopenharmony_ci The window buffer size and container format. 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ciReturns a bytes object containing compressed data. 3177db96d56Sopenharmony_ci[clinic start generated code]*/ 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_cistatic PyObject * 3207db96d56Sopenharmony_cizlib_compress_impl(PyObject *module, Py_buffer *data, int level, int wbits) 3217db96d56Sopenharmony_ci/*[clinic end generated code: output=46bd152fadd66df2 input=c4d06ee5782a7e3f]*/ 3227db96d56Sopenharmony_ci{ 3237db96d56Sopenharmony_ci PyObject *RetVal; 3247db96d56Sopenharmony_ci int flush; 3257db96d56Sopenharmony_ci z_stream zst; 3267db96d56Sopenharmony_ci _BlocksOutputBuffer buffer = {.list = NULL}; 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(module); 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci Byte *ibuf = data->buf; 3317db96d56Sopenharmony_ci Py_ssize_t ibuflen = data->len; 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci if (OutputBuffer_InitAndGrow(&buffer, -1, &zst.next_out, &zst.avail_out) < 0) { 3347db96d56Sopenharmony_ci goto error; 3357db96d56Sopenharmony_ci } 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci zst.opaque = NULL; 3387db96d56Sopenharmony_ci zst.zalloc = PyZlib_Malloc; 3397db96d56Sopenharmony_ci zst.zfree = PyZlib_Free; 3407db96d56Sopenharmony_ci zst.next_in = ibuf; 3417db96d56Sopenharmony_ci int err = deflateInit2(&zst, level, DEFLATED, wbits, DEF_MEM_LEVEL, 3427db96d56Sopenharmony_ci Z_DEFAULT_STRATEGY); 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci switch (err) { 3457db96d56Sopenharmony_ci case Z_OK: 3467db96d56Sopenharmony_ci break; 3477db96d56Sopenharmony_ci case Z_MEM_ERROR: 3487db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 3497db96d56Sopenharmony_ci "Out of memory while compressing data"); 3507db96d56Sopenharmony_ci goto error; 3517db96d56Sopenharmony_ci case Z_STREAM_ERROR: 3527db96d56Sopenharmony_ci PyErr_SetString(state->ZlibError, "Bad compression level"); 3537db96d56Sopenharmony_ci goto error; 3547db96d56Sopenharmony_ci default: 3557db96d56Sopenharmony_ci deflateEnd(&zst); 3567db96d56Sopenharmony_ci zlib_error(state, zst, err, "while compressing data"); 3577db96d56Sopenharmony_ci goto error; 3587db96d56Sopenharmony_ci } 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci do { 3617db96d56Sopenharmony_ci arrange_input_buffer(&zst, &ibuflen); 3627db96d56Sopenharmony_ci flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci do { 3657db96d56Sopenharmony_ci if (zst.avail_out == 0) { 3667db96d56Sopenharmony_ci if (OutputBuffer_Grow(&buffer, &zst.next_out, &zst.avail_out) < 0) { 3677db96d56Sopenharmony_ci deflateEnd(&zst); 3687db96d56Sopenharmony_ci goto error; 3697db96d56Sopenharmony_ci } 3707db96d56Sopenharmony_ci } 3717db96d56Sopenharmony_ci 3727db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 3737db96d56Sopenharmony_ci err = deflate(&zst, flush); 3747db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_ci if (err == Z_STREAM_ERROR) { 3777db96d56Sopenharmony_ci deflateEnd(&zst); 3787db96d56Sopenharmony_ci zlib_error(state, zst, err, "while compressing data"); 3797db96d56Sopenharmony_ci goto error; 3807db96d56Sopenharmony_ci } 3817db96d56Sopenharmony_ci 3827db96d56Sopenharmony_ci } while (zst.avail_out == 0); 3837db96d56Sopenharmony_ci assert(zst.avail_in == 0); 3847db96d56Sopenharmony_ci 3857db96d56Sopenharmony_ci } while (flush != Z_FINISH); 3867db96d56Sopenharmony_ci assert(err == Z_STREAM_END); 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci err = deflateEnd(&zst); 3897db96d56Sopenharmony_ci if (err == Z_OK) { 3907db96d56Sopenharmony_ci RetVal = OutputBuffer_Finish(&buffer, zst.avail_out); 3917db96d56Sopenharmony_ci if (RetVal == NULL) { 3927db96d56Sopenharmony_ci goto error; 3937db96d56Sopenharmony_ci } 3947db96d56Sopenharmony_ci return RetVal; 3957db96d56Sopenharmony_ci } 3967db96d56Sopenharmony_ci else 3977db96d56Sopenharmony_ci zlib_error(state, zst, err, "while finishing compression"); 3987db96d56Sopenharmony_ci error: 3997db96d56Sopenharmony_ci OutputBuffer_OnError(&buffer); 4007db96d56Sopenharmony_ci return NULL; 4017db96d56Sopenharmony_ci} 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_ci/*[clinic input] 4047db96d56Sopenharmony_cizlib.decompress 4057db96d56Sopenharmony_ci 4067db96d56Sopenharmony_ci data: Py_buffer 4077db96d56Sopenharmony_ci Compressed data. 4087db96d56Sopenharmony_ci / 4097db96d56Sopenharmony_ci wbits: int(c_default="MAX_WBITS") = MAX_WBITS 4107db96d56Sopenharmony_ci The window buffer size and container format. 4117db96d56Sopenharmony_ci bufsize: Py_ssize_t(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE 4127db96d56Sopenharmony_ci The initial output buffer size. 4137db96d56Sopenharmony_ci 4147db96d56Sopenharmony_ciReturns a bytes object containing the uncompressed data. 4157db96d56Sopenharmony_ci[clinic start generated code]*/ 4167db96d56Sopenharmony_ci 4177db96d56Sopenharmony_cistatic PyObject * 4187db96d56Sopenharmony_cizlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, 4197db96d56Sopenharmony_ci Py_ssize_t bufsize) 4207db96d56Sopenharmony_ci/*[clinic end generated code: output=77c7e35111dc8c42 input=a9ac17beff1f893f]*/ 4217db96d56Sopenharmony_ci{ 4227db96d56Sopenharmony_ci PyObject *RetVal; 4237db96d56Sopenharmony_ci Byte *ibuf; 4247db96d56Sopenharmony_ci Py_ssize_t ibuflen; 4257db96d56Sopenharmony_ci int err, flush; 4267db96d56Sopenharmony_ci z_stream zst; 4277db96d56Sopenharmony_ci _BlocksOutputBuffer buffer = {.list = NULL}; 4287db96d56Sopenharmony_ci _Uint32Window window; // output buffer's UINT32_MAX sliding window 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(module); 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_ci if (bufsize < 0) { 4337db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "bufsize must be non-negative"); 4347db96d56Sopenharmony_ci return NULL; 4357db96d56Sopenharmony_ci } else if (bufsize == 0) { 4367db96d56Sopenharmony_ci bufsize = 1; 4377db96d56Sopenharmony_ci } 4387db96d56Sopenharmony_ci 4397db96d56Sopenharmony_ci if (OutputBuffer_WindowInitWithSize(&buffer, &window, bufsize, 4407db96d56Sopenharmony_ci &zst.next_out, &zst.avail_out) < 0) { 4417db96d56Sopenharmony_ci goto error; 4427db96d56Sopenharmony_ci } 4437db96d56Sopenharmony_ci 4447db96d56Sopenharmony_ci ibuf = data->buf; 4457db96d56Sopenharmony_ci ibuflen = data->len; 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci zst.opaque = NULL; 4487db96d56Sopenharmony_ci zst.zalloc = PyZlib_Malloc; 4497db96d56Sopenharmony_ci zst.zfree = PyZlib_Free; 4507db96d56Sopenharmony_ci zst.avail_in = 0; 4517db96d56Sopenharmony_ci zst.next_in = ibuf; 4527db96d56Sopenharmony_ci err = inflateInit2(&zst, wbits); 4537db96d56Sopenharmony_ci 4547db96d56Sopenharmony_ci switch (err) { 4557db96d56Sopenharmony_ci case Z_OK: 4567db96d56Sopenharmony_ci break; 4577db96d56Sopenharmony_ci case Z_MEM_ERROR: 4587db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 4597db96d56Sopenharmony_ci "Out of memory while decompressing data"); 4607db96d56Sopenharmony_ci goto error; 4617db96d56Sopenharmony_ci default: 4627db96d56Sopenharmony_ci inflateEnd(&zst); 4637db96d56Sopenharmony_ci zlib_error(state, zst, err, "while preparing to decompress data"); 4647db96d56Sopenharmony_ci goto error; 4657db96d56Sopenharmony_ci } 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_ci do { 4687db96d56Sopenharmony_ci arrange_input_buffer(&zst, &ibuflen); 4697db96d56Sopenharmony_ci flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci do { 4727db96d56Sopenharmony_ci if (zst.avail_out == 0) { 4737db96d56Sopenharmony_ci if (OutputBuffer_WindowGrow(&buffer, &window, 4747db96d56Sopenharmony_ci &zst.next_out, &zst.avail_out) < 0) { 4757db96d56Sopenharmony_ci inflateEnd(&zst); 4767db96d56Sopenharmony_ci goto error; 4777db96d56Sopenharmony_ci } 4787db96d56Sopenharmony_ci } 4797db96d56Sopenharmony_ci 4807db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 4817db96d56Sopenharmony_ci err = inflate(&zst, flush); 4827db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 4837db96d56Sopenharmony_ci 4847db96d56Sopenharmony_ci switch (err) { 4857db96d56Sopenharmony_ci case Z_OK: /* fall through */ 4867db96d56Sopenharmony_ci case Z_BUF_ERROR: /* fall through */ 4877db96d56Sopenharmony_ci case Z_STREAM_END: 4887db96d56Sopenharmony_ci break; 4897db96d56Sopenharmony_ci case Z_MEM_ERROR: 4907db96d56Sopenharmony_ci inflateEnd(&zst); 4917db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 4927db96d56Sopenharmony_ci "Out of memory while decompressing data"); 4937db96d56Sopenharmony_ci goto error; 4947db96d56Sopenharmony_ci default: 4957db96d56Sopenharmony_ci inflateEnd(&zst); 4967db96d56Sopenharmony_ci zlib_error(state, zst, err, "while decompressing data"); 4977db96d56Sopenharmony_ci goto error; 4987db96d56Sopenharmony_ci } 4997db96d56Sopenharmony_ci 5007db96d56Sopenharmony_ci } while (zst.avail_out == 0); 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci } while (err != Z_STREAM_END && ibuflen != 0); 5037db96d56Sopenharmony_ci 5047db96d56Sopenharmony_ci 5057db96d56Sopenharmony_ci if (err != Z_STREAM_END) { 5067db96d56Sopenharmony_ci inflateEnd(&zst); 5077db96d56Sopenharmony_ci zlib_error(state, zst, err, "while decompressing data"); 5087db96d56Sopenharmony_ci goto error; 5097db96d56Sopenharmony_ci } 5107db96d56Sopenharmony_ci 5117db96d56Sopenharmony_ci err = inflateEnd(&zst); 5127db96d56Sopenharmony_ci if (err != Z_OK) { 5137db96d56Sopenharmony_ci zlib_error(state, zst, err, "while finishing decompression"); 5147db96d56Sopenharmony_ci goto error; 5157db96d56Sopenharmony_ci } 5167db96d56Sopenharmony_ci 5177db96d56Sopenharmony_ci RetVal = OutputBuffer_WindowFinish(&buffer, &window, zst.avail_out); 5187db96d56Sopenharmony_ci if (RetVal != NULL) { 5197db96d56Sopenharmony_ci return RetVal; 5207db96d56Sopenharmony_ci } 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ci error: 5237db96d56Sopenharmony_ci OutputBuffer_WindowOnError(&buffer, &window); 5247db96d56Sopenharmony_ci return NULL; 5257db96d56Sopenharmony_ci} 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci/*[clinic input] 5287db96d56Sopenharmony_cizlib.compressobj 5297db96d56Sopenharmony_ci 5307db96d56Sopenharmony_ci level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION 5317db96d56Sopenharmony_ci The compression level (an integer in the range 0-9 or -1; default is 5327db96d56Sopenharmony_ci currently equivalent to 6). Higher compression levels are slower, 5337db96d56Sopenharmony_ci but produce smaller results. 5347db96d56Sopenharmony_ci method: int(c_default="DEFLATED") = DEFLATED 5357db96d56Sopenharmony_ci The compression algorithm. If given, this must be DEFLATED. 5367db96d56Sopenharmony_ci wbits: int(c_default="MAX_WBITS") = MAX_WBITS 5377db96d56Sopenharmony_ci +9 to +15: The base-two logarithm of the window size. Include a zlib 5387db96d56Sopenharmony_ci container. 5397db96d56Sopenharmony_ci -9 to -15: Generate a raw stream. 5407db96d56Sopenharmony_ci +25 to +31: Include a gzip container. 5417db96d56Sopenharmony_ci memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL 5427db96d56Sopenharmony_ci Controls the amount of memory used for internal compression state. 5437db96d56Sopenharmony_ci Valid values range from 1 to 9. Higher values result in higher memory 5447db96d56Sopenharmony_ci usage, faster compression, and smaller output. 5457db96d56Sopenharmony_ci strategy: int(c_default="Z_DEFAULT_STRATEGY") = Z_DEFAULT_STRATEGY 5467db96d56Sopenharmony_ci Used to tune the compression algorithm. Possible values are 5477db96d56Sopenharmony_ci Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY. 5487db96d56Sopenharmony_ci zdict: Py_buffer = None 5497db96d56Sopenharmony_ci The predefined compression dictionary - a sequence of bytes 5507db96d56Sopenharmony_ci containing subsequences that are likely to occur in the input data. 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_ciReturn a compressor object. 5537db96d56Sopenharmony_ci[clinic start generated code]*/ 5547db96d56Sopenharmony_ci 5557db96d56Sopenharmony_cistatic PyObject * 5567db96d56Sopenharmony_cizlib_compressobj_impl(PyObject *module, int level, int method, int wbits, 5577db96d56Sopenharmony_ci int memLevel, int strategy, Py_buffer *zdict) 5587db96d56Sopenharmony_ci/*[clinic end generated code: output=8b5bed9c8fc3814d input=2fa3d026f90ab8d5]*/ 5597db96d56Sopenharmony_ci{ 5607db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(module); 5617db96d56Sopenharmony_ci if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) { 5627db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 5637db96d56Sopenharmony_ci "zdict length does not fit in an unsigned int"); 5647db96d56Sopenharmony_ci return NULL; 5657db96d56Sopenharmony_ci } 5667db96d56Sopenharmony_ci 5677db96d56Sopenharmony_ci compobject *self = newcompobject(state->Comptype); 5687db96d56Sopenharmony_ci if (self == NULL) 5697db96d56Sopenharmony_ci goto error; 5707db96d56Sopenharmony_ci self->zst.opaque = NULL; 5717db96d56Sopenharmony_ci self->zst.zalloc = PyZlib_Malloc; 5727db96d56Sopenharmony_ci self->zst.zfree = PyZlib_Free; 5737db96d56Sopenharmony_ci self->zst.next_in = NULL; 5747db96d56Sopenharmony_ci self->zst.avail_in = 0; 5757db96d56Sopenharmony_ci int err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); 5767db96d56Sopenharmony_ci switch (err) { 5777db96d56Sopenharmony_ci case Z_OK: 5787db96d56Sopenharmony_ci self->is_initialised = 1; 5797db96d56Sopenharmony_ci if (zdict->buf == NULL) { 5807db96d56Sopenharmony_ci goto success; 5817db96d56Sopenharmony_ci } else { 5827db96d56Sopenharmony_ci err = deflateSetDictionary(&self->zst, 5837db96d56Sopenharmony_ci zdict->buf, (unsigned int)zdict->len); 5847db96d56Sopenharmony_ci switch (err) { 5857db96d56Sopenharmony_ci case Z_OK: 5867db96d56Sopenharmony_ci goto success; 5877db96d56Sopenharmony_ci case Z_STREAM_ERROR: 5887db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Invalid dictionary"); 5897db96d56Sopenharmony_ci goto error; 5907db96d56Sopenharmony_ci default: 5917db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "deflateSetDictionary()"); 5927db96d56Sopenharmony_ci goto error; 5937db96d56Sopenharmony_ci } 5947db96d56Sopenharmony_ci } 5957db96d56Sopenharmony_ci case Z_MEM_ERROR: 5967db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 5977db96d56Sopenharmony_ci "Can't allocate memory for compression object"); 5987db96d56Sopenharmony_ci goto error; 5997db96d56Sopenharmony_ci case Z_STREAM_ERROR: 6007db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); 6017db96d56Sopenharmony_ci goto error; 6027db96d56Sopenharmony_ci default: 6037db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while creating compression object"); 6047db96d56Sopenharmony_ci goto error; 6057db96d56Sopenharmony_ci } 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_ci error: 6087db96d56Sopenharmony_ci Py_CLEAR(self); 6097db96d56Sopenharmony_ci success: 6107db96d56Sopenharmony_ci return (PyObject *)self; 6117db96d56Sopenharmony_ci} 6127db96d56Sopenharmony_ci 6137db96d56Sopenharmony_cistatic int 6147db96d56Sopenharmony_ciset_inflate_zdict(zlibstate *state, compobject *self) 6157db96d56Sopenharmony_ci{ 6167db96d56Sopenharmony_ci Py_buffer zdict_buf; 6177db96d56Sopenharmony_ci if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { 6187db96d56Sopenharmony_ci return -1; 6197db96d56Sopenharmony_ci } 6207db96d56Sopenharmony_ci if ((size_t)zdict_buf.len > UINT_MAX) { 6217db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 6227db96d56Sopenharmony_ci "zdict length does not fit in an unsigned int"); 6237db96d56Sopenharmony_ci PyBuffer_Release(&zdict_buf); 6247db96d56Sopenharmony_ci return -1; 6257db96d56Sopenharmony_ci } 6267db96d56Sopenharmony_ci int err; 6277db96d56Sopenharmony_ci err = inflateSetDictionary(&self->zst, 6287db96d56Sopenharmony_ci zdict_buf.buf, (unsigned int)zdict_buf.len); 6297db96d56Sopenharmony_ci PyBuffer_Release(&zdict_buf); 6307db96d56Sopenharmony_ci if (err != Z_OK) { 6317db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while setting zdict"); 6327db96d56Sopenharmony_ci return -1; 6337db96d56Sopenharmony_ci } 6347db96d56Sopenharmony_ci return 0; 6357db96d56Sopenharmony_ci} 6367db96d56Sopenharmony_ci 6377db96d56Sopenharmony_ci/*[clinic input] 6387db96d56Sopenharmony_cizlib.decompressobj 6397db96d56Sopenharmony_ci 6407db96d56Sopenharmony_ci wbits: int(c_default="MAX_WBITS") = MAX_WBITS 6417db96d56Sopenharmony_ci The window buffer size and container format. 6427db96d56Sopenharmony_ci zdict: object(c_default="NULL") = b'' 6437db96d56Sopenharmony_ci The predefined compression dictionary. This must be the same 6447db96d56Sopenharmony_ci dictionary as used by the compressor that produced the input data. 6457db96d56Sopenharmony_ci 6467db96d56Sopenharmony_ciReturn a decompressor object. 6477db96d56Sopenharmony_ci[clinic start generated code]*/ 6487db96d56Sopenharmony_ci 6497db96d56Sopenharmony_cistatic PyObject * 6507db96d56Sopenharmony_cizlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) 6517db96d56Sopenharmony_ci/*[clinic end generated code: output=3069b99994f36906 input=d3832b8511fc977b]*/ 6527db96d56Sopenharmony_ci{ 6537db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(module); 6547db96d56Sopenharmony_ci 6557db96d56Sopenharmony_ci if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { 6567db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 6577db96d56Sopenharmony_ci "zdict argument must support the buffer protocol"); 6587db96d56Sopenharmony_ci return NULL; 6597db96d56Sopenharmony_ci } 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci compobject *self = newcompobject(state->Decomptype); 6627db96d56Sopenharmony_ci if (self == NULL) 6637db96d56Sopenharmony_ci return NULL; 6647db96d56Sopenharmony_ci self->zst.opaque = NULL; 6657db96d56Sopenharmony_ci self->zst.zalloc = PyZlib_Malloc; 6667db96d56Sopenharmony_ci self->zst.zfree = PyZlib_Free; 6677db96d56Sopenharmony_ci self->zst.next_in = NULL; 6687db96d56Sopenharmony_ci self->zst.avail_in = 0; 6697db96d56Sopenharmony_ci if (zdict != NULL) { 6707db96d56Sopenharmony_ci Py_INCREF(zdict); 6717db96d56Sopenharmony_ci self->zdict = zdict; 6727db96d56Sopenharmony_ci } 6737db96d56Sopenharmony_ci int err = inflateInit2(&self->zst, wbits); 6747db96d56Sopenharmony_ci switch (err) { 6757db96d56Sopenharmony_ci case Z_OK: 6767db96d56Sopenharmony_ci self->is_initialised = 1; 6777db96d56Sopenharmony_ci if (self->zdict != NULL && wbits < 0) { 6787db96d56Sopenharmony_ci#ifdef AT_LEAST_ZLIB_1_2_2_1 6797db96d56Sopenharmony_ci if (set_inflate_zdict(state, self) < 0) { 6807db96d56Sopenharmony_ci Py_DECREF(self); 6817db96d56Sopenharmony_ci return NULL; 6827db96d56Sopenharmony_ci } 6837db96d56Sopenharmony_ci#else 6847db96d56Sopenharmony_ci PyErr_Format(state->ZlibError, 6857db96d56Sopenharmony_ci "zlib version %s does not allow raw inflate with dictionary", 6867db96d56Sopenharmony_ci ZLIB_VERSION); 6877db96d56Sopenharmony_ci Py_DECREF(self); 6887db96d56Sopenharmony_ci return NULL; 6897db96d56Sopenharmony_ci#endif 6907db96d56Sopenharmony_ci } 6917db96d56Sopenharmony_ci return (PyObject *)self; 6927db96d56Sopenharmony_ci case Z_STREAM_ERROR: 6937db96d56Sopenharmony_ci Py_DECREF(self); 6947db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); 6957db96d56Sopenharmony_ci return NULL; 6967db96d56Sopenharmony_ci case Z_MEM_ERROR: 6977db96d56Sopenharmony_ci Py_DECREF(self); 6987db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 6997db96d56Sopenharmony_ci "Can't allocate memory for decompression object"); 7007db96d56Sopenharmony_ci return NULL; 7017db96d56Sopenharmony_ci default: 7027db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while creating decompression object"); 7037db96d56Sopenharmony_ci Py_DECREF(self); 7047db96d56Sopenharmony_ci return NULL; 7057db96d56Sopenharmony_ci } 7067db96d56Sopenharmony_ci} 7077db96d56Sopenharmony_ci 7087db96d56Sopenharmony_cistatic void 7097db96d56Sopenharmony_ciDealloc(compobject *self) 7107db96d56Sopenharmony_ci{ 7117db96d56Sopenharmony_ci PyObject *type = (PyObject *)Py_TYPE(self); 7127db96d56Sopenharmony_ci PyThread_free_lock(self->lock); 7137db96d56Sopenharmony_ci Py_XDECREF(self->unused_data); 7147db96d56Sopenharmony_ci Py_XDECREF(self->unconsumed_tail); 7157db96d56Sopenharmony_ci Py_XDECREF(self->zdict); 7167db96d56Sopenharmony_ci PyObject_Free(self); 7177db96d56Sopenharmony_ci Py_DECREF(type); 7187db96d56Sopenharmony_ci} 7197db96d56Sopenharmony_ci 7207db96d56Sopenharmony_cistatic void 7217db96d56Sopenharmony_ciComp_dealloc(compobject *self) 7227db96d56Sopenharmony_ci{ 7237db96d56Sopenharmony_ci if (self->is_initialised) 7247db96d56Sopenharmony_ci deflateEnd(&self->zst); 7257db96d56Sopenharmony_ci Dealloc(self); 7267db96d56Sopenharmony_ci} 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_cistatic void 7297db96d56Sopenharmony_ciDecomp_dealloc(compobject *self) 7307db96d56Sopenharmony_ci{ 7317db96d56Sopenharmony_ci if (self->is_initialised) 7327db96d56Sopenharmony_ci inflateEnd(&self->zst); 7337db96d56Sopenharmony_ci Dealloc(self); 7347db96d56Sopenharmony_ci} 7357db96d56Sopenharmony_ci 7367db96d56Sopenharmony_ci/*[clinic input] 7377db96d56Sopenharmony_cizlib.Compress.compress 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci cls: defining_class 7407db96d56Sopenharmony_ci data: Py_buffer 7417db96d56Sopenharmony_ci Binary data to be compressed. 7427db96d56Sopenharmony_ci / 7437db96d56Sopenharmony_ci 7447db96d56Sopenharmony_ciReturns a bytes object containing compressed data. 7457db96d56Sopenharmony_ci 7467db96d56Sopenharmony_ciAfter calling this function, some of the input data may still 7477db96d56Sopenharmony_cibe stored in internal buffers for later processing. 7487db96d56Sopenharmony_ciCall the flush() method to clear these buffers. 7497db96d56Sopenharmony_ci[clinic start generated code]*/ 7507db96d56Sopenharmony_ci 7517db96d56Sopenharmony_cistatic PyObject * 7527db96d56Sopenharmony_cizlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, 7537db96d56Sopenharmony_ci Py_buffer *data) 7547db96d56Sopenharmony_ci/*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ 7557db96d56Sopenharmony_ci{ 7567db96d56Sopenharmony_ci PyObject *RetVal; 7577db96d56Sopenharmony_ci int err; 7587db96d56Sopenharmony_ci _BlocksOutputBuffer buffer = {.list = NULL}; 7597db96d56Sopenharmony_ci zlibstate *state = PyType_GetModuleState(cls); 7607db96d56Sopenharmony_ci 7617db96d56Sopenharmony_ci ENTER_ZLIB(self); 7627db96d56Sopenharmony_ci 7637db96d56Sopenharmony_ci self->zst.next_in = data->buf; 7647db96d56Sopenharmony_ci Py_ssize_t ibuflen = data->len; 7657db96d56Sopenharmony_ci 7667db96d56Sopenharmony_ci if (OutputBuffer_InitAndGrow(&buffer, -1, &self->zst.next_out, &self->zst.avail_out) < 0) { 7677db96d56Sopenharmony_ci goto error; 7687db96d56Sopenharmony_ci } 7697db96d56Sopenharmony_ci 7707db96d56Sopenharmony_ci do { 7717db96d56Sopenharmony_ci arrange_input_buffer(&self->zst, &ibuflen); 7727db96d56Sopenharmony_ci 7737db96d56Sopenharmony_ci do { 7747db96d56Sopenharmony_ci if (self->zst.avail_out == 0) { 7757db96d56Sopenharmony_ci if (OutputBuffer_Grow(&buffer, &self->zst.next_out, &self->zst.avail_out) < 0) { 7767db96d56Sopenharmony_ci goto error; 7777db96d56Sopenharmony_ci } 7787db96d56Sopenharmony_ci } 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 7817db96d56Sopenharmony_ci err = deflate(&self->zst, Z_NO_FLUSH); 7827db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 7837db96d56Sopenharmony_ci 7847db96d56Sopenharmony_ci if (err == Z_STREAM_ERROR) { 7857db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while compressing data"); 7867db96d56Sopenharmony_ci goto error; 7877db96d56Sopenharmony_ci } 7887db96d56Sopenharmony_ci 7897db96d56Sopenharmony_ci } while (self->zst.avail_out == 0); 7907db96d56Sopenharmony_ci assert(self->zst.avail_in == 0); 7917db96d56Sopenharmony_ci 7927db96d56Sopenharmony_ci } while (ibuflen != 0); 7937db96d56Sopenharmony_ci 7947db96d56Sopenharmony_ci RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); 7957db96d56Sopenharmony_ci if (RetVal != NULL) { 7967db96d56Sopenharmony_ci goto success; 7977db96d56Sopenharmony_ci } 7987db96d56Sopenharmony_ci 7997db96d56Sopenharmony_ci error: 8007db96d56Sopenharmony_ci OutputBuffer_OnError(&buffer); 8017db96d56Sopenharmony_ci RetVal = NULL; 8027db96d56Sopenharmony_ci success: 8037db96d56Sopenharmony_ci LEAVE_ZLIB(self); 8047db96d56Sopenharmony_ci return RetVal; 8057db96d56Sopenharmony_ci} 8067db96d56Sopenharmony_ci 8077db96d56Sopenharmony_ci/* Helper for objdecompress() and flush(). Saves any unconsumed input data in 8087db96d56Sopenharmony_ci self->unused_data or self->unconsumed_tail, as appropriate. */ 8097db96d56Sopenharmony_cistatic int 8107db96d56Sopenharmony_cisave_unconsumed_input(compobject *self, Py_buffer *data, int err) 8117db96d56Sopenharmony_ci{ 8127db96d56Sopenharmony_ci if (err == Z_STREAM_END) { 8137db96d56Sopenharmony_ci /* The end of the compressed data has been reached. Store the leftover 8147db96d56Sopenharmony_ci input data in self->unused_data. */ 8157db96d56Sopenharmony_ci if (self->zst.avail_in > 0) { 8167db96d56Sopenharmony_ci Py_ssize_t old_size = PyBytes_GET_SIZE(self->unused_data); 8177db96d56Sopenharmony_ci Py_ssize_t new_size, left_size; 8187db96d56Sopenharmony_ci PyObject *new_data; 8197db96d56Sopenharmony_ci left_size = (Byte *)data->buf + data->len - self->zst.next_in; 8207db96d56Sopenharmony_ci if (left_size > (PY_SSIZE_T_MAX - old_size)) { 8217db96d56Sopenharmony_ci PyErr_NoMemory(); 8227db96d56Sopenharmony_ci return -1; 8237db96d56Sopenharmony_ci } 8247db96d56Sopenharmony_ci new_size = old_size + left_size; 8257db96d56Sopenharmony_ci new_data = PyBytes_FromStringAndSize(NULL, new_size); 8267db96d56Sopenharmony_ci if (new_data == NULL) 8277db96d56Sopenharmony_ci return -1; 8287db96d56Sopenharmony_ci memcpy(PyBytes_AS_STRING(new_data), 8297db96d56Sopenharmony_ci PyBytes_AS_STRING(self->unused_data), old_size); 8307db96d56Sopenharmony_ci memcpy(PyBytes_AS_STRING(new_data) + old_size, 8317db96d56Sopenharmony_ci self->zst.next_in, left_size); 8327db96d56Sopenharmony_ci Py_SETREF(self->unused_data, new_data); 8337db96d56Sopenharmony_ci self->zst.avail_in = 0; 8347db96d56Sopenharmony_ci } 8357db96d56Sopenharmony_ci } 8367db96d56Sopenharmony_ci 8377db96d56Sopenharmony_ci if (self->zst.avail_in > 0 || PyBytes_GET_SIZE(self->unconsumed_tail)) { 8387db96d56Sopenharmony_ci /* This code handles two distinct cases: 8397db96d56Sopenharmony_ci 1. Output limit was reached. Save leftover input in unconsumed_tail. 8407db96d56Sopenharmony_ci 2. All input data was consumed. Clear unconsumed_tail. */ 8417db96d56Sopenharmony_ci Py_ssize_t left_size = (Byte *)data->buf + data->len - self->zst.next_in; 8427db96d56Sopenharmony_ci PyObject *new_data = PyBytes_FromStringAndSize( 8437db96d56Sopenharmony_ci (char *)self->zst.next_in, left_size); 8447db96d56Sopenharmony_ci if (new_data == NULL) 8457db96d56Sopenharmony_ci return -1; 8467db96d56Sopenharmony_ci Py_SETREF(self->unconsumed_tail, new_data); 8477db96d56Sopenharmony_ci } 8487db96d56Sopenharmony_ci 8497db96d56Sopenharmony_ci return 0; 8507db96d56Sopenharmony_ci} 8517db96d56Sopenharmony_ci 8527db96d56Sopenharmony_ci/*[clinic input] 8537db96d56Sopenharmony_cizlib.Decompress.decompress 8547db96d56Sopenharmony_ci 8557db96d56Sopenharmony_ci cls: defining_class 8567db96d56Sopenharmony_ci data: Py_buffer 8577db96d56Sopenharmony_ci The binary data to decompress. 8587db96d56Sopenharmony_ci / 8597db96d56Sopenharmony_ci max_length: Py_ssize_t = 0 8607db96d56Sopenharmony_ci The maximum allowable length of the decompressed data. 8617db96d56Sopenharmony_ci Unconsumed input data will be stored in 8627db96d56Sopenharmony_ci the unconsumed_tail attribute. 8637db96d56Sopenharmony_ci 8647db96d56Sopenharmony_ciReturn a bytes object containing the decompressed version of the data. 8657db96d56Sopenharmony_ci 8667db96d56Sopenharmony_ciAfter calling this function, some of the input data may still be stored in 8677db96d56Sopenharmony_ciinternal buffers for later processing. 8687db96d56Sopenharmony_ciCall the flush() method to clear these buffers. 8697db96d56Sopenharmony_ci[clinic start generated code]*/ 8707db96d56Sopenharmony_ci 8717db96d56Sopenharmony_cistatic PyObject * 8727db96d56Sopenharmony_cizlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, 8737db96d56Sopenharmony_ci Py_buffer *data, Py_ssize_t max_length) 8747db96d56Sopenharmony_ci/*[clinic end generated code: output=b024a93c2c922d57 input=bfb37b3864cfb606]*/ 8757db96d56Sopenharmony_ci{ 8767db96d56Sopenharmony_ci int err = Z_OK; 8777db96d56Sopenharmony_ci Py_ssize_t ibuflen; 8787db96d56Sopenharmony_ci PyObject *RetVal; 8797db96d56Sopenharmony_ci _BlocksOutputBuffer buffer = {.list = NULL}; 8807db96d56Sopenharmony_ci 8817db96d56Sopenharmony_ci PyObject *module = PyType_GetModule(cls); 8827db96d56Sopenharmony_ci if (module == NULL) 8837db96d56Sopenharmony_ci return NULL; 8847db96d56Sopenharmony_ci 8857db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(module); 8867db96d56Sopenharmony_ci if (max_length < 0) { 8877db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "max_length must be non-negative"); 8887db96d56Sopenharmony_ci return NULL; 8897db96d56Sopenharmony_ci } else if (max_length == 0) { 8907db96d56Sopenharmony_ci max_length = -1; 8917db96d56Sopenharmony_ci } 8927db96d56Sopenharmony_ci 8937db96d56Sopenharmony_ci ENTER_ZLIB(self); 8947db96d56Sopenharmony_ci 8957db96d56Sopenharmony_ci self->zst.next_in = data->buf; 8967db96d56Sopenharmony_ci ibuflen = data->len; 8977db96d56Sopenharmony_ci 8987db96d56Sopenharmony_ci if (OutputBuffer_InitAndGrow(&buffer, max_length, &self->zst.next_out, &self->zst.avail_out) < 0) { 8997db96d56Sopenharmony_ci goto abort; 9007db96d56Sopenharmony_ci } 9017db96d56Sopenharmony_ci 9027db96d56Sopenharmony_ci do { 9037db96d56Sopenharmony_ci arrange_input_buffer(&self->zst, &ibuflen); 9047db96d56Sopenharmony_ci 9057db96d56Sopenharmony_ci do { 9067db96d56Sopenharmony_ci if (self->zst.avail_out == 0) { 9077db96d56Sopenharmony_ci if (OutputBuffer_GetDataSize(&buffer, self->zst.avail_out) == max_length) { 9087db96d56Sopenharmony_ci goto save; 9097db96d56Sopenharmony_ci } 9107db96d56Sopenharmony_ci if (OutputBuffer_Grow(&buffer, &self->zst.next_out, &self->zst.avail_out) < 0) { 9117db96d56Sopenharmony_ci goto abort; 9127db96d56Sopenharmony_ci } 9137db96d56Sopenharmony_ci } 9147db96d56Sopenharmony_ci 9157db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 9167db96d56Sopenharmony_ci err = inflate(&self->zst, Z_SYNC_FLUSH); 9177db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 9187db96d56Sopenharmony_ci 9197db96d56Sopenharmony_ci switch (err) { 9207db96d56Sopenharmony_ci case Z_OK: /* fall through */ 9217db96d56Sopenharmony_ci case Z_BUF_ERROR: /* fall through */ 9227db96d56Sopenharmony_ci case Z_STREAM_END: 9237db96d56Sopenharmony_ci break; 9247db96d56Sopenharmony_ci default: 9257db96d56Sopenharmony_ci if (err == Z_NEED_DICT && self->zdict != NULL) { 9267db96d56Sopenharmony_ci if (set_inflate_zdict(state, self) < 0) { 9277db96d56Sopenharmony_ci goto abort; 9287db96d56Sopenharmony_ci } 9297db96d56Sopenharmony_ci else 9307db96d56Sopenharmony_ci break; 9317db96d56Sopenharmony_ci } 9327db96d56Sopenharmony_ci goto save; 9337db96d56Sopenharmony_ci } 9347db96d56Sopenharmony_ci 9357db96d56Sopenharmony_ci } while (self->zst.avail_out == 0 || err == Z_NEED_DICT); 9367db96d56Sopenharmony_ci 9377db96d56Sopenharmony_ci } while (err != Z_STREAM_END && ibuflen != 0); 9387db96d56Sopenharmony_ci 9397db96d56Sopenharmony_ci save: 9407db96d56Sopenharmony_ci if (save_unconsumed_input(self, data, err) < 0) 9417db96d56Sopenharmony_ci goto abort; 9427db96d56Sopenharmony_ci 9437db96d56Sopenharmony_ci if (err == Z_STREAM_END) { 9447db96d56Sopenharmony_ci /* This is the logical place to call inflateEnd, but the old behaviour 9457db96d56Sopenharmony_ci of only calling it on flush() is preserved. */ 9467db96d56Sopenharmony_ci self->eof = 1; 9477db96d56Sopenharmony_ci } else if (err != Z_OK && err != Z_BUF_ERROR) { 9487db96d56Sopenharmony_ci /* We will only get Z_BUF_ERROR if the output buffer was full 9497db96d56Sopenharmony_ci but there wasn't more output when we tried again, so it is 9507db96d56Sopenharmony_ci not an error condition. 9517db96d56Sopenharmony_ci */ 9527db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while decompressing data"); 9537db96d56Sopenharmony_ci goto abort; 9547db96d56Sopenharmony_ci } 9557db96d56Sopenharmony_ci 9567db96d56Sopenharmony_ci RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); 9577db96d56Sopenharmony_ci if (RetVal != NULL) { 9587db96d56Sopenharmony_ci goto success; 9597db96d56Sopenharmony_ci } 9607db96d56Sopenharmony_ci 9617db96d56Sopenharmony_ci abort: 9627db96d56Sopenharmony_ci OutputBuffer_OnError(&buffer); 9637db96d56Sopenharmony_ci RetVal = NULL; 9647db96d56Sopenharmony_ci success: 9657db96d56Sopenharmony_ci LEAVE_ZLIB(self); 9667db96d56Sopenharmony_ci return RetVal; 9677db96d56Sopenharmony_ci} 9687db96d56Sopenharmony_ci 9697db96d56Sopenharmony_ci/*[clinic input] 9707db96d56Sopenharmony_cizlib.Compress.flush 9717db96d56Sopenharmony_ci 9727db96d56Sopenharmony_ci cls: defining_class 9737db96d56Sopenharmony_ci mode: int(c_default="Z_FINISH") = zlib.Z_FINISH 9747db96d56Sopenharmony_ci One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH. 9757db96d56Sopenharmony_ci If mode == Z_FINISH, the compressor object can no longer be 9767db96d56Sopenharmony_ci used after calling the flush() method. Otherwise, more data 9777db96d56Sopenharmony_ci can still be compressed. 9787db96d56Sopenharmony_ci / 9797db96d56Sopenharmony_ci 9807db96d56Sopenharmony_ciReturn a bytes object containing any remaining compressed data. 9817db96d56Sopenharmony_ci[clinic start generated code]*/ 9827db96d56Sopenharmony_ci 9837db96d56Sopenharmony_cistatic PyObject * 9847db96d56Sopenharmony_cizlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) 9857db96d56Sopenharmony_ci/*[clinic end generated code: output=c7efd13efd62add2 input=286146e29442eb6c]*/ 9867db96d56Sopenharmony_ci{ 9877db96d56Sopenharmony_ci int err; 9887db96d56Sopenharmony_ci PyObject *RetVal; 9897db96d56Sopenharmony_ci _BlocksOutputBuffer buffer = {.list = NULL}; 9907db96d56Sopenharmony_ci 9917db96d56Sopenharmony_ci zlibstate *state = PyType_GetModuleState(cls); 9927db96d56Sopenharmony_ci /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in 9937db96d56Sopenharmony_ci doing any work at all; just return an empty string. */ 9947db96d56Sopenharmony_ci if (mode == Z_NO_FLUSH) { 9957db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(NULL, 0); 9967db96d56Sopenharmony_ci } 9977db96d56Sopenharmony_ci 9987db96d56Sopenharmony_ci ENTER_ZLIB(self); 9997db96d56Sopenharmony_ci 10007db96d56Sopenharmony_ci self->zst.avail_in = 0; 10017db96d56Sopenharmony_ci 10027db96d56Sopenharmony_ci if (OutputBuffer_InitAndGrow(&buffer, -1, &self->zst.next_out, &self->zst.avail_out) < 0) { 10037db96d56Sopenharmony_ci goto error; 10047db96d56Sopenharmony_ci } 10057db96d56Sopenharmony_ci 10067db96d56Sopenharmony_ci do { 10077db96d56Sopenharmony_ci if (self->zst.avail_out == 0) { 10087db96d56Sopenharmony_ci if (OutputBuffer_Grow(&buffer, &self->zst.next_out, &self->zst.avail_out) < 0) { 10097db96d56Sopenharmony_ci goto error; 10107db96d56Sopenharmony_ci } 10117db96d56Sopenharmony_ci } 10127db96d56Sopenharmony_ci 10137db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 10147db96d56Sopenharmony_ci err = deflate(&self->zst, mode); 10157db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 10167db96d56Sopenharmony_ci 10177db96d56Sopenharmony_ci if (err == Z_STREAM_ERROR) { 10187db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while flushing"); 10197db96d56Sopenharmony_ci goto error; 10207db96d56Sopenharmony_ci } 10217db96d56Sopenharmony_ci } while (self->zst.avail_out == 0); 10227db96d56Sopenharmony_ci assert(self->zst.avail_in == 0); 10237db96d56Sopenharmony_ci 10247db96d56Sopenharmony_ci /* If mode is Z_FINISH, we also have to call deflateEnd() to free 10257db96d56Sopenharmony_ci various data structures. Note we should only get Z_STREAM_END when 10267db96d56Sopenharmony_ci mode is Z_FINISH, but checking both for safety*/ 10277db96d56Sopenharmony_ci if (err == Z_STREAM_END && mode == Z_FINISH) { 10287db96d56Sopenharmony_ci err = deflateEnd(&self->zst); 10297db96d56Sopenharmony_ci if (err != Z_OK) { 10307db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while finishing compression"); 10317db96d56Sopenharmony_ci goto error; 10327db96d56Sopenharmony_ci } 10337db96d56Sopenharmony_ci else 10347db96d56Sopenharmony_ci self->is_initialised = 0; 10357db96d56Sopenharmony_ci 10367db96d56Sopenharmony_ci /* We will only get Z_BUF_ERROR if the output buffer was full 10377db96d56Sopenharmony_ci but there wasn't more output when we tried again, so it is 10387db96d56Sopenharmony_ci not an error condition. 10397db96d56Sopenharmony_ci */ 10407db96d56Sopenharmony_ci } else if (err != Z_OK && err != Z_BUF_ERROR) { 10417db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while flushing"); 10427db96d56Sopenharmony_ci goto error; 10437db96d56Sopenharmony_ci } 10447db96d56Sopenharmony_ci 10457db96d56Sopenharmony_ci RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); 10467db96d56Sopenharmony_ci if (RetVal != NULL) { 10477db96d56Sopenharmony_ci goto success; 10487db96d56Sopenharmony_ci } 10497db96d56Sopenharmony_ci 10507db96d56Sopenharmony_cierror: 10517db96d56Sopenharmony_ci OutputBuffer_OnError(&buffer); 10527db96d56Sopenharmony_ci RetVal = NULL; 10537db96d56Sopenharmony_cisuccess: 10547db96d56Sopenharmony_ci LEAVE_ZLIB(self); 10557db96d56Sopenharmony_ci return RetVal; 10567db96d56Sopenharmony_ci} 10577db96d56Sopenharmony_ci 10587db96d56Sopenharmony_ci#ifdef HAVE_ZLIB_COPY 10597db96d56Sopenharmony_ci 10607db96d56Sopenharmony_ci/*[clinic input] 10617db96d56Sopenharmony_cizlib.Compress.copy 10627db96d56Sopenharmony_ci 10637db96d56Sopenharmony_ci cls: defining_class 10647db96d56Sopenharmony_ci 10657db96d56Sopenharmony_ciReturn a copy of the compression object. 10667db96d56Sopenharmony_ci[clinic start generated code]*/ 10677db96d56Sopenharmony_ci 10687db96d56Sopenharmony_cistatic PyObject * 10697db96d56Sopenharmony_cizlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) 10707db96d56Sopenharmony_ci/*[clinic end generated code: output=c4d2cfb4b0d7350b input=235497e482d40986]*/ 10717db96d56Sopenharmony_ci{ 10727db96d56Sopenharmony_ci zlibstate *state = PyType_GetModuleState(cls); 10737db96d56Sopenharmony_ci 10747db96d56Sopenharmony_ci compobject *retval = newcompobject(state->Comptype); 10757db96d56Sopenharmony_ci if (!retval) return NULL; 10767db96d56Sopenharmony_ci 10777db96d56Sopenharmony_ci /* Copy the zstream state 10787db96d56Sopenharmony_ci * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe 10797db96d56Sopenharmony_ci */ 10807db96d56Sopenharmony_ci ENTER_ZLIB(self); 10817db96d56Sopenharmony_ci int err = deflateCopy(&retval->zst, &self->zst); 10827db96d56Sopenharmony_ci switch (err) { 10837db96d56Sopenharmony_ci case Z_OK: 10847db96d56Sopenharmony_ci break; 10857db96d56Sopenharmony_ci case Z_STREAM_ERROR: 10867db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Inconsistent stream state"); 10877db96d56Sopenharmony_ci goto error; 10887db96d56Sopenharmony_ci case Z_MEM_ERROR: 10897db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 10907db96d56Sopenharmony_ci "Can't allocate memory for compression object"); 10917db96d56Sopenharmony_ci goto error; 10927db96d56Sopenharmony_ci default: 10937db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while copying compression object"); 10947db96d56Sopenharmony_ci goto error; 10957db96d56Sopenharmony_ci } 10967db96d56Sopenharmony_ci Py_INCREF(self->unused_data); 10977db96d56Sopenharmony_ci Py_XSETREF(retval->unused_data, self->unused_data); 10987db96d56Sopenharmony_ci Py_INCREF(self->unconsumed_tail); 10997db96d56Sopenharmony_ci Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); 11007db96d56Sopenharmony_ci Py_XINCREF(self->zdict); 11017db96d56Sopenharmony_ci Py_XSETREF(retval->zdict, self->zdict); 11027db96d56Sopenharmony_ci retval->eof = self->eof; 11037db96d56Sopenharmony_ci 11047db96d56Sopenharmony_ci /* Mark it as being initialized */ 11057db96d56Sopenharmony_ci retval->is_initialised = 1; 11067db96d56Sopenharmony_ci 11077db96d56Sopenharmony_ci LEAVE_ZLIB(self); 11087db96d56Sopenharmony_ci return (PyObject *)retval; 11097db96d56Sopenharmony_ci 11107db96d56Sopenharmony_cierror: 11117db96d56Sopenharmony_ci LEAVE_ZLIB(self); 11127db96d56Sopenharmony_ci Py_XDECREF(retval); 11137db96d56Sopenharmony_ci return NULL; 11147db96d56Sopenharmony_ci} 11157db96d56Sopenharmony_ci 11167db96d56Sopenharmony_ci/*[clinic input] 11177db96d56Sopenharmony_cizlib.Compress.__copy__ 11187db96d56Sopenharmony_ci 11197db96d56Sopenharmony_ci cls: defining_class 11207db96d56Sopenharmony_ci 11217db96d56Sopenharmony_ci[clinic start generated code]*/ 11227db96d56Sopenharmony_ci 11237db96d56Sopenharmony_cistatic PyObject * 11247db96d56Sopenharmony_cizlib_Compress___copy___impl(compobject *self, PyTypeObject *cls) 11257db96d56Sopenharmony_ci/*[clinic end generated code: output=074613db332cb668 input=5c0188367ab0fe64]*/ 11267db96d56Sopenharmony_ci{ 11277db96d56Sopenharmony_ci return zlib_Compress_copy_impl(self, cls); 11287db96d56Sopenharmony_ci} 11297db96d56Sopenharmony_ci 11307db96d56Sopenharmony_ci/*[clinic input] 11317db96d56Sopenharmony_cizlib.Compress.__deepcopy__ 11327db96d56Sopenharmony_ci 11337db96d56Sopenharmony_ci cls: defining_class 11347db96d56Sopenharmony_ci memo: object 11357db96d56Sopenharmony_ci / 11367db96d56Sopenharmony_ci 11377db96d56Sopenharmony_ci[clinic start generated code]*/ 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_cistatic PyObject * 11407db96d56Sopenharmony_cizlib_Compress___deepcopy___impl(compobject *self, PyTypeObject *cls, 11417db96d56Sopenharmony_ci PyObject *memo) 11427db96d56Sopenharmony_ci/*[clinic end generated code: output=24b3aed785f54033 input=c90347319a514430]*/ 11437db96d56Sopenharmony_ci{ 11447db96d56Sopenharmony_ci return zlib_Compress_copy_impl(self, cls); 11457db96d56Sopenharmony_ci} 11467db96d56Sopenharmony_ci 11477db96d56Sopenharmony_ci/*[clinic input] 11487db96d56Sopenharmony_cizlib.Decompress.copy 11497db96d56Sopenharmony_ci 11507db96d56Sopenharmony_ci cls: defining_class 11517db96d56Sopenharmony_ci 11527db96d56Sopenharmony_ciReturn a copy of the decompression object. 11537db96d56Sopenharmony_ci[clinic start generated code]*/ 11547db96d56Sopenharmony_ci 11557db96d56Sopenharmony_cistatic PyObject * 11567db96d56Sopenharmony_cizlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) 11577db96d56Sopenharmony_ci/*[clinic end generated code: output=a7ddc016e1d0a781 input=20ef3aa208282ff2]*/ 11587db96d56Sopenharmony_ci{ 11597db96d56Sopenharmony_ci zlibstate *state = PyType_GetModuleState(cls); 11607db96d56Sopenharmony_ci 11617db96d56Sopenharmony_ci compobject *retval = newcompobject(state->Decomptype); 11627db96d56Sopenharmony_ci if (!retval) return NULL; 11637db96d56Sopenharmony_ci 11647db96d56Sopenharmony_ci /* Copy the zstream state 11657db96d56Sopenharmony_ci * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe 11667db96d56Sopenharmony_ci */ 11677db96d56Sopenharmony_ci ENTER_ZLIB(self); 11687db96d56Sopenharmony_ci int err = inflateCopy(&retval->zst, &self->zst); 11697db96d56Sopenharmony_ci switch (err) { 11707db96d56Sopenharmony_ci case Z_OK: 11717db96d56Sopenharmony_ci break; 11727db96d56Sopenharmony_ci case Z_STREAM_ERROR: 11737db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "Inconsistent stream state"); 11747db96d56Sopenharmony_ci goto error; 11757db96d56Sopenharmony_ci case Z_MEM_ERROR: 11767db96d56Sopenharmony_ci PyErr_SetString(PyExc_MemoryError, 11777db96d56Sopenharmony_ci "Can't allocate memory for decompression object"); 11787db96d56Sopenharmony_ci goto error; 11797db96d56Sopenharmony_ci default: 11807db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while copying decompression object"); 11817db96d56Sopenharmony_ci goto error; 11827db96d56Sopenharmony_ci } 11837db96d56Sopenharmony_ci 11847db96d56Sopenharmony_ci Py_INCREF(self->unused_data); 11857db96d56Sopenharmony_ci Py_XSETREF(retval->unused_data, self->unused_data); 11867db96d56Sopenharmony_ci Py_INCREF(self->unconsumed_tail); 11877db96d56Sopenharmony_ci Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); 11887db96d56Sopenharmony_ci Py_XINCREF(self->zdict); 11897db96d56Sopenharmony_ci Py_XSETREF(retval->zdict, self->zdict); 11907db96d56Sopenharmony_ci retval->eof = self->eof; 11917db96d56Sopenharmony_ci 11927db96d56Sopenharmony_ci /* Mark it as being initialized */ 11937db96d56Sopenharmony_ci retval->is_initialised = 1; 11947db96d56Sopenharmony_ci 11957db96d56Sopenharmony_ci LEAVE_ZLIB(self); 11967db96d56Sopenharmony_ci return (PyObject *)retval; 11977db96d56Sopenharmony_ci 11987db96d56Sopenharmony_cierror: 11997db96d56Sopenharmony_ci LEAVE_ZLIB(self); 12007db96d56Sopenharmony_ci Py_XDECREF(retval); 12017db96d56Sopenharmony_ci return NULL; 12027db96d56Sopenharmony_ci} 12037db96d56Sopenharmony_ci 12047db96d56Sopenharmony_ci/*[clinic input] 12057db96d56Sopenharmony_cizlib.Decompress.__copy__ 12067db96d56Sopenharmony_ci 12077db96d56Sopenharmony_ci cls: defining_class 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_ci[clinic start generated code]*/ 12107db96d56Sopenharmony_ci 12117db96d56Sopenharmony_cistatic PyObject * 12127db96d56Sopenharmony_cizlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls) 12137db96d56Sopenharmony_ci/*[clinic end generated code: output=cf1e6473744f53fa input=cc3143067b622bdf]*/ 12147db96d56Sopenharmony_ci{ 12157db96d56Sopenharmony_ci return zlib_Decompress_copy_impl(self, cls); 12167db96d56Sopenharmony_ci} 12177db96d56Sopenharmony_ci 12187db96d56Sopenharmony_ci/*[clinic input] 12197db96d56Sopenharmony_cizlib.Decompress.__deepcopy__ 12207db96d56Sopenharmony_ci 12217db96d56Sopenharmony_ci cls: defining_class 12227db96d56Sopenharmony_ci memo: object 12237db96d56Sopenharmony_ci / 12247db96d56Sopenharmony_ci 12257db96d56Sopenharmony_ci[clinic start generated code]*/ 12267db96d56Sopenharmony_ci 12277db96d56Sopenharmony_cistatic PyObject * 12287db96d56Sopenharmony_cizlib_Decompress___deepcopy___impl(compobject *self, PyTypeObject *cls, 12297db96d56Sopenharmony_ci PyObject *memo) 12307db96d56Sopenharmony_ci/*[clinic end generated code: output=34f7b719a0c0d51b input=fc13b9c58622544e]*/ 12317db96d56Sopenharmony_ci{ 12327db96d56Sopenharmony_ci return zlib_Decompress_copy_impl(self, cls); 12337db96d56Sopenharmony_ci} 12347db96d56Sopenharmony_ci 12357db96d56Sopenharmony_ci#endif 12367db96d56Sopenharmony_ci 12377db96d56Sopenharmony_ci/*[clinic input] 12387db96d56Sopenharmony_cizlib.Decompress.flush 12397db96d56Sopenharmony_ci 12407db96d56Sopenharmony_ci cls: defining_class 12417db96d56Sopenharmony_ci length: Py_ssize_t(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE 12427db96d56Sopenharmony_ci the initial size of the output buffer. 12437db96d56Sopenharmony_ci / 12447db96d56Sopenharmony_ci 12457db96d56Sopenharmony_ciReturn a bytes object containing any remaining decompressed data. 12467db96d56Sopenharmony_ci[clinic start generated code]*/ 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_cistatic PyObject * 12497db96d56Sopenharmony_cizlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, 12507db96d56Sopenharmony_ci Py_ssize_t length) 12517db96d56Sopenharmony_ci/*[clinic end generated code: output=4532fc280bd0f8f2 input=42f1f4b75230e2cd]*/ 12527db96d56Sopenharmony_ci{ 12537db96d56Sopenharmony_ci int err, flush; 12547db96d56Sopenharmony_ci Py_buffer data; 12557db96d56Sopenharmony_ci PyObject *RetVal; 12567db96d56Sopenharmony_ci Py_ssize_t ibuflen; 12577db96d56Sopenharmony_ci _BlocksOutputBuffer buffer = {.list = NULL}; 12587db96d56Sopenharmony_ci _Uint32Window window; // output buffer's UINT32_MAX sliding window 12597db96d56Sopenharmony_ci 12607db96d56Sopenharmony_ci PyObject *module = PyType_GetModule(cls); 12617db96d56Sopenharmony_ci if (module == NULL) { 12627db96d56Sopenharmony_ci return NULL; 12637db96d56Sopenharmony_ci } 12647db96d56Sopenharmony_ci 12657db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(module); 12667db96d56Sopenharmony_ci 12677db96d56Sopenharmony_ci if (length <= 0) { 12687db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); 12697db96d56Sopenharmony_ci return NULL; 12707db96d56Sopenharmony_ci } 12717db96d56Sopenharmony_ci 12727db96d56Sopenharmony_ci ENTER_ZLIB(self); 12737db96d56Sopenharmony_ci 12747db96d56Sopenharmony_ci if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) { 12757db96d56Sopenharmony_ci LEAVE_ZLIB(self); 12767db96d56Sopenharmony_ci return NULL; 12777db96d56Sopenharmony_ci } 12787db96d56Sopenharmony_ci 12797db96d56Sopenharmony_ci self->zst.next_in = data.buf; 12807db96d56Sopenharmony_ci ibuflen = data.len; 12817db96d56Sopenharmony_ci 12827db96d56Sopenharmony_ci if (OutputBuffer_WindowInitWithSize(&buffer, &window, length, 12837db96d56Sopenharmony_ci &self->zst.next_out, &self->zst.avail_out) < 0) { 12847db96d56Sopenharmony_ci goto abort; 12857db96d56Sopenharmony_ci } 12867db96d56Sopenharmony_ci 12877db96d56Sopenharmony_ci do { 12887db96d56Sopenharmony_ci arrange_input_buffer(&self->zst, &ibuflen); 12897db96d56Sopenharmony_ci flush = ibuflen == 0 ? Z_FINISH : Z_NO_FLUSH; 12907db96d56Sopenharmony_ci 12917db96d56Sopenharmony_ci do { 12927db96d56Sopenharmony_ci if (self->zst.avail_out == 0) { 12937db96d56Sopenharmony_ci if (OutputBuffer_WindowGrow(&buffer, &window, 12947db96d56Sopenharmony_ci &self->zst.next_out, &self->zst.avail_out) < 0) { 12957db96d56Sopenharmony_ci goto abort; 12967db96d56Sopenharmony_ci } 12977db96d56Sopenharmony_ci } 12987db96d56Sopenharmony_ci 12997db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 13007db96d56Sopenharmony_ci err = inflate(&self->zst, flush); 13017db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 13027db96d56Sopenharmony_ci 13037db96d56Sopenharmony_ci switch (err) { 13047db96d56Sopenharmony_ci case Z_OK: /* fall through */ 13057db96d56Sopenharmony_ci case Z_BUF_ERROR: /* fall through */ 13067db96d56Sopenharmony_ci case Z_STREAM_END: 13077db96d56Sopenharmony_ci break; 13087db96d56Sopenharmony_ci default: 13097db96d56Sopenharmony_ci if (err == Z_NEED_DICT && self->zdict != NULL) { 13107db96d56Sopenharmony_ci if (set_inflate_zdict(state, self) < 0) { 13117db96d56Sopenharmony_ci goto abort; 13127db96d56Sopenharmony_ci } 13137db96d56Sopenharmony_ci else 13147db96d56Sopenharmony_ci break; 13157db96d56Sopenharmony_ci } 13167db96d56Sopenharmony_ci goto save; 13177db96d56Sopenharmony_ci } 13187db96d56Sopenharmony_ci 13197db96d56Sopenharmony_ci } while (self->zst.avail_out == 0 || err == Z_NEED_DICT); 13207db96d56Sopenharmony_ci 13217db96d56Sopenharmony_ci } while (err != Z_STREAM_END && ibuflen != 0); 13227db96d56Sopenharmony_ci 13237db96d56Sopenharmony_ci save: 13247db96d56Sopenharmony_ci if (save_unconsumed_input(self, &data, err) < 0) { 13257db96d56Sopenharmony_ci goto abort; 13267db96d56Sopenharmony_ci } 13277db96d56Sopenharmony_ci 13287db96d56Sopenharmony_ci /* If at end of stream, clean up any memory allocated by zlib. */ 13297db96d56Sopenharmony_ci if (err == Z_STREAM_END) { 13307db96d56Sopenharmony_ci self->eof = 1; 13317db96d56Sopenharmony_ci self->is_initialised = 0; 13327db96d56Sopenharmony_ci err = inflateEnd(&self->zst); 13337db96d56Sopenharmony_ci if (err != Z_OK) { 13347db96d56Sopenharmony_ci zlib_error(state, self->zst, err, "while finishing decompression"); 13357db96d56Sopenharmony_ci goto abort; 13367db96d56Sopenharmony_ci } 13377db96d56Sopenharmony_ci } 13387db96d56Sopenharmony_ci 13397db96d56Sopenharmony_ci RetVal = OutputBuffer_WindowFinish(&buffer, &window, self->zst.avail_out); 13407db96d56Sopenharmony_ci if (RetVal != NULL) { 13417db96d56Sopenharmony_ci goto success; 13427db96d56Sopenharmony_ci } 13437db96d56Sopenharmony_ci 13447db96d56Sopenharmony_ci abort: 13457db96d56Sopenharmony_ci OutputBuffer_WindowOnError(&buffer, &window); 13467db96d56Sopenharmony_ci RetVal = NULL; 13477db96d56Sopenharmony_ci success: 13487db96d56Sopenharmony_ci PyBuffer_Release(&data); 13497db96d56Sopenharmony_ci LEAVE_ZLIB(self); 13507db96d56Sopenharmony_ci return RetVal; 13517db96d56Sopenharmony_ci} 13527db96d56Sopenharmony_ci 13537db96d56Sopenharmony_ci#include "clinic/zlibmodule.c.h" 13547db96d56Sopenharmony_ci 13557db96d56Sopenharmony_cistatic PyMethodDef comp_methods[] = 13567db96d56Sopenharmony_ci{ 13577db96d56Sopenharmony_ci ZLIB_COMPRESS_COMPRESS_METHODDEF 13587db96d56Sopenharmony_ci ZLIB_COMPRESS_FLUSH_METHODDEF 13597db96d56Sopenharmony_ci ZLIB_COMPRESS_COPY_METHODDEF 13607db96d56Sopenharmony_ci ZLIB_COMPRESS___COPY___METHODDEF 13617db96d56Sopenharmony_ci ZLIB_COMPRESS___DEEPCOPY___METHODDEF 13627db96d56Sopenharmony_ci {NULL, NULL} 13637db96d56Sopenharmony_ci}; 13647db96d56Sopenharmony_ci 13657db96d56Sopenharmony_cistatic PyMethodDef Decomp_methods[] = 13667db96d56Sopenharmony_ci{ 13677db96d56Sopenharmony_ci ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF 13687db96d56Sopenharmony_ci ZLIB_DECOMPRESS_FLUSH_METHODDEF 13697db96d56Sopenharmony_ci ZLIB_DECOMPRESS_COPY_METHODDEF 13707db96d56Sopenharmony_ci ZLIB_DECOMPRESS___COPY___METHODDEF 13717db96d56Sopenharmony_ci ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF 13727db96d56Sopenharmony_ci {NULL, NULL} 13737db96d56Sopenharmony_ci}; 13747db96d56Sopenharmony_ci 13757db96d56Sopenharmony_ci#define COMP_OFF(x) offsetof(compobject, x) 13767db96d56Sopenharmony_cistatic PyMemberDef Decomp_members[] = { 13777db96d56Sopenharmony_ci {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, 13787db96d56Sopenharmony_ci {"unconsumed_tail", T_OBJECT, COMP_OFF(unconsumed_tail), READONLY}, 13797db96d56Sopenharmony_ci {"eof", T_BOOL, COMP_OFF(eof), READONLY}, 13807db96d56Sopenharmony_ci {NULL}, 13817db96d56Sopenharmony_ci}; 13827db96d56Sopenharmony_ci 13837db96d56Sopenharmony_ci/*[clinic input] 13847db96d56Sopenharmony_cizlib.adler32 13857db96d56Sopenharmony_ci 13867db96d56Sopenharmony_ci data: Py_buffer 13877db96d56Sopenharmony_ci value: unsigned_int(bitwise=True) = 1 13887db96d56Sopenharmony_ci Starting value of the checksum. 13897db96d56Sopenharmony_ci / 13907db96d56Sopenharmony_ci 13917db96d56Sopenharmony_ciCompute an Adler-32 checksum of data. 13927db96d56Sopenharmony_ci 13937db96d56Sopenharmony_ciThe returned checksum is an integer. 13947db96d56Sopenharmony_ci[clinic start generated code]*/ 13957db96d56Sopenharmony_ci 13967db96d56Sopenharmony_cistatic PyObject * 13977db96d56Sopenharmony_cizlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value) 13987db96d56Sopenharmony_ci/*[clinic end generated code: output=422106f5ca8c92c0 input=6ff4557872160e88]*/ 13997db96d56Sopenharmony_ci{ 14007db96d56Sopenharmony_ci /* Releasing the GIL for very small buffers is inefficient 14017db96d56Sopenharmony_ci and may lower performance */ 14027db96d56Sopenharmony_ci if (data->len > 1024*5) { 14037db96d56Sopenharmony_ci unsigned char *buf = data->buf; 14047db96d56Sopenharmony_ci Py_ssize_t len = data->len; 14057db96d56Sopenharmony_ci 14067db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 14077db96d56Sopenharmony_ci /* Avoid truncation of length for very large buffers. adler32() takes 14087db96d56Sopenharmony_ci length as an unsigned int, which may be narrower than Py_ssize_t. */ 14097db96d56Sopenharmony_ci while ((size_t)len > UINT_MAX) { 14107db96d56Sopenharmony_ci value = adler32(value, buf, UINT_MAX); 14117db96d56Sopenharmony_ci buf += (size_t) UINT_MAX; 14127db96d56Sopenharmony_ci len -= (size_t) UINT_MAX; 14137db96d56Sopenharmony_ci } 14147db96d56Sopenharmony_ci value = adler32(value, buf, (unsigned int)len); 14157db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 14167db96d56Sopenharmony_ci } else { 14177db96d56Sopenharmony_ci value = adler32(value, data->buf, (unsigned int)data->len); 14187db96d56Sopenharmony_ci } 14197db96d56Sopenharmony_ci return PyLong_FromUnsignedLong(value & 0xffffffffU); 14207db96d56Sopenharmony_ci} 14217db96d56Sopenharmony_ci 14227db96d56Sopenharmony_ci/*[clinic input] 14237db96d56Sopenharmony_cizlib.crc32 -> unsigned_int 14247db96d56Sopenharmony_ci 14257db96d56Sopenharmony_ci data: Py_buffer 14267db96d56Sopenharmony_ci value: unsigned_int(bitwise=True) = 0 14277db96d56Sopenharmony_ci Starting value of the checksum. 14287db96d56Sopenharmony_ci / 14297db96d56Sopenharmony_ci 14307db96d56Sopenharmony_ciCompute a CRC-32 checksum of data. 14317db96d56Sopenharmony_ci 14327db96d56Sopenharmony_ciThe returned checksum is an integer. 14337db96d56Sopenharmony_ci[clinic start generated code]*/ 14347db96d56Sopenharmony_ci 14357db96d56Sopenharmony_cistatic unsigned int 14367db96d56Sopenharmony_cizlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) 14377db96d56Sopenharmony_ci/*[clinic end generated code: output=b217562e4fe6d6a6 input=1229cb2fb5ea948a]*/ 14387db96d56Sopenharmony_ci{ 14397db96d56Sopenharmony_ci /* Releasing the GIL for very small buffers is inefficient 14407db96d56Sopenharmony_ci and may lower performance */ 14417db96d56Sopenharmony_ci if (data->len > 1024*5) { 14427db96d56Sopenharmony_ci unsigned char *buf = data->buf; 14437db96d56Sopenharmony_ci Py_ssize_t len = data->len; 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 14467db96d56Sopenharmony_ci /* Avoid truncation of length for very large buffers. crc32() takes 14477db96d56Sopenharmony_ci length as an unsigned int, which may be narrower than Py_ssize_t. */ 14487db96d56Sopenharmony_ci while ((size_t)len > UINT_MAX) { 14497db96d56Sopenharmony_ci value = crc32(value, buf, UINT_MAX); 14507db96d56Sopenharmony_ci buf += (size_t) UINT_MAX; 14517db96d56Sopenharmony_ci len -= (size_t) UINT_MAX; 14527db96d56Sopenharmony_ci } 14537db96d56Sopenharmony_ci value = crc32(value, buf, (unsigned int)len); 14547db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 14557db96d56Sopenharmony_ci } else { 14567db96d56Sopenharmony_ci value = crc32(value, data->buf, (unsigned int)data->len); 14577db96d56Sopenharmony_ci } 14587db96d56Sopenharmony_ci return value; 14597db96d56Sopenharmony_ci} 14607db96d56Sopenharmony_ci 14617db96d56Sopenharmony_ci 14627db96d56Sopenharmony_cistatic PyMethodDef zlib_methods[] = 14637db96d56Sopenharmony_ci{ 14647db96d56Sopenharmony_ci ZLIB_ADLER32_METHODDEF 14657db96d56Sopenharmony_ci ZLIB_COMPRESS_METHODDEF 14667db96d56Sopenharmony_ci ZLIB_COMPRESSOBJ_METHODDEF 14677db96d56Sopenharmony_ci ZLIB_CRC32_METHODDEF 14687db96d56Sopenharmony_ci ZLIB_DECOMPRESS_METHODDEF 14697db96d56Sopenharmony_ci ZLIB_DECOMPRESSOBJ_METHODDEF 14707db96d56Sopenharmony_ci {NULL, NULL} 14717db96d56Sopenharmony_ci}; 14727db96d56Sopenharmony_ci 14737db96d56Sopenharmony_cistatic PyType_Slot Comptype_slots[] = { 14747db96d56Sopenharmony_ci {Py_tp_dealloc, Comp_dealloc}, 14757db96d56Sopenharmony_ci {Py_tp_methods, comp_methods}, 14767db96d56Sopenharmony_ci {0, 0}, 14777db96d56Sopenharmony_ci}; 14787db96d56Sopenharmony_ci 14797db96d56Sopenharmony_cistatic PyType_Spec Comptype_spec = { 14807db96d56Sopenharmony_ci .name = "zlib.Compress", 14817db96d56Sopenharmony_ci .basicsize = sizeof(compobject), 14827db96d56Sopenharmony_ci .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, 14837db96d56Sopenharmony_ci .slots= Comptype_slots, 14847db96d56Sopenharmony_ci}; 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_cistatic PyType_Slot Decomptype_slots[] = { 14877db96d56Sopenharmony_ci {Py_tp_dealloc, Decomp_dealloc}, 14887db96d56Sopenharmony_ci {Py_tp_methods, Decomp_methods}, 14897db96d56Sopenharmony_ci {Py_tp_members, Decomp_members}, 14907db96d56Sopenharmony_ci {0, 0}, 14917db96d56Sopenharmony_ci}; 14927db96d56Sopenharmony_ci 14937db96d56Sopenharmony_cistatic PyType_Spec Decomptype_spec = { 14947db96d56Sopenharmony_ci .name = "zlib.Decompress", 14957db96d56Sopenharmony_ci .basicsize = sizeof(compobject), 14967db96d56Sopenharmony_ci .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, 14977db96d56Sopenharmony_ci .slots = Decomptype_slots, 14987db96d56Sopenharmony_ci}; 14997db96d56Sopenharmony_ci 15007db96d56Sopenharmony_ciPyDoc_STRVAR(zlib_module_documentation, 15017db96d56Sopenharmony_ci"The functions in this module allow compression and decompression using the\n" 15027db96d56Sopenharmony_ci"zlib library, which is based on GNU zip.\n" 15037db96d56Sopenharmony_ci"\n" 15047db96d56Sopenharmony_ci"adler32(string[, start]) -- Compute an Adler-32 checksum.\n" 15057db96d56Sopenharmony_ci"compress(data[, level]) -- Compress data, with compression level 0-9 or -1.\n" 15067db96d56Sopenharmony_ci"compressobj([level[, ...]]) -- Return a compressor object.\n" 15077db96d56Sopenharmony_ci"crc32(string[, start]) -- Compute a CRC-32 checksum.\n" 15087db96d56Sopenharmony_ci"decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n" 15097db96d56Sopenharmony_ci"decompressobj([wbits[, zdict]]) -- Return a decompressor object.\n" 15107db96d56Sopenharmony_ci"\n" 15117db96d56Sopenharmony_ci"'wbits' is window buffer size and container format.\n" 15127db96d56Sopenharmony_ci"Compressor objects support compress() and flush() methods; decompressor\n" 15137db96d56Sopenharmony_ci"objects support decompress() and flush()."); 15147db96d56Sopenharmony_ci 15157db96d56Sopenharmony_cistatic int 15167db96d56Sopenharmony_cizlib_clear(PyObject *mod) 15177db96d56Sopenharmony_ci{ 15187db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(mod); 15197db96d56Sopenharmony_ci Py_CLEAR(state->Comptype); 15207db96d56Sopenharmony_ci Py_CLEAR(state->Decomptype); 15217db96d56Sopenharmony_ci Py_CLEAR(state->ZlibError); 15227db96d56Sopenharmony_ci return 0; 15237db96d56Sopenharmony_ci} 15247db96d56Sopenharmony_ci 15257db96d56Sopenharmony_cistatic int 15267db96d56Sopenharmony_cizlib_traverse(PyObject *mod, visitproc visit, void *arg) 15277db96d56Sopenharmony_ci{ 15287db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(mod); 15297db96d56Sopenharmony_ci Py_VISIT(state->Comptype); 15307db96d56Sopenharmony_ci Py_VISIT(state->Decomptype); 15317db96d56Sopenharmony_ci Py_VISIT(state->ZlibError); 15327db96d56Sopenharmony_ci return 0; 15337db96d56Sopenharmony_ci} 15347db96d56Sopenharmony_ci 15357db96d56Sopenharmony_cistatic void 15367db96d56Sopenharmony_cizlib_free(void *mod) 15377db96d56Sopenharmony_ci{ 15387db96d56Sopenharmony_ci zlib_clear((PyObject *)mod); 15397db96d56Sopenharmony_ci} 15407db96d56Sopenharmony_ci 15417db96d56Sopenharmony_cistatic int 15427db96d56Sopenharmony_cizlib_exec(PyObject *mod) 15437db96d56Sopenharmony_ci{ 15447db96d56Sopenharmony_ci zlibstate *state = get_zlib_state(mod); 15457db96d56Sopenharmony_ci 15467db96d56Sopenharmony_ci state->Comptype = (PyTypeObject *)PyType_FromModuleAndSpec( 15477db96d56Sopenharmony_ci mod, &Comptype_spec, NULL); 15487db96d56Sopenharmony_ci if (state->Comptype == NULL) { 15497db96d56Sopenharmony_ci return -1; 15507db96d56Sopenharmony_ci } 15517db96d56Sopenharmony_ci 15527db96d56Sopenharmony_ci state->Decomptype = (PyTypeObject *)PyType_FromModuleAndSpec( 15537db96d56Sopenharmony_ci mod, &Decomptype_spec, NULL); 15547db96d56Sopenharmony_ci if (state->Decomptype == NULL) { 15557db96d56Sopenharmony_ci return -1; 15567db96d56Sopenharmony_ci } 15577db96d56Sopenharmony_ci 15587db96d56Sopenharmony_ci state->ZlibError = PyErr_NewException("zlib.error", NULL, NULL); 15597db96d56Sopenharmony_ci if (state->ZlibError == NULL) { 15607db96d56Sopenharmony_ci return -1; 15617db96d56Sopenharmony_ci } 15627db96d56Sopenharmony_ci 15637db96d56Sopenharmony_ci Py_INCREF(state->ZlibError); 15647db96d56Sopenharmony_ci if (PyModule_AddObject(mod, "error", state->ZlibError) < 0) { 15657db96d56Sopenharmony_ci Py_DECREF(state->ZlibError); 15667db96d56Sopenharmony_ci return -1; 15677db96d56Sopenharmony_ci } 15687db96d56Sopenharmony_ci 15697db96d56Sopenharmony_ci#define ZLIB_ADD_INT_MACRO(c) \ 15707db96d56Sopenharmony_ci do { \ 15717db96d56Sopenharmony_ci if ((PyModule_AddIntConstant(mod, #c, c)) < 0) { \ 15727db96d56Sopenharmony_ci return -1; \ 15737db96d56Sopenharmony_ci } \ 15747db96d56Sopenharmony_ci } while(0) 15757db96d56Sopenharmony_ci 15767db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(MAX_WBITS); 15777db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(DEFLATED); 15787db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(DEF_MEM_LEVEL); 15797db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(DEF_BUF_SIZE); 15807db96d56Sopenharmony_ci // compression levels 15817db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_NO_COMPRESSION); 15827db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_BEST_SPEED); 15837db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_BEST_COMPRESSION); 15847db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_DEFAULT_COMPRESSION); 15857db96d56Sopenharmony_ci // compression strategies 15867db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_FILTERED); 15877db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_HUFFMAN_ONLY); 15887db96d56Sopenharmony_ci#ifdef Z_RLE // 1.2.0.1 15897db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_RLE); 15907db96d56Sopenharmony_ci#endif 15917db96d56Sopenharmony_ci#ifdef Z_FIXED // 1.2.2.2 15927db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_FIXED); 15937db96d56Sopenharmony_ci#endif 15947db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_DEFAULT_STRATEGY); 15957db96d56Sopenharmony_ci // allowed flush values 15967db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_NO_FLUSH); 15977db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_PARTIAL_FLUSH); 15987db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_SYNC_FLUSH); 15997db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_FULL_FLUSH); 16007db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_FINISH); 16017db96d56Sopenharmony_ci#ifdef Z_BLOCK // 1.2.0.5 for inflate, 1.2.3.4 for deflate 16027db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_BLOCK); 16037db96d56Sopenharmony_ci#endif 16047db96d56Sopenharmony_ci#ifdef Z_TREES // 1.2.3.4, only for inflate 16057db96d56Sopenharmony_ci ZLIB_ADD_INT_MACRO(Z_TREES); 16067db96d56Sopenharmony_ci#endif 16077db96d56Sopenharmony_ci PyObject *ver = PyUnicode_FromString(ZLIB_VERSION); 16087db96d56Sopenharmony_ci if (ver == NULL) { 16097db96d56Sopenharmony_ci return -1; 16107db96d56Sopenharmony_ci } 16117db96d56Sopenharmony_ci 16127db96d56Sopenharmony_ci if (PyModule_AddObject(mod, "ZLIB_VERSION", ver) < 0) { 16137db96d56Sopenharmony_ci Py_DECREF(ver); 16147db96d56Sopenharmony_ci return -1; 16157db96d56Sopenharmony_ci } 16167db96d56Sopenharmony_ci 16177db96d56Sopenharmony_ci ver = PyUnicode_FromString(zlibVersion()); 16187db96d56Sopenharmony_ci if (ver == NULL) { 16197db96d56Sopenharmony_ci return -1; 16207db96d56Sopenharmony_ci } 16217db96d56Sopenharmony_ci 16227db96d56Sopenharmony_ci if (PyModule_AddObject(mod, "ZLIB_RUNTIME_VERSION", ver) < 0) { 16237db96d56Sopenharmony_ci Py_DECREF(ver); 16247db96d56Sopenharmony_ci return -1; 16257db96d56Sopenharmony_ci } 16267db96d56Sopenharmony_ci 16277db96d56Sopenharmony_ci if (PyModule_AddStringConstant(mod, "__version__", "1.0") < 0) { 16287db96d56Sopenharmony_ci return -1; 16297db96d56Sopenharmony_ci } 16307db96d56Sopenharmony_ci return 0; 16317db96d56Sopenharmony_ci} 16327db96d56Sopenharmony_ci 16337db96d56Sopenharmony_cistatic PyModuleDef_Slot zlib_slots[] = { 16347db96d56Sopenharmony_ci {Py_mod_exec, zlib_exec}, 16357db96d56Sopenharmony_ci {0, NULL} 16367db96d56Sopenharmony_ci}; 16377db96d56Sopenharmony_ci 16387db96d56Sopenharmony_cistatic struct PyModuleDef zlibmodule = { 16397db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 16407db96d56Sopenharmony_ci .m_name = "zlib", 16417db96d56Sopenharmony_ci .m_doc = zlib_module_documentation, 16427db96d56Sopenharmony_ci .m_size = sizeof(zlibstate), 16437db96d56Sopenharmony_ci .m_methods = zlib_methods, 16447db96d56Sopenharmony_ci .m_slots = zlib_slots, 16457db96d56Sopenharmony_ci .m_traverse = zlib_traverse, 16467db96d56Sopenharmony_ci .m_clear = zlib_clear, 16477db96d56Sopenharmony_ci .m_free = zlib_free, 16487db96d56Sopenharmony_ci}; 16497db96d56Sopenharmony_ci 16507db96d56Sopenharmony_ciPyMODINIT_FUNC 16517db96d56Sopenharmony_ciPyInit_zlib(void) 16527db96d56Sopenharmony_ci{ 16537db96d56Sopenharmony_ci return PyModuleDef_Init(&zlibmodule); 16547db96d56Sopenharmony_ci} 1655