1cb93a386Sopenharmony_ci#define PY_SSIZE_T_CLEAN 1 2cb93a386Sopenharmony_ci#include <Python.h> 3cb93a386Sopenharmony_ci#include <bytesobject.h> 4cb93a386Sopenharmony_ci#include <structmember.h> 5cb93a386Sopenharmony_ci#include <vector> 6cb93a386Sopenharmony_ci#include "../common/version.h" 7cb93a386Sopenharmony_ci#include <brotli/decode.h> 8cb93a386Sopenharmony_ci#include <brotli/encode.h> 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#if PY_MAJOR_VERSION >= 3 11cb93a386Sopenharmony_ci#define PyInt_Check PyLong_Check 12cb93a386Sopenharmony_ci#define PyInt_AsLong PyLong_AsLong 13cb93a386Sopenharmony_ci#endif 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cistatic PyObject *BrotliError; 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cistatic int as_bounded_int(PyObject *o, int* result, int lower_bound, int upper_bound) { 18cb93a386Sopenharmony_ci long value = PyInt_AsLong(o); 19cb93a386Sopenharmony_ci if ((value < (long) lower_bound) || (value > (long) upper_bound)) { 20cb93a386Sopenharmony_ci return 0; 21cb93a386Sopenharmony_ci } 22cb93a386Sopenharmony_ci *result = (int) value; 23cb93a386Sopenharmony_ci return 1; 24cb93a386Sopenharmony_ci} 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_cistatic int mode_convertor(PyObject *o, BrotliEncoderMode *mode) { 27cb93a386Sopenharmony_ci if (!PyInt_Check(o)) { 28cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid mode"); 29cb93a386Sopenharmony_ci return 0; 30cb93a386Sopenharmony_ci } 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci int mode_value = -1; 33cb93a386Sopenharmony_ci if (!as_bounded_int(o, &mode_value, 0, 255)) { 34cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid mode"); 35cb93a386Sopenharmony_ci return 0; 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci *mode = (BrotliEncoderMode) mode_value; 38cb93a386Sopenharmony_ci if (*mode != BROTLI_MODE_GENERIC && 39cb93a386Sopenharmony_ci *mode != BROTLI_MODE_TEXT && 40cb93a386Sopenharmony_ci *mode != BROTLI_MODE_FONT) { 41cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid mode"); 42cb93a386Sopenharmony_ci return 0; 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci return 1; 46cb93a386Sopenharmony_ci} 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_cistatic int quality_convertor(PyObject *o, int *quality) { 49cb93a386Sopenharmony_ci if (!PyInt_Check(o)) { 50cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid quality"); 51cb93a386Sopenharmony_ci return 0; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci if (!as_bounded_int(o, quality, 0, 11)) { 55cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid quality. Range is 0 to 11."); 56cb93a386Sopenharmony_ci return 0; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci return 1; 60cb93a386Sopenharmony_ci} 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_cistatic int lgwin_convertor(PyObject *o, int *lgwin) { 63cb93a386Sopenharmony_ci if (!PyInt_Check(o)) { 64cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid lgwin"); 65cb93a386Sopenharmony_ci return 0; 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci if (!as_bounded_int(o, lgwin, 10, 24)) { 69cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid lgwin. Range is 10 to 24."); 70cb93a386Sopenharmony_ci return 0; 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci return 1; 74cb93a386Sopenharmony_ci} 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_cistatic int lgblock_convertor(PyObject *o, int *lgblock) { 77cb93a386Sopenharmony_ci if (!PyInt_Check(o)) { 78cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid lgblock"); 79cb93a386Sopenharmony_ci return 0; 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci if (!as_bounded_int(o, lgblock, 0, 24) || (*lgblock != 0 && *lgblock < 16)) { 83cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "Invalid lgblock. Can be 0 or in range 16 to 24."); 84cb93a386Sopenharmony_ci return 0; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci return 1; 88cb93a386Sopenharmony_ci} 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_cistatic BROTLI_BOOL compress_stream(BrotliEncoderState* enc, BrotliEncoderOperation op, 91cb93a386Sopenharmony_ci std::vector<uint8_t>* output, 92cb93a386Sopenharmony_ci uint8_t* input, size_t input_length) { 93cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 94cb93a386Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci size_t available_in = input_length; 97cb93a386Sopenharmony_ci const uint8_t* next_in = input; 98cb93a386Sopenharmony_ci size_t available_out = 0; 99cb93a386Sopenharmony_ci uint8_t* next_out = NULL; 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci while (ok) { 102cb93a386Sopenharmony_ci ok = BrotliEncoderCompressStream(enc, op, 103cb93a386Sopenharmony_ci &available_in, &next_in, 104cb93a386Sopenharmony_ci &available_out, &next_out, NULL); 105cb93a386Sopenharmony_ci if (!ok) 106cb93a386Sopenharmony_ci break; 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci size_t buffer_length = 0; // Request all available output. 109cb93a386Sopenharmony_ci const uint8_t* buffer = BrotliEncoderTakeOutput(enc, &buffer_length); 110cb93a386Sopenharmony_ci if (buffer_length) { 111cb93a386Sopenharmony_ci (*output).insert((*output).end(), buffer, buffer + buffer_length); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci if (available_in || BrotliEncoderHasMoreOutput(enc)) { 115cb93a386Sopenharmony_ci continue; 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci break; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci Py_END_ALLOW_THREADS 122cb93a386Sopenharmony_ci return ok; 123cb93a386Sopenharmony_ci} 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Compressor_doc, 126cb93a386Sopenharmony_ci"An object to compress a byte string.\n" 127cb93a386Sopenharmony_ci"\n" 128cb93a386Sopenharmony_ci"Signature:\n" 129cb93a386Sopenharmony_ci" Compressor(mode=MODE_GENERIC, quality=11, lgwin=22, lgblock=0)\n" 130cb93a386Sopenharmony_ci"\n" 131cb93a386Sopenharmony_ci"Args:\n" 132cb93a386Sopenharmony_ci" mode (int, optional): The compression mode can be MODE_GENERIC (default),\n" 133cb93a386Sopenharmony_ci" MODE_TEXT (for UTF-8 format text input) or MODE_FONT (for WOFF 2.0). \n" 134cb93a386Sopenharmony_ci" quality (int, optional): Controls the compression-speed vs compression-\n" 135cb93a386Sopenharmony_ci" density tradeoff. The higher the quality, the slower the compression.\n" 136cb93a386Sopenharmony_ci" Range is 0 to 11. Defaults to 11.\n" 137cb93a386Sopenharmony_ci" lgwin (int, optional): Base 2 logarithm of the sliding window size. Range\n" 138cb93a386Sopenharmony_ci" is 10 to 24. Defaults to 22.\n" 139cb93a386Sopenharmony_ci" lgblock (int, optional): Base 2 logarithm of the maximum input block size.\n" 140cb93a386Sopenharmony_ci" Range is 16 to 24. If set to 0, the value will be set based on the\n" 141cb93a386Sopenharmony_ci" quality. Defaults to 0.\n" 142cb93a386Sopenharmony_ci"\n" 143cb93a386Sopenharmony_ci"Raises:\n" 144cb93a386Sopenharmony_ci" brotli.error: If arguments are invalid.\n"); 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_citypedef struct { 147cb93a386Sopenharmony_ci PyObject_HEAD 148cb93a386Sopenharmony_ci BrotliEncoderState* enc; 149cb93a386Sopenharmony_ci} brotli_Compressor; 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_cistatic void brotli_Compressor_dealloc(brotli_Compressor* self) { 152cb93a386Sopenharmony_ci BrotliEncoderDestroyInstance(self->enc); 153cb93a386Sopenharmony_ci #if PY_MAJOR_VERSION >= 3 154cb93a386Sopenharmony_ci Py_TYPE(self)->tp_free((PyObject*)self); 155cb93a386Sopenharmony_ci #else 156cb93a386Sopenharmony_ci self->ob_type->tp_free((PyObject*)self); 157cb93a386Sopenharmony_ci #endif 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_cistatic PyObject* brotli_Compressor_new(PyTypeObject *type, PyObject *args, PyObject *keywds) { 161cb93a386Sopenharmony_ci brotli_Compressor *self; 162cb93a386Sopenharmony_ci self = (brotli_Compressor *)type->tp_alloc(type, 0); 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ci if (self != NULL) { 165cb93a386Sopenharmony_ci self->enc = BrotliEncoderCreateInstance(0, 0, 0); 166cb93a386Sopenharmony_ci } 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci return (PyObject *)self; 169cb93a386Sopenharmony_ci} 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_cistatic int brotli_Compressor_init(brotli_Compressor *self, PyObject *args, PyObject *keywds) { 172cb93a386Sopenharmony_ci BrotliEncoderMode mode = (BrotliEncoderMode) -1; 173cb93a386Sopenharmony_ci int quality = -1; 174cb93a386Sopenharmony_ci int lgwin = -1; 175cb93a386Sopenharmony_ci int lgblock = -1; 176cb93a386Sopenharmony_ci int ok; 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci static const char *kwlist[] = {"mode", "quality", "lgwin", "lgblock", NULL}; 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci ok = PyArg_ParseTupleAndKeywords(args, keywds, "|O&O&O&O&:Compressor", 181cb93a386Sopenharmony_ci const_cast<char **>(kwlist), 182cb93a386Sopenharmony_ci &mode_convertor, &mode, 183cb93a386Sopenharmony_ci &quality_convertor, &quality, 184cb93a386Sopenharmony_ci &lgwin_convertor, &lgwin, 185cb93a386Sopenharmony_ci &lgblock_convertor, &lgblock); 186cb93a386Sopenharmony_ci if (!ok) 187cb93a386Sopenharmony_ci return -1; 188cb93a386Sopenharmony_ci if (!self->enc) 189cb93a386Sopenharmony_ci return -1; 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_ci if ((int) mode != -1) 192cb93a386Sopenharmony_ci BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_MODE, (uint32_t)mode); 193cb93a386Sopenharmony_ci if (quality != -1) 194cb93a386Sopenharmony_ci BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_QUALITY, (uint32_t)quality); 195cb93a386Sopenharmony_ci if (lgwin != -1) 196cb93a386Sopenharmony_ci BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_LGWIN, (uint32_t)lgwin); 197cb93a386Sopenharmony_ci if (lgblock != -1) 198cb93a386Sopenharmony_ci BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_LGBLOCK, (uint32_t)lgblock); 199cb93a386Sopenharmony_ci 200cb93a386Sopenharmony_ci return 0; 201cb93a386Sopenharmony_ci} 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Compressor_process_doc, 204cb93a386Sopenharmony_ci"Process \"string\" for compression, returning a string that contains \n" 205cb93a386Sopenharmony_ci"compressed output data. This data should be concatenated to the output \n" 206cb93a386Sopenharmony_ci"produced by any preceding calls to the \"process()\" or flush()\" methods. \n" 207cb93a386Sopenharmony_ci"Some or all of the input may be kept in internal buffers for later \n" 208cb93a386Sopenharmony_ci"processing, and the compressed output data may be empty until enough input \n" 209cb93a386Sopenharmony_ci"has been accumulated.\n" 210cb93a386Sopenharmony_ci"\n" 211cb93a386Sopenharmony_ci"Signature:\n" 212cb93a386Sopenharmony_ci" compress(string)\n" 213cb93a386Sopenharmony_ci"\n" 214cb93a386Sopenharmony_ci"Args:\n" 215cb93a386Sopenharmony_ci" string (bytes): The input data\n" 216cb93a386Sopenharmony_ci"\n" 217cb93a386Sopenharmony_ci"Returns:\n" 218cb93a386Sopenharmony_ci" The compressed output data (bytes)\n" 219cb93a386Sopenharmony_ci"\n" 220cb93a386Sopenharmony_ci"Raises:\n" 221cb93a386Sopenharmony_ci" brotli.error: If compression fails\n"); 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_cistatic PyObject* brotli_Compressor_process(brotli_Compressor *self, PyObject *args) { 224cb93a386Sopenharmony_ci PyObject* ret = NULL; 225cb93a386Sopenharmony_ci std::vector<uint8_t> output; 226cb93a386Sopenharmony_ci Py_buffer input; 227cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci#if PY_MAJOR_VERSION >= 3 230cb93a386Sopenharmony_ci ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "y*:process", &input); 231cb93a386Sopenharmony_ci#else 232cb93a386Sopenharmony_ci ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "s*:process", &input); 233cb93a386Sopenharmony_ci#endif 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci if (!ok) 236cb93a386Sopenharmony_ci return NULL; 237cb93a386Sopenharmony_ci 238cb93a386Sopenharmony_ci if (!self->enc) { 239cb93a386Sopenharmony_ci ok = BROTLI_FALSE; 240cb93a386Sopenharmony_ci goto end; 241cb93a386Sopenharmony_ci } 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_ci ok = compress_stream(self->enc, BROTLI_OPERATION_PROCESS, 244cb93a386Sopenharmony_ci &output, static_cast<uint8_t*>(input.buf), input.len); 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ciend: 247cb93a386Sopenharmony_ci PyBuffer_Release(&input); 248cb93a386Sopenharmony_ci if (ok) { 249cb93a386Sopenharmony_ci ret = PyBytes_FromStringAndSize((char*)(output.size() ? &output[0] : NULL), output.size()); 250cb93a386Sopenharmony_ci } else { 251cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliEncoderCompressStream failed while processing the stream"); 252cb93a386Sopenharmony_ci } 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_ci return ret; 255cb93a386Sopenharmony_ci} 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Compressor_flush_doc, 258cb93a386Sopenharmony_ci"Process all pending input, returning a string containing the remaining\n" 259cb93a386Sopenharmony_ci"compressed data. This data should be concatenated to the output produced by\n" 260cb93a386Sopenharmony_ci"any preceding calls to the \"process()\" or \"flush()\" methods.\n" 261cb93a386Sopenharmony_ci"\n" 262cb93a386Sopenharmony_ci"Signature:\n" 263cb93a386Sopenharmony_ci" flush()\n" 264cb93a386Sopenharmony_ci"\n" 265cb93a386Sopenharmony_ci"Returns:\n" 266cb93a386Sopenharmony_ci" The compressed output data (bytes)\n" 267cb93a386Sopenharmony_ci"\n" 268cb93a386Sopenharmony_ci"Raises:\n" 269cb93a386Sopenharmony_ci" brotli.error: If compression fails\n"); 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_cistatic PyObject* brotli_Compressor_flush(brotli_Compressor *self) { 272cb93a386Sopenharmony_ci PyObject *ret = NULL; 273cb93a386Sopenharmony_ci std::vector<uint8_t> output; 274cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci if (!self->enc) { 277cb93a386Sopenharmony_ci ok = BROTLI_FALSE; 278cb93a386Sopenharmony_ci goto end; 279cb93a386Sopenharmony_ci } 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci ok = compress_stream(self->enc, BROTLI_OPERATION_FLUSH, 282cb93a386Sopenharmony_ci &output, NULL, 0); 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_ciend: 285cb93a386Sopenharmony_ci if (ok) { 286cb93a386Sopenharmony_ci ret = PyBytes_FromStringAndSize((char*)(output.size() ? &output[0] : NULL), output.size()); 287cb93a386Sopenharmony_ci } else { 288cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliEncoderCompressStream failed while flushing the stream"); 289cb93a386Sopenharmony_ci } 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ci return ret; 292cb93a386Sopenharmony_ci} 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Compressor_finish_doc, 295cb93a386Sopenharmony_ci"Process all pending input and complete all compression, returning a string\n" 296cb93a386Sopenharmony_ci"containing the remaining compressed data. This data should be concatenated\n" 297cb93a386Sopenharmony_ci"to the output produced by any preceding calls to the \"process()\" or\n" 298cb93a386Sopenharmony_ci"\"flush()\" methods.\n" 299cb93a386Sopenharmony_ci"After calling \"finish()\", the \"process()\" and \"flush()\" methods\n" 300cb93a386Sopenharmony_ci"cannot be called again, and a new \"Compressor\" object should be created.\n" 301cb93a386Sopenharmony_ci"\n" 302cb93a386Sopenharmony_ci"Signature:\n" 303cb93a386Sopenharmony_ci" finish(string)\n" 304cb93a386Sopenharmony_ci"\n" 305cb93a386Sopenharmony_ci"Returns:\n" 306cb93a386Sopenharmony_ci" The compressed output data (bytes)\n" 307cb93a386Sopenharmony_ci"\n" 308cb93a386Sopenharmony_ci"Raises:\n" 309cb93a386Sopenharmony_ci" brotli.error: If compression fails\n"); 310cb93a386Sopenharmony_ci 311cb93a386Sopenharmony_cistatic PyObject* brotli_Compressor_finish(brotli_Compressor *self) { 312cb93a386Sopenharmony_ci PyObject *ret = NULL; 313cb93a386Sopenharmony_ci std::vector<uint8_t> output; 314cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ci if (!self->enc) { 317cb93a386Sopenharmony_ci ok = BROTLI_FALSE; 318cb93a386Sopenharmony_ci goto end; 319cb93a386Sopenharmony_ci } 320cb93a386Sopenharmony_ci 321cb93a386Sopenharmony_ci ok = compress_stream(self->enc, BROTLI_OPERATION_FINISH, 322cb93a386Sopenharmony_ci &output, NULL, 0); 323cb93a386Sopenharmony_ci 324cb93a386Sopenharmony_ci if (ok) { 325cb93a386Sopenharmony_ci ok = BrotliEncoderIsFinished(self->enc); 326cb93a386Sopenharmony_ci } 327cb93a386Sopenharmony_ci 328cb93a386Sopenharmony_ciend: 329cb93a386Sopenharmony_ci if (ok) { 330cb93a386Sopenharmony_ci ret = PyBytes_FromStringAndSize((char*)(output.empty() ? NULL : &output[0]), output.size()); 331cb93a386Sopenharmony_ci } else { 332cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliEncoderCompressStream failed while finishing the stream"); 333cb93a386Sopenharmony_ci } 334cb93a386Sopenharmony_ci 335cb93a386Sopenharmony_ci return ret; 336cb93a386Sopenharmony_ci} 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_cistatic PyMemberDef brotli_Compressor_members[] = { 339cb93a386Sopenharmony_ci {NULL} /* Sentinel */ 340cb93a386Sopenharmony_ci}; 341cb93a386Sopenharmony_ci 342cb93a386Sopenharmony_cistatic PyMethodDef brotli_Compressor_methods[] = { 343cb93a386Sopenharmony_ci {"process", (PyCFunction)brotli_Compressor_process, METH_VARARGS, brotli_Compressor_process_doc}, 344cb93a386Sopenharmony_ci {"flush", (PyCFunction)brotli_Compressor_flush, METH_NOARGS, brotli_Compressor_flush_doc}, 345cb93a386Sopenharmony_ci {"finish", (PyCFunction)brotli_Compressor_finish, METH_NOARGS, brotli_Compressor_finish_doc}, 346cb93a386Sopenharmony_ci {NULL} /* Sentinel */ 347cb93a386Sopenharmony_ci}; 348cb93a386Sopenharmony_ci 349cb93a386Sopenharmony_cistatic PyTypeObject brotli_CompressorType = { 350cb93a386Sopenharmony_ci #if PY_MAJOR_VERSION >= 3 351cb93a386Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 352cb93a386Sopenharmony_ci #else 353cb93a386Sopenharmony_ci PyObject_HEAD_INIT(NULL) 354cb93a386Sopenharmony_ci 0, /* ob_size*/ 355cb93a386Sopenharmony_ci #endif 356cb93a386Sopenharmony_ci "brotli.Compressor", /* tp_name */ 357cb93a386Sopenharmony_ci sizeof(brotli_Compressor), /* tp_basicsize */ 358cb93a386Sopenharmony_ci 0, /* tp_itemsize */ 359cb93a386Sopenharmony_ci (destructor)brotli_Compressor_dealloc, /* tp_dealloc */ 360cb93a386Sopenharmony_ci 0, /* tp_print */ 361cb93a386Sopenharmony_ci 0, /* tp_getattr */ 362cb93a386Sopenharmony_ci 0, /* tp_setattr */ 363cb93a386Sopenharmony_ci 0, /* tp_compare */ 364cb93a386Sopenharmony_ci 0, /* tp_repr */ 365cb93a386Sopenharmony_ci 0, /* tp_as_number */ 366cb93a386Sopenharmony_ci 0, /* tp_as_sequence */ 367cb93a386Sopenharmony_ci 0, /* tp_as_mapping */ 368cb93a386Sopenharmony_ci 0, /* tp_hash */ 369cb93a386Sopenharmony_ci 0, /* tp_call */ 370cb93a386Sopenharmony_ci 0, /* tp_str */ 371cb93a386Sopenharmony_ci 0, /* tp_getattro */ 372cb93a386Sopenharmony_ci 0, /* tp_setattro */ 373cb93a386Sopenharmony_ci 0, /* tp_as_buffer */ 374cb93a386Sopenharmony_ci Py_TPFLAGS_DEFAULT, /* tp_flags */ 375cb93a386Sopenharmony_ci brotli_Compressor_doc, /* tp_doc */ 376cb93a386Sopenharmony_ci 0, /* tp_traverse */ 377cb93a386Sopenharmony_ci 0, /* tp_clear */ 378cb93a386Sopenharmony_ci 0, /* tp_richcompare */ 379cb93a386Sopenharmony_ci 0, /* tp_weaklistoffset */ 380cb93a386Sopenharmony_ci 0, /* tp_iter */ 381cb93a386Sopenharmony_ci 0, /* tp_iternext */ 382cb93a386Sopenharmony_ci brotli_Compressor_methods, /* tp_methods */ 383cb93a386Sopenharmony_ci brotli_Compressor_members, /* tp_members */ 384cb93a386Sopenharmony_ci 0, /* tp_getset */ 385cb93a386Sopenharmony_ci 0, /* tp_base */ 386cb93a386Sopenharmony_ci 0, /* tp_dict */ 387cb93a386Sopenharmony_ci 0, /* tp_descr_get */ 388cb93a386Sopenharmony_ci 0, /* tp_descr_set */ 389cb93a386Sopenharmony_ci 0, /* tp_dictoffset */ 390cb93a386Sopenharmony_ci (initproc)brotli_Compressor_init, /* tp_init */ 391cb93a386Sopenharmony_ci 0, /* tp_alloc */ 392cb93a386Sopenharmony_ci brotli_Compressor_new, /* tp_new */ 393cb93a386Sopenharmony_ci}; 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_cistatic BROTLI_BOOL decompress_stream(BrotliDecoderState* dec, 396cb93a386Sopenharmony_ci std::vector<uint8_t>* output, 397cb93a386Sopenharmony_ci uint8_t* input, size_t input_length) { 398cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 399cb93a386Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 400cb93a386Sopenharmony_ci 401cb93a386Sopenharmony_ci size_t available_in = input_length; 402cb93a386Sopenharmony_ci const uint8_t* next_in = input; 403cb93a386Sopenharmony_ci size_t available_out = 0; 404cb93a386Sopenharmony_ci uint8_t* next_out = NULL; 405cb93a386Sopenharmony_ci 406cb93a386Sopenharmony_ci BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; 407cb93a386Sopenharmony_ci while (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { 408cb93a386Sopenharmony_ci result = BrotliDecoderDecompressStream(dec, 409cb93a386Sopenharmony_ci &available_in, &next_in, 410cb93a386Sopenharmony_ci &available_out, &next_out, NULL); 411cb93a386Sopenharmony_ci size_t buffer_length = 0; // Request all available output. 412cb93a386Sopenharmony_ci const uint8_t* buffer = BrotliDecoderTakeOutput(dec, &buffer_length); 413cb93a386Sopenharmony_ci if (buffer_length) { 414cb93a386Sopenharmony_ci (*output).insert((*output).end(), buffer, buffer + buffer_length); 415cb93a386Sopenharmony_ci } 416cb93a386Sopenharmony_ci } 417cb93a386Sopenharmony_ci ok = result != BROTLI_DECODER_RESULT_ERROR && !available_in; 418cb93a386Sopenharmony_ci 419cb93a386Sopenharmony_ci Py_END_ALLOW_THREADS 420cb93a386Sopenharmony_ci return ok; 421cb93a386Sopenharmony_ci} 422cb93a386Sopenharmony_ci 423cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Decompressor_doc, 424cb93a386Sopenharmony_ci"An object to decompress a byte string.\n" 425cb93a386Sopenharmony_ci"\n" 426cb93a386Sopenharmony_ci"Signature:\n" 427cb93a386Sopenharmony_ci" Decompressor()\n" 428cb93a386Sopenharmony_ci"\n" 429cb93a386Sopenharmony_ci"Raises:\n" 430cb93a386Sopenharmony_ci" brotli.error: If arguments are invalid.\n"); 431cb93a386Sopenharmony_ci 432cb93a386Sopenharmony_citypedef struct { 433cb93a386Sopenharmony_ci PyObject_HEAD 434cb93a386Sopenharmony_ci BrotliDecoderState* dec; 435cb93a386Sopenharmony_ci} brotli_Decompressor; 436cb93a386Sopenharmony_ci 437cb93a386Sopenharmony_cistatic void brotli_Decompressor_dealloc(brotli_Decompressor* self) { 438cb93a386Sopenharmony_ci BrotliDecoderDestroyInstance(self->dec); 439cb93a386Sopenharmony_ci #if PY_MAJOR_VERSION >= 3 440cb93a386Sopenharmony_ci Py_TYPE(self)->tp_free((PyObject*)self); 441cb93a386Sopenharmony_ci #else 442cb93a386Sopenharmony_ci self->ob_type->tp_free((PyObject*)self); 443cb93a386Sopenharmony_ci #endif 444cb93a386Sopenharmony_ci} 445cb93a386Sopenharmony_ci 446cb93a386Sopenharmony_cistatic PyObject* brotli_Decompressor_new(PyTypeObject *type, PyObject *args, PyObject *keywds) { 447cb93a386Sopenharmony_ci brotli_Decompressor *self; 448cb93a386Sopenharmony_ci self = (brotli_Decompressor *)type->tp_alloc(type, 0); 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_ci if (self != NULL) { 451cb93a386Sopenharmony_ci self->dec = BrotliDecoderCreateInstance(0, 0, 0); 452cb93a386Sopenharmony_ci } 453cb93a386Sopenharmony_ci 454cb93a386Sopenharmony_ci return (PyObject *)self; 455cb93a386Sopenharmony_ci} 456cb93a386Sopenharmony_ci 457cb93a386Sopenharmony_cistatic int brotli_Decompressor_init(brotli_Decompressor *self, PyObject *args, PyObject *keywds) { 458cb93a386Sopenharmony_ci int ok; 459cb93a386Sopenharmony_ci 460cb93a386Sopenharmony_ci static const char *kwlist[] = {NULL}; 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_ci ok = PyArg_ParseTupleAndKeywords(args, keywds, "|:Decompressor", 463cb93a386Sopenharmony_ci const_cast<char **>(kwlist)); 464cb93a386Sopenharmony_ci if (!ok) 465cb93a386Sopenharmony_ci return -1; 466cb93a386Sopenharmony_ci if (!self->dec) 467cb93a386Sopenharmony_ci return -1; 468cb93a386Sopenharmony_ci 469cb93a386Sopenharmony_ci return 0; 470cb93a386Sopenharmony_ci} 471cb93a386Sopenharmony_ci 472cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Decompressor_process_doc, 473cb93a386Sopenharmony_ci"Process \"string\" for decompression, returning a string that contains \n" 474cb93a386Sopenharmony_ci"decompressed output data. This data should be concatenated to the output \n" 475cb93a386Sopenharmony_ci"produced by any preceding calls to the \"process()\" method. \n" 476cb93a386Sopenharmony_ci"Some or all of the input may be kept in internal buffers for later \n" 477cb93a386Sopenharmony_ci"processing, and the decompressed output data may be empty until enough input \n" 478cb93a386Sopenharmony_ci"has been accumulated.\n" 479cb93a386Sopenharmony_ci"\n" 480cb93a386Sopenharmony_ci"Signature:\n" 481cb93a386Sopenharmony_ci" decompress(string)\n" 482cb93a386Sopenharmony_ci"\n" 483cb93a386Sopenharmony_ci"Args:\n" 484cb93a386Sopenharmony_ci" string (bytes): The input data\n" 485cb93a386Sopenharmony_ci"\n" 486cb93a386Sopenharmony_ci"Returns:\n" 487cb93a386Sopenharmony_ci" The decompressed output data (bytes)\n" 488cb93a386Sopenharmony_ci"\n" 489cb93a386Sopenharmony_ci"Raises:\n" 490cb93a386Sopenharmony_ci" brotli.error: If decompression fails\n"); 491cb93a386Sopenharmony_ci 492cb93a386Sopenharmony_cistatic PyObject* brotli_Decompressor_process(brotli_Decompressor *self, PyObject *args) { 493cb93a386Sopenharmony_ci PyObject* ret = NULL; 494cb93a386Sopenharmony_ci std::vector<uint8_t> output; 495cb93a386Sopenharmony_ci Py_buffer input; 496cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ci#if PY_MAJOR_VERSION >= 3 499cb93a386Sopenharmony_ci ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "y*:process", &input); 500cb93a386Sopenharmony_ci#else 501cb93a386Sopenharmony_ci ok = (BROTLI_BOOL)PyArg_ParseTuple(args, "s*:process", &input); 502cb93a386Sopenharmony_ci#endif 503cb93a386Sopenharmony_ci 504cb93a386Sopenharmony_ci if (!ok) 505cb93a386Sopenharmony_ci return NULL; 506cb93a386Sopenharmony_ci 507cb93a386Sopenharmony_ci if (!self->dec) { 508cb93a386Sopenharmony_ci ok = BROTLI_FALSE; 509cb93a386Sopenharmony_ci goto end; 510cb93a386Sopenharmony_ci } 511cb93a386Sopenharmony_ci 512cb93a386Sopenharmony_ci ok = decompress_stream(self->dec, &output, static_cast<uint8_t*>(input.buf), input.len); 513cb93a386Sopenharmony_ci 514cb93a386Sopenharmony_ciend: 515cb93a386Sopenharmony_ci PyBuffer_Release(&input); 516cb93a386Sopenharmony_ci if (ok) { 517cb93a386Sopenharmony_ci ret = PyBytes_FromStringAndSize((char*)(output.empty() ? NULL : &output[0]), output.size()); 518cb93a386Sopenharmony_ci } else { 519cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliDecoderDecompressStream failed while processing the stream"); 520cb93a386Sopenharmony_ci } 521cb93a386Sopenharmony_ci 522cb93a386Sopenharmony_ci return ret; 523cb93a386Sopenharmony_ci} 524cb93a386Sopenharmony_ci 525cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_Decompressor_is_finished_doc, 526cb93a386Sopenharmony_ci"Checks if decoder instance reached the final state.\n" 527cb93a386Sopenharmony_ci"\n" 528cb93a386Sopenharmony_ci"Signature:\n" 529cb93a386Sopenharmony_ci" is_finished()\n" 530cb93a386Sopenharmony_ci"\n" 531cb93a386Sopenharmony_ci"Returns:\n" 532cb93a386Sopenharmony_ci" True if the decoder is in a state where it reached the end of the input\n" 533cb93a386Sopenharmony_ci" and produced all of the output\n" 534cb93a386Sopenharmony_ci" False otherwise\n" 535cb93a386Sopenharmony_ci"\n" 536cb93a386Sopenharmony_ci"Raises:\n" 537cb93a386Sopenharmony_ci" brotli.error: If decompression fails\n"); 538cb93a386Sopenharmony_ci 539cb93a386Sopenharmony_cistatic PyObject* brotli_Decompressor_is_finished(brotli_Decompressor *self) { 540cb93a386Sopenharmony_ci PyObject *ret = NULL; 541cb93a386Sopenharmony_ci std::vector<uint8_t> output; 542cb93a386Sopenharmony_ci BROTLI_BOOL ok = BROTLI_TRUE; 543cb93a386Sopenharmony_ci 544cb93a386Sopenharmony_ci if (!self->dec) { 545cb93a386Sopenharmony_ci ok = BROTLI_FALSE; 546cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliDecoderState is NULL while checking is_finished"); 547cb93a386Sopenharmony_ci goto end; 548cb93a386Sopenharmony_ci } 549cb93a386Sopenharmony_ci 550cb93a386Sopenharmony_ci if (BrotliDecoderIsFinished(self->dec)) { 551cb93a386Sopenharmony_ci Py_RETURN_TRUE; 552cb93a386Sopenharmony_ci } else { 553cb93a386Sopenharmony_ci Py_RETURN_FALSE; 554cb93a386Sopenharmony_ci } 555cb93a386Sopenharmony_ci 556cb93a386Sopenharmony_ciend: 557cb93a386Sopenharmony_ci if (ok) { 558cb93a386Sopenharmony_ci ret = PyBytes_FromStringAndSize((char*)(output.empty() ? NULL : &output[0]), output.size()); 559cb93a386Sopenharmony_ci } else { 560cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliDecoderDecompressStream failed while finishing the stream"); 561cb93a386Sopenharmony_ci } 562cb93a386Sopenharmony_ci 563cb93a386Sopenharmony_ci return ret; 564cb93a386Sopenharmony_ci} 565cb93a386Sopenharmony_ci 566cb93a386Sopenharmony_cistatic PyMemberDef brotli_Decompressor_members[] = { 567cb93a386Sopenharmony_ci {NULL} /* Sentinel */ 568cb93a386Sopenharmony_ci}; 569cb93a386Sopenharmony_ci 570cb93a386Sopenharmony_cistatic PyMethodDef brotli_Decompressor_methods[] = { 571cb93a386Sopenharmony_ci {"process", (PyCFunction)brotli_Decompressor_process, METH_VARARGS, brotli_Decompressor_process_doc}, 572cb93a386Sopenharmony_ci {"is_finished", (PyCFunction)brotli_Decompressor_is_finished, METH_NOARGS, brotli_Decompressor_is_finished_doc}, 573cb93a386Sopenharmony_ci {NULL} /* Sentinel */ 574cb93a386Sopenharmony_ci}; 575cb93a386Sopenharmony_ci 576cb93a386Sopenharmony_cistatic PyTypeObject brotli_DecompressorType = { 577cb93a386Sopenharmony_ci #if PY_MAJOR_VERSION >= 3 578cb93a386Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 579cb93a386Sopenharmony_ci #else 580cb93a386Sopenharmony_ci PyObject_HEAD_INIT(NULL) 581cb93a386Sopenharmony_ci 0, /* ob_size*/ 582cb93a386Sopenharmony_ci #endif 583cb93a386Sopenharmony_ci "brotli.Decompressor", /* tp_name */ 584cb93a386Sopenharmony_ci sizeof(brotli_Decompressor), /* tp_basicsize */ 585cb93a386Sopenharmony_ci 0, /* tp_itemsize */ 586cb93a386Sopenharmony_ci (destructor)brotli_Decompressor_dealloc, /* tp_dealloc */ 587cb93a386Sopenharmony_ci 0, /* tp_print */ 588cb93a386Sopenharmony_ci 0, /* tp_getattr */ 589cb93a386Sopenharmony_ci 0, /* tp_setattr */ 590cb93a386Sopenharmony_ci 0, /* tp_compare */ 591cb93a386Sopenharmony_ci 0, /* tp_repr */ 592cb93a386Sopenharmony_ci 0, /* tp_as_number */ 593cb93a386Sopenharmony_ci 0, /* tp_as_sequence */ 594cb93a386Sopenharmony_ci 0, /* tp_as_mapping */ 595cb93a386Sopenharmony_ci 0, /* tp_hash */ 596cb93a386Sopenharmony_ci 0, /* tp_call */ 597cb93a386Sopenharmony_ci 0, /* tp_str */ 598cb93a386Sopenharmony_ci 0, /* tp_getattro */ 599cb93a386Sopenharmony_ci 0, /* tp_setattro */ 600cb93a386Sopenharmony_ci 0, /* tp_as_buffer */ 601cb93a386Sopenharmony_ci Py_TPFLAGS_DEFAULT, /* tp_flags */ 602cb93a386Sopenharmony_ci brotli_Decompressor_doc, /* tp_doc */ 603cb93a386Sopenharmony_ci 0, /* tp_traverse */ 604cb93a386Sopenharmony_ci 0, /* tp_clear */ 605cb93a386Sopenharmony_ci 0, /* tp_richcompare */ 606cb93a386Sopenharmony_ci 0, /* tp_weaklistoffset */ 607cb93a386Sopenharmony_ci 0, /* tp_iter */ 608cb93a386Sopenharmony_ci 0, /* tp_iternext */ 609cb93a386Sopenharmony_ci brotli_Decompressor_methods, /* tp_methods */ 610cb93a386Sopenharmony_ci brotli_Decompressor_members, /* tp_members */ 611cb93a386Sopenharmony_ci 0, /* tp_getset */ 612cb93a386Sopenharmony_ci 0, /* tp_base */ 613cb93a386Sopenharmony_ci 0, /* tp_dict */ 614cb93a386Sopenharmony_ci 0, /* tp_descr_get */ 615cb93a386Sopenharmony_ci 0, /* tp_descr_set */ 616cb93a386Sopenharmony_ci 0, /* tp_dictoffset */ 617cb93a386Sopenharmony_ci (initproc)brotli_Decompressor_init, /* tp_init */ 618cb93a386Sopenharmony_ci 0, /* tp_alloc */ 619cb93a386Sopenharmony_ci brotli_Decompressor_new, /* tp_new */ 620cb93a386Sopenharmony_ci}; 621cb93a386Sopenharmony_ci 622cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_decompress__doc__, 623cb93a386Sopenharmony_ci"Decompress a compressed byte string.\n" 624cb93a386Sopenharmony_ci"\n" 625cb93a386Sopenharmony_ci"Signature:\n" 626cb93a386Sopenharmony_ci" decompress(string)\n" 627cb93a386Sopenharmony_ci"\n" 628cb93a386Sopenharmony_ci"Args:\n" 629cb93a386Sopenharmony_ci" string (bytes): The compressed input data.\n" 630cb93a386Sopenharmony_ci"\n" 631cb93a386Sopenharmony_ci"Returns:\n" 632cb93a386Sopenharmony_ci" The decompressed byte string.\n" 633cb93a386Sopenharmony_ci"\n" 634cb93a386Sopenharmony_ci"Raises:\n" 635cb93a386Sopenharmony_ci" brotli.error: If decompressor fails.\n"); 636cb93a386Sopenharmony_ci 637cb93a386Sopenharmony_cistatic PyObject* brotli_decompress(PyObject *self, PyObject *args, PyObject *keywds) { 638cb93a386Sopenharmony_ci PyObject *ret = NULL; 639cb93a386Sopenharmony_ci Py_buffer input; 640cb93a386Sopenharmony_ci const uint8_t* next_in; 641cb93a386Sopenharmony_ci size_t available_in; 642cb93a386Sopenharmony_ci int ok; 643cb93a386Sopenharmony_ci 644cb93a386Sopenharmony_ci static const char *kwlist[] = {"string", NULL}; 645cb93a386Sopenharmony_ci 646cb93a386Sopenharmony_ci#if PY_MAJOR_VERSION >= 3 647cb93a386Sopenharmony_ci ok = PyArg_ParseTupleAndKeywords(args, keywds, "y*|:decompress", 648cb93a386Sopenharmony_ci const_cast<char **>(kwlist), &input); 649cb93a386Sopenharmony_ci#else 650cb93a386Sopenharmony_ci ok = PyArg_ParseTupleAndKeywords(args, keywds, "s*|:decompress", 651cb93a386Sopenharmony_ci const_cast<char **>(kwlist), &input); 652cb93a386Sopenharmony_ci#endif 653cb93a386Sopenharmony_ci 654cb93a386Sopenharmony_ci if (!ok) 655cb93a386Sopenharmony_ci return NULL; 656cb93a386Sopenharmony_ci 657cb93a386Sopenharmony_ci std::vector<uint8_t> output; 658cb93a386Sopenharmony_ci 659cb93a386Sopenharmony_ci /* >>> Pure C block; release python GIL. */ 660cb93a386Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 661cb93a386Sopenharmony_ci 662cb93a386Sopenharmony_ci BrotliDecoderState* state = BrotliDecoderCreateInstance(0, 0, 0); 663cb93a386Sopenharmony_ci 664cb93a386Sopenharmony_ci BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; 665cb93a386Sopenharmony_ci next_in = static_cast<uint8_t*>(input.buf); 666cb93a386Sopenharmony_ci available_in = input.len; 667cb93a386Sopenharmony_ci while (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { 668cb93a386Sopenharmony_ci size_t available_out = 0; 669cb93a386Sopenharmony_ci result = BrotliDecoderDecompressStream(state, &available_in, &next_in, 670cb93a386Sopenharmony_ci &available_out, 0, 0); 671cb93a386Sopenharmony_ci const uint8_t* next_out = BrotliDecoderTakeOutput(state, &available_out); 672cb93a386Sopenharmony_ci if (available_out != 0) 673cb93a386Sopenharmony_ci output.insert(output.end(), next_out, next_out + available_out); 674cb93a386Sopenharmony_ci } 675cb93a386Sopenharmony_ci ok = result == BROTLI_DECODER_RESULT_SUCCESS && !available_in; 676cb93a386Sopenharmony_ci BrotliDecoderDestroyInstance(state); 677cb93a386Sopenharmony_ci 678cb93a386Sopenharmony_ci Py_END_ALLOW_THREADS 679cb93a386Sopenharmony_ci /* <<< Pure C block end. Python GIL reacquired. */ 680cb93a386Sopenharmony_ci 681cb93a386Sopenharmony_ci PyBuffer_Release(&input); 682cb93a386Sopenharmony_ci if (ok) { 683cb93a386Sopenharmony_ci ret = PyBytes_FromStringAndSize((char*)(output.size() ? &output[0] : NULL), output.size()); 684cb93a386Sopenharmony_ci } else { 685cb93a386Sopenharmony_ci PyErr_SetString(BrotliError, "BrotliDecompress failed"); 686cb93a386Sopenharmony_ci } 687cb93a386Sopenharmony_ci 688cb93a386Sopenharmony_ci return ret; 689cb93a386Sopenharmony_ci} 690cb93a386Sopenharmony_ci 691cb93a386Sopenharmony_cistatic PyMethodDef brotli_methods[] = { 692cb93a386Sopenharmony_ci {"decompress", (PyCFunction)brotli_decompress, METH_VARARGS | METH_KEYWORDS, brotli_decompress__doc__}, 693cb93a386Sopenharmony_ci {NULL, NULL, 0, NULL} 694cb93a386Sopenharmony_ci}; 695cb93a386Sopenharmony_ci 696cb93a386Sopenharmony_ciPyDoc_STRVAR(brotli_doc, "Implementation module for the Brotli library."); 697cb93a386Sopenharmony_ci 698cb93a386Sopenharmony_ci#if PY_MAJOR_VERSION >= 3 699cb93a386Sopenharmony_ci#define INIT_BROTLI PyInit__brotli 700cb93a386Sopenharmony_ci#define CREATE_BROTLI PyModule_Create(&brotli_module) 701cb93a386Sopenharmony_ci#define RETURN_BROTLI return m 702cb93a386Sopenharmony_ci#define RETURN_NULL return NULL 703cb93a386Sopenharmony_ci 704cb93a386Sopenharmony_cistatic struct PyModuleDef brotli_module = { 705cb93a386Sopenharmony_ci PyModuleDef_HEAD_INIT, 706cb93a386Sopenharmony_ci "_brotli", /* m_name */ 707cb93a386Sopenharmony_ci brotli_doc, /* m_doc */ 708cb93a386Sopenharmony_ci 0, /* m_size */ 709cb93a386Sopenharmony_ci brotli_methods, /* m_methods */ 710cb93a386Sopenharmony_ci NULL, /* m_reload */ 711cb93a386Sopenharmony_ci NULL, /* m_traverse */ 712cb93a386Sopenharmony_ci NULL, /* m_clear */ 713cb93a386Sopenharmony_ci NULL /* m_free */ 714cb93a386Sopenharmony_ci}; 715cb93a386Sopenharmony_ci#else 716cb93a386Sopenharmony_ci#define INIT_BROTLI init_brotli 717cb93a386Sopenharmony_ci#define CREATE_BROTLI Py_InitModule3("_brotli", brotli_methods, brotli_doc) 718cb93a386Sopenharmony_ci#define RETURN_BROTLI return 719cb93a386Sopenharmony_ci#define RETURN_NULL return 720cb93a386Sopenharmony_ci#endif 721cb93a386Sopenharmony_ci 722cb93a386Sopenharmony_ciPyMODINIT_FUNC INIT_BROTLI(void) { 723cb93a386Sopenharmony_ci PyObject *m = CREATE_BROTLI; 724cb93a386Sopenharmony_ci 725cb93a386Sopenharmony_ci BrotliError = PyErr_NewException((char*) "brotli.error", NULL, NULL); 726cb93a386Sopenharmony_ci if (BrotliError != NULL) { 727cb93a386Sopenharmony_ci Py_INCREF(BrotliError); 728cb93a386Sopenharmony_ci PyModule_AddObject(m, "error", BrotliError); 729cb93a386Sopenharmony_ci } 730cb93a386Sopenharmony_ci 731cb93a386Sopenharmony_ci if (PyType_Ready(&brotli_CompressorType) < 0) { 732cb93a386Sopenharmony_ci RETURN_NULL; 733cb93a386Sopenharmony_ci } 734cb93a386Sopenharmony_ci Py_INCREF(&brotli_CompressorType); 735cb93a386Sopenharmony_ci PyModule_AddObject(m, "Compressor", (PyObject *)&brotli_CompressorType); 736cb93a386Sopenharmony_ci 737cb93a386Sopenharmony_ci if (PyType_Ready(&brotli_DecompressorType) < 0) { 738cb93a386Sopenharmony_ci RETURN_NULL; 739cb93a386Sopenharmony_ci } 740cb93a386Sopenharmony_ci Py_INCREF(&brotli_DecompressorType); 741cb93a386Sopenharmony_ci PyModule_AddObject(m, "Decompressor", (PyObject *)&brotli_DecompressorType); 742cb93a386Sopenharmony_ci 743cb93a386Sopenharmony_ci PyModule_AddIntConstant(m, "MODE_GENERIC", (int) BROTLI_MODE_GENERIC); 744cb93a386Sopenharmony_ci PyModule_AddIntConstant(m, "MODE_TEXT", (int) BROTLI_MODE_TEXT); 745cb93a386Sopenharmony_ci PyModule_AddIntConstant(m, "MODE_FONT", (int) BROTLI_MODE_FONT); 746cb93a386Sopenharmony_ci 747cb93a386Sopenharmony_ci char version[16]; 748cb93a386Sopenharmony_ci snprintf(version, sizeof(version), "%d.%d.%d", 749cb93a386Sopenharmony_ci BROTLI_VERSION >> 24, (BROTLI_VERSION >> 12) & 0xFFF, BROTLI_VERSION & 0xFFF); 750cb93a386Sopenharmony_ci PyModule_AddStringConstant(m, "__version__", version); 751cb93a386Sopenharmony_ci 752cb93a386Sopenharmony_ci RETURN_BROTLI; 753cb93a386Sopenharmony_ci} 754