17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * multibytecodec.c: Common Multibyte Codec Implementation 37db96d56Sopenharmony_ci * 47db96d56Sopenharmony_ci * Written by Hye-Shik Chang <perky@FreeBSD.org> 57db96d56Sopenharmony_ci */ 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 87db96d56Sopenharmony_ci#include "Python.h" 97db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 107db96d56Sopenharmony_ci#include "multibytecodec.h" 117db96d56Sopenharmony_ci#include "clinic/multibytecodec.c.h" 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci#define MODULE_NAME "_multibytecodec" 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_citypedef struct { 167db96d56Sopenharmony_ci PyTypeObject *encoder_type; 177db96d56Sopenharmony_ci PyTypeObject *decoder_type; 187db96d56Sopenharmony_ci PyTypeObject *reader_type; 197db96d56Sopenharmony_ci PyTypeObject *writer_type; 207db96d56Sopenharmony_ci PyTypeObject *multibytecodec_type; 217db96d56Sopenharmony_ci PyObject *str_write; 227db96d56Sopenharmony_ci} _multibytecodec_state; 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_cistatic _multibytecodec_state * 257db96d56Sopenharmony_ci_multibytecodec_get_state(PyObject *module) 267db96d56Sopenharmony_ci{ 277db96d56Sopenharmony_ci _multibytecodec_state *state = PyModule_GetState(module); 287db96d56Sopenharmony_ci assert(state != NULL); 297db96d56Sopenharmony_ci return state; 307db96d56Sopenharmony_ci} 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_cistatic struct PyModuleDef _multibytecodecmodule; 337db96d56Sopenharmony_cistatic _multibytecodec_state * 347db96d56Sopenharmony_ci_multibyte_codec_find_state_by_type(PyTypeObject *type) 357db96d56Sopenharmony_ci{ 367db96d56Sopenharmony_ci PyObject *module = PyType_GetModuleByDef(type, &_multibytecodecmodule); 377db96d56Sopenharmony_ci assert(module != NULL); 387db96d56Sopenharmony_ci return _multibytecodec_get_state(module); 397db96d56Sopenharmony_ci} 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci#define clinic_get_state() _multibyte_codec_find_state_by_type(type) 427db96d56Sopenharmony_ci/*[clinic input] 437db96d56Sopenharmony_cimodule _multibytecodec 447db96d56Sopenharmony_ciclass _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "clinic_get_state()->multibytecodec_type" 457db96d56Sopenharmony_ciclass _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "clinic_get_state()->encoder_type" 467db96d56Sopenharmony_ciclass _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "clinic_get_state()->decoder_type" 477db96d56Sopenharmony_ciclass _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "clinic_get_state()->reader_type" 487db96d56Sopenharmony_ciclass _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "clinic_get_state()->writer_type" 497db96d56Sopenharmony_ci[clinic start generated code]*/ 507db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=305a76dfdd24b99c]*/ 517db96d56Sopenharmony_ci#undef clinic_get_state 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_citypedef struct { 547db96d56Sopenharmony_ci PyObject *inobj; 557db96d56Sopenharmony_ci Py_ssize_t inpos, inlen; 567db96d56Sopenharmony_ci unsigned char *outbuf, *outbuf_end; 577db96d56Sopenharmony_ci PyObject *excobj, *outobj; 587db96d56Sopenharmony_ci} MultibyteEncodeBuffer; 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_citypedef struct { 617db96d56Sopenharmony_ci const unsigned char *inbuf, *inbuf_top, *inbuf_end; 627db96d56Sopenharmony_ci PyObject *excobj; 637db96d56Sopenharmony_ci _PyUnicodeWriter writer; 647db96d56Sopenharmony_ci} MultibyteDecodeBuffer; 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_cistatic char *incnewkwarglist[] = {"errors", NULL}; 677db96d56Sopenharmony_cistatic char *streamkwarglist[] = {"stream", "errors", NULL}; 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_cistatic PyObject *multibytecodec_encode(MultibyteCodec *, 707db96d56Sopenharmony_ci MultibyteCodec_State *, PyObject *, Py_ssize_t *, 717db96d56Sopenharmony_ci PyObject *, int); 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci#define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */ 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_cistatic PyObject * 767db96d56Sopenharmony_cimake_tuple(PyObject *object, Py_ssize_t len) 777db96d56Sopenharmony_ci{ 787db96d56Sopenharmony_ci PyObject *v, *w; 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci if (object == NULL) 817db96d56Sopenharmony_ci return NULL; 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci v = PyTuple_New(2); 847db96d56Sopenharmony_ci if (v == NULL) { 857db96d56Sopenharmony_ci Py_DECREF(object); 867db96d56Sopenharmony_ci return NULL; 877db96d56Sopenharmony_ci } 887db96d56Sopenharmony_ci PyTuple_SET_ITEM(v, 0, object); 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci w = PyLong_FromSsize_t(len); 917db96d56Sopenharmony_ci if (w == NULL) { 927db96d56Sopenharmony_ci Py_DECREF(v); 937db96d56Sopenharmony_ci return NULL; 947db96d56Sopenharmony_ci } 957db96d56Sopenharmony_ci PyTuple_SET_ITEM(v, 1, w); 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci return v; 987db96d56Sopenharmony_ci} 997db96d56Sopenharmony_ci 1007db96d56Sopenharmony_cistatic PyObject * 1017db96d56Sopenharmony_ciinternal_error_callback(const char *errors) 1027db96d56Sopenharmony_ci{ 1037db96d56Sopenharmony_ci if (errors == NULL || strcmp(errors, "strict") == 0) 1047db96d56Sopenharmony_ci return ERROR_STRICT; 1057db96d56Sopenharmony_ci else if (strcmp(errors, "ignore") == 0) 1067db96d56Sopenharmony_ci return ERROR_IGNORE; 1077db96d56Sopenharmony_ci else if (strcmp(errors, "replace") == 0) 1087db96d56Sopenharmony_ci return ERROR_REPLACE; 1097db96d56Sopenharmony_ci else 1107db96d56Sopenharmony_ci return PyUnicode_FromString(errors); 1117db96d56Sopenharmony_ci} 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_cistatic PyObject * 1147db96d56Sopenharmony_cicall_error_callback(PyObject *errors, PyObject *exc) 1157db96d56Sopenharmony_ci{ 1167db96d56Sopenharmony_ci PyObject *cb, *r; 1177db96d56Sopenharmony_ci const char *str; 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci assert(PyUnicode_Check(errors)); 1207db96d56Sopenharmony_ci str = PyUnicode_AsUTF8(errors); 1217db96d56Sopenharmony_ci if (str == NULL) 1227db96d56Sopenharmony_ci return NULL; 1237db96d56Sopenharmony_ci cb = PyCodec_LookupError(str); 1247db96d56Sopenharmony_ci if (cb == NULL) 1257db96d56Sopenharmony_ci return NULL; 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci r = PyObject_CallOneArg(cb, exc); 1287db96d56Sopenharmony_ci Py_DECREF(cb); 1297db96d56Sopenharmony_ci return r; 1307db96d56Sopenharmony_ci} 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_cistatic PyObject * 1337db96d56Sopenharmony_cicodecctx_errors_get(MultibyteStatefulCodecContext *self, void *Py_UNUSED(ignored)) 1347db96d56Sopenharmony_ci{ 1357db96d56Sopenharmony_ci const char *errors; 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci if (self->errors == ERROR_STRICT) 1387db96d56Sopenharmony_ci errors = "strict"; 1397db96d56Sopenharmony_ci else if (self->errors == ERROR_IGNORE) 1407db96d56Sopenharmony_ci errors = "ignore"; 1417db96d56Sopenharmony_ci else if (self->errors == ERROR_REPLACE) 1427db96d56Sopenharmony_ci errors = "replace"; 1437db96d56Sopenharmony_ci else { 1447db96d56Sopenharmony_ci Py_INCREF(self->errors); 1457db96d56Sopenharmony_ci return self->errors; 1467db96d56Sopenharmony_ci } 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci return PyUnicode_FromString(errors); 1497db96d56Sopenharmony_ci} 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_cistatic int 1527db96d56Sopenharmony_cicodecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value, 1537db96d56Sopenharmony_ci void *closure) 1547db96d56Sopenharmony_ci{ 1557db96d56Sopenharmony_ci PyObject *cb; 1567db96d56Sopenharmony_ci const char *str; 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci if (value == NULL) { 1597db96d56Sopenharmony_ci PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); 1607db96d56Sopenharmony_ci return -1; 1617db96d56Sopenharmony_ci } 1627db96d56Sopenharmony_ci if (!PyUnicode_Check(value)) { 1637db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "errors must be a string"); 1647db96d56Sopenharmony_ci return -1; 1657db96d56Sopenharmony_ci } 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ci str = PyUnicode_AsUTF8(value); 1687db96d56Sopenharmony_ci if (str == NULL) 1697db96d56Sopenharmony_ci return -1; 1707db96d56Sopenharmony_ci 1717db96d56Sopenharmony_ci cb = internal_error_callback(str); 1727db96d56Sopenharmony_ci if (cb == NULL) 1737db96d56Sopenharmony_ci return -1; 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_ci ERROR_DECREF(self->errors); 1767db96d56Sopenharmony_ci self->errors = cb; 1777db96d56Sopenharmony_ci return 0; 1787db96d56Sopenharmony_ci} 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci/* This getset handlers list is used by all the stateful codec objects */ 1817db96d56Sopenharmony_cistatic PyGetSetDef codecctx_getsets[] = { 1827db96d56Sopenharmony_ci {"errors", (getter)codecctx_errors_get, 1837db96d56Sopenharmony_ci (setter)codecctx_errors_set, 1847db96d56Sopenharmony_ci PyDoc_STR("how to treat errors")}, 1857db96d56Sopenharmony_ci {NULL,} 1867db96d56Sopenharmony_ci}; 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_cistatic int 1897db96d56Sopenharmony_ciexpand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) 1907db96d56Sopenharmony_ci{ 1917db96d56Sopenharmony_ci Py_ssize_t orgpos, orgsize, incsize; 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci orgpos = (Py_ssize_t)((char *)buf->outbuf - 1947db96d56Sopenharmony_ci PyBytes_AS_STRING(buf->outobj)); 1957db96d56Sopenharmony_ci orgsize = PyBytes_GET_SIZE(buf->outobj); 1967db96d56Sopenharmony_ci incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci if (orgsize > PY_SSIZE_T_MAX - incsize) { 1997db96d56Sopenharmony_ci PyErr_NoMemory(); 2007db96d56Sopenharmony_ci return -1; 2017db96d56Sopenharmony_ci } 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) 2047db96d56Sopenharmony_ci return -1; 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ci buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos; 2077db96d56Sopenharmony_ci buf->outbuf_end = (unsigned char *)PyBytes_AS_STRING(buf->outobj) 2087db96d56Sopenharmony_ci + PyBytes_GET_SIZE(buf->outobj); 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci return 0; 2117db96d56Sopenharmony_ci} 2127db96d56Sopenharmony_ci#define REQUIRE_ENCODEBUFFER(buf, s) do { \ 2137db96d56Sopenharmony_ci if ((s) < 0 || (s) > (buf)->outbuf_end - (buf)->outbuf) \ 2147db96d56Sopenharmony_ci if (expand_encodebuffer(buf, s) == -1) \ 2157db96d56Sopenharmony_ci goto errorexit; \ 2167db96d56Sopenharmony_ci} while(0) 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci/** 2207db96d56Sopenharmony_ci * MultibyteCodec object 2217db96d56Sopenharmony_ci */ 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_cistatic int 2247db96d56Sopenharmony_cimultibytecodec_encerror(MultibyteCodec *codec, 2257db96d56Sopenharmony_ci MultibyteCodec_State *state, 2267db96d56Sopenharmony_ci MultibyteEncodeBuffer *buf, 2277db96d56Sopenharmony_ci PyObject *errors, Py_ssize_t e) 2287db96d56Sopenharmony_ci{ 2297db96d56Sopenharmony_ci PyObject *retobj = NULL, *retstr = NULL, *tobj; 2307db96d56Sopenharmony_ci Py_ssize_t retstrsize, newpos; 2317db96d56Sopenharmony_ci Py_ssize_t esize, start, end; 2327db96d56Sopenharmony_ci const char *reason; 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci if (e > 0) { 2357db96d56Sopenharmony_ci reason = "illegal multibyte sequence"; 2367db96d56Sopenharmony_ci esize = e; 2377db96d56Sopenharmony_ci } 2387db96d56Sopenharmony_ci else { 2397db96d56Sopenharmony_ci switch (e) { 2407db96d56Sopenharmony_ci case MBERR_TOOSMALL: 2417db96d56Sopenharmony_ci REQUIRE_ENCODEBUFFER(buf, -1); 2427db96d56Sopenharmony_ci return 0; /* retry it */ 2437db96d56Sopenharmony_ci case MBERR_TOOFEW: 2447db96d56Sopenharmony_ci reason = "incomplete multibyte sequence"; 2457db96d56Sopenharmony_ci esize = (Py_ssize_t)buf->inpos; 2467db96d56Sopenharmony_ci break; 2477db96d56Sopenharmony_ci case MBERR_INTERNAL: 2487db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 2497db96d56Sopenharmony_ci "internal codec error"); 2507db96d56Sopenharmony_ci return -1; 2517db96d56Sopenharmony_ci default: 2527db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 2537db96d56Sopenharmony_ci "unknown runtime error"); 2547db96d56Sopenharmony_ci return -1; 2557db96d56Sopenharmony_ci } 2567db96d56Sopenharmony_ci } 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ci if (errors == ERROR_REPLACE) { 2597db96d56Sopenharmony_ci PyObject *replchar; 2607db96d56Sopenharmony_ci Py_ssize_t r; 2617db96d56Sopenharmony_ci Py_ssize_t inpos; 2627db96d56Sopenharmony_ci int kind; 2637db96d56Sopenharmony_ci const void *data; 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci replchar = PyUnicode_FromOrdinal('?'); 2667db96d56Sopenharmony_ci if (replchar == NULL) 2677db96d56Sopenharmony_ci goto errorexit; 2687db96d56Sopenharmony_ci kind = PyUnicode_KIND(replchar); 2697db96d56Sopenharmony_ci data = PyUnicode_DATA(replchar); 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci inpos = 0; 2727db96d56Sopenharmony_ci for (;;) { 2737db96d56Sopenharmony_ci Py_ssize_t outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci r = codec->encode(state, codec->config, 2767db96d56Sopenharmony_ci kind, data, &inpos, 1, 2777db96d56Sopenharmony_ci &buf->outbuf, outleft, 0); 2787db96d56Sopenharmony_ci if (r == MBERR_TOOSMALL) { 2797db96d56Sopenharmony_ci REQUIRE_ENCODEBUFFER(buf, -1); 2807db96d56Sopenharmony_ci continue; 2817db96d56Sopenharmony_ci } 2827db96d56Sopenharmony_ci else 2837db96d56Sopenharmony_ci break; 2847db96d56Sopenharmony_ci } 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ci Py_DECREF(replchar); 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci if (r != 0) { 2897db96d56Sopenharmony_ci REQUIRE_ENCODEBUFFER(buf, 1); 2907db96d56Sopenharmony_ci *buf->outbuf++ = '?'; 2917db96d56Sopenharmony_ci } 2927db96d56Sopenharmony_ci } 2937db96d56Sopenharmony_ci if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { 2947db96d56Sopenharmony_ci buf->inpos += esize; 2957db96d56Sopenharmony_ci return 0; 2967db96d56Sopenharmony_ci } 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci start = (Py_ssize_t)buf->inpos; 2997db96d56Sopenharmony_ci end = start + esize; 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci /* use cached exception object if available */ 3027db96d56Sopenharmony_ci if (buf->excobj == NULL) { 3037db96d56Sopenharmony_ci buf->excobj = PyObject_CallFunction(PyExc_UnicodeEncodeError, 3047db96d56Sopenharmony_ci "sOnns", 3057db96d56Sopenharmony_ci codec->encoding, buf->inobj, 3067db96d56Sopenharmony_ci start, end, reason); 3077db96d56Sopenharmony_ci if (buf->excobj == NULL) 3087db96d56Sopenharmony_ci goto errorexit; 3097db96d56Sopenharmony_ci } 3107db96d56Sopenharmony_ci else 3117db96d56Sopenharmony_ci if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 || 3127db96d56Sopenharmony_ci PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 || 3137db96d56Sopenharmony_ci PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0) 3147db96d56Sopenharmony_ci goto errorexit; 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ci if (errors == ERROR_STRICT) { 3177db96d56Sopenharmony_ci PyCodec_StrictErrors(buf->excobj); 3187db96d56Sopenharmony_ci goto errorexit; 3197db96d56Sopenharmony_ci } 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_ci retobj = call_error_callback(errors, buf->excobj); 3227db96d56Sopenharmony_ci if (retobj == NULL) 3237db96d56Sopenharmony_ci goto errorexit; 3247db96d56Sopenharmony_ci 3257db96d56Sopenharmony_ci if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || 3267db96d56Sopenharmony_ci (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) || 3277db96d56Sopenharmony_ci !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { 3287db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 3297db96d56Sopenharmony_ci "encoding error handler must return " 3307db96d56Sopenharmony_ci "(str, int) tuple"); 3317db96d56Sopenharmony_ci goto errorexit; 3327db96d56Sopenharmony_ci } 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci if (PyUnicode_Check(tobj)) { 3357db96d56Sopenharmony_ci Py_ssize_t inpos; 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci retstr = multibytecodec_encode(codec, state, tobj, 3387db96d56Sopenharmony_ci &inpos, ERROR_STRICT, 3397db96d56Sopenharmony_ci MBENC_FLUSH); 3407db96d56Sopenharmony_ci if (retstr == NULL) 3417db96d56Sopenharmony_ci goto errorexit; 3427db96d56Sopenharmony_ci } 3437db96d56Sopenharmony_ci else { 3447db96d56Sopenharmony_ci Py_INCREF(tobj); 3457db96d56Sopenharmony_ci retstr = tobj; 3467db96d56Sopenharmony_ci } 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci assert(PyBytes_Check(retstr)); 3497db96d56Sopenharmony_ci retstrsize = PyBytes_GET_SIZE(retstr); 3507db96d56Sopenharmony_ci if (retstrsize > 0) { 3517db96d56Sopenharmony_ci REQUIRE_ENCODEBUFFER(buf, retstrsize); 3527db96d56Sopenharmony_ci memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); 3537db96d56Sopenharmony_ci buf->outbuf += retstrsize; 3547db96d56Sopenharmony_ci } 3557db96d56Sopenharmony_ci 3567db96d56Sopenharmony_ci newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); 3577db96d56Sopenharmony_ci if (newpos < 0 && !PyErr_Occurred()) 3587db96d56Sopenharmony_ci newpos += (Py_ssize_t)buf->inlen; 3597db96d56Sopenharmony_ci if (newpos < 0 || newpos > buf->inlen) { 3607db96d56Sopenharmony_ci PyErr_Clear(); 3617db96d56Sopenharmony_ci PyErr_Format(PyExc_IndexError, 3627db96d56Sopenharmony_ci "position %zd from error handler out of bounds", 3637db96d56Sopenharmony_ci newpos); 3647db96d56Sopenharmony_ci goto errorexit; 3657db96d56Sopenharmony_ci } 3667db96d56Sopenharmony_ci buf->inpos = newpos; 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci Py_DECREF(retobj); 3697db96d56Sopenharmony_ci Py_DECREF(retstr); 3707db96d56Sopenharmony_ci return 0; 3717db96d56Sopenharmony_ci 3727db96d56Sopenharmony_cierrorexit: 3737db96d56Sopenharmony_ci Py_XDECREF(retobj); 3747db96d56Sopenharmony_ci Py_XDECREF(retstr); 3757db96d56Sopenharmony_ci return -1; 3767db96d56Sopenharmony_ci} 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_cistatic int 3797db96d56Sopenharmony_cimultibytecodec_decerror(MultibyteCodec *codec, 3807db96d56Sopenharmony_ci MultibyteCodec_State *state, 3817db96d56Sopenharmony_ci MultibyteDecodeBuffer *buf, 3827db96d56Sopenharmony_ci PyObject *errors, Py_ssize_t e) 3837db96d56Sopenharmony_ci{ 3847db96d56Sopenharmony_ci PyObject *retobj = NULL, *retuni = NULL; 3857db96d56Sopenharmony_ci Py_ssize_t newpos; 3867db96d56Sopenharmony_ci const char *reason; 3877db96d56Sopenharmony_ci Py_ssize_t esize, start, end; 3887db96d56Sopenharmony_ci 3897db96d56Sopenharmony_ci if (e > 0) { 3907db96d56Sopenharmony_ci reason = "illegal multibyte sequence"; 3917db96d56Sopenharmony_ci esize = e; 3927db96d56Sopenharmony_ci } 3937db96d56Sopenharmony_ci else { 3947db96d56Sopenharmony_ci switch (e) { 3957db96d56Sopenharmony_ci case MBERR_TOOSMALL: 3967db96d56Sopenharmony_ci return 0; /* retry it */ 3977db96d56Sopenharmony_ci case MBERR_TOOFEW: 3987db96d56Sopenharmony_ci reason = "incomplete multibyte sequence"; 3997db96d56Sopenharmony_ci esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 4007db96d56Sopenharmony_ci break; 4017db96d56Sopenharmony_ci case MBERR_INTERNAL: 4027db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 4037db96d56Sopenharmony_ci "internal codec error"); 4047db96d56Sopenharmony_ci return -1; 4057db96d56Sopenharmony_ci case MBERR_EXCEPTION: 4067db96d56Sopenharmony_ci return -1; 4077db96d56Sopenharmony_ci default: 4087db96d56Sopenharmony_ci PyErr_SetString(PyExc_RuntimeError, 4097db96d56Sopenharmony_ci "unknown runtime error"); 4107db96d56Sopenharmony_ci return -1; 4117db96d56Sopenharmony_ci } 4127db96d56Sopenharmony_ci } 4137db96d56Sopenharmony_ci 4147db96d56Sopenharmony_ci if (errors == ERROR_REPLACE) { 4157db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteChar(&buf->writer, 4167db96d56Sopenharmony_ci Py_UNICODE_REPLACEMENT_CHARACTER) < 0) 4177db96d56Sopenharmony_ci goto errorexit; 4187db96d56Sopenharmony_ci } 4197db96d56Sopenharmony_ci if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { 4207db96d56Sopenharmony_ci buf->inbuf += esize; 4217db96d56Sopenharmony_ci return 0; 4227db96d56Sopenharmony_ci } 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top); 4257db96d56Sopenharmony_ci end = start + esize; 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci /* use cached exception object if available */ 4287db96d56Sopenharmony_ci if (buf->excobj == NULL) { 4297db96d56Sopenharmony_ci buf->excobj = PyUnicodeDecodeError_Create(codec->encoding, 4307db96d56Sopenharmony_ci (const char *)buf->inbuf_top, 4317db96d56Sopenharmony_ci (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top), 4327db96d56Sopenharmony_ci start, end, reason); 4337db96d56Sopenharmony_ci if (buf->excobj == NULL) 4347db96d56Sopenharmony_ci goto errorexit; 4357db96d56Sopenharmony_ci } 4367db96d56Sopenharmony_ci else 4377db96d56Sopenharmony_ci if (PyUnicodeDecodeError_SetStart(buf->excobj, start) || 4387db96d56Sopenharmony_ci PyUnicodeDecodeError_SetEnd(buf->excobj, end) || 4397db96d56Sopenharmony_ci PyUnicodeDecodeError_SetReason(buf->excobj, reason)) 4407db96d56Sopenharmony_ci goto errorexit; 4417db96d56Sopenharmony_ci 4427db96d56Sopenharmony_ci if (errors == ERROR_STRICT) { 4437db96d56Sopenharmony_ci PyCodec_StrictErrors(buf->excobj); 4447db96d56Sopenharmony_ci goto errorexit; 4457db96d56Sopenharmony_ci } 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci retobj = call_error_callback(errors, buf->excobj); 4487db96d56Sopenharmony_ci if (retobj == NULL) 4497db96d56Sopenharmony_ci goto errorexit; 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_ci if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || 4527db96d56Sopenharmony_ci !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || 4537db96d56Sopenharmony_ci !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { 4547db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 4557db96d56Sopenharmony_ci "decoding error handler must return " 4567db96d56Sopenharmony_ci "(str, int) tuple"); 4577db96d56Sopenharmony_ci goto errorexit; 4587db96d56Sopenharmony_ci } 4597db96d56Sopenharmony_ci 4607db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteStr(&buf->writer, retuni) < 0) 4617db96d56Sopenharmony_ci goto errorexit; 4627db96d56Sopenharmony_ci 4637db96d56Sopenharmony_ci newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); 4647db96d56Sopenharmony_ci if (newpos < 0 && !PyErr_Occurred()) 4657db96d56Sopenharmony_ci newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); 4667db96d56Sopenharmony_ci if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { 4677db96d56Sopenharmony_ci PyErr_Clear(); 4687db96d56Sopenharmony_ci PyErr_Format(PyExc_IndexError, 4697db96d56Sopenharmony_ci "position %zd from error handler out of bounds", 4707db96d56Sopenharmony_ci newpos); 4717db96d56Sopenharmony_ci goto errorexit; 4727db96d56Sopenharmony_ci } 4737db96d56Sopenharmony_ci buf->inbuf = buf->inbuf_top + newpos; 4747db96d56Sopenharmony_ci Py_DECREF(retobj); 4757db96d56Sopenharmony_ci return 0; 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_cierrorexit: 4787db96d56Sopenharmony_ci Py_XDECREF(retobj); 4797db96d56Sopenharmony_ci return -1; 4807db96d56Sopenharmony_ci} 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_cistatic PyObject * 4837db96d56Sopenharmony_cimultibytecodec_encode(MultibyteCodec *codec, 4847db96d56Sopenharmony_ci MultibyteCodec_State *state, 4857db96d56Sopenharmony_ci PyObject *text, Py_ssize_t *inpos_t, 4867db96d56Sopenharmony_ci PyObject *errors, int flags) 4877db96d56Sopenharmony_ci{ 4887db96d56Sopenharmony_ci MultibyteEncodeBuffer buf; 4897db96d56Sopenharmony_ci Py_ssize_t finalsize, r = 0; 4907db96d56Sopenharmony_ci Py_ssize_t datalen; 4917db96d56Sopenharmony_ci int kind; 4927db96d56Sopenharmony_ci const void *data; 4937db96d56Sopenharmony_ci 4947db96d56Sopenharmony_ci if (PyUnicode_READY(text) < 0) 4957db96d56Sopenharmony_ci return NULL; 4967db96d56Sopenharmony_ci datalen = PyUnicode_GET_LENGTH(text); 4977db96d56Sopenharmony_ci 4987db96d56Sopenharmony_ci if (datalen == 0 && !(flags & MBENC_RESET)) 4997db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(NULL, 0); 5007db96d56Sopenharmony_ci 5017db96d56Sopenharmony_ci buf.excobj = NULL; 5027db96d56Sopenharmony_ci buf.outobj = NULL; 5037db96d56Sopenharmony_ci buf.inobj = text; /* borrowed reference */ 5047db96d56Sopenharmony_ci buf.inpos = 0; 5057db96d56Sopenharmony_ci buf.inlen = datalen; 5067db96d56Sopenharmony_ci kind = PyUnicode_KIND(buf.inobj); 5077db96d56Sopenharmony_ci data = PyUnicode_DATA(buf.inobj); 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci if (datalen > (PY_SSIZE_T_MAX - 16) / 2) { 5107db96d56Sopenharmony_ci PyErr_NoMemory(); 5117db96d56Sopenharmony_ci goto errorexit; 5127db96d56Sopenharmony_ci } 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16); 5157db96d56Sopenharmony_ci if (buf.outobj == NULL) 5167db96d56Sopenharmony_ci goto errorexit; 5177db96d56Sopenharmony_ci buf.outbuf = (unsigned char *)PyBytes_AS_STRING(buf.outobj); 5187db96d56Sopenharmony_ci buf.outbuf_end = buf.outbuf + PyBytes_GET_SIZE(buf.outobj); 5197db96d56Sopenharmony_ci 5207db96d56Sopenharmony_ci while (buf.inpos < buf.inlen) { 5217db96d56Sopenharmony_ci /* we don't reuse inleft and outleft here. 5227db96d56Sopenharmony_ci * error callbacks can relocate the cursor anywhere on buffer*/ 5237db96d56Sopenharmony_ci Py_ssize_t outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_ci r = codec->encode(state, codec->config, 5267db96d56Sopenharmony_ci kind, data, 5277db96d56Sopenharmony_ci &buf.inpos, buf.inlen, 5287db96d56Sopenharmony_ci &buf.outbuf, outleft, flags); 5297db96d56Sopenharmony_ci if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) 5307db96d56Sopenharmony_ci break; 5317db96d56Sopenharmony_ci else if (multibytecodec_encerror(codec, state, &buf, errors,r)) 5327db96d56Sopenharmony_ci goto errorexit; 5337db96d56Sopenharmony_ci else if (r == MBERR_TOOFEW) 5347db96d56Sopenharmony_ci break; 5357db96d56Sopenharmony_ci } 5367db96d56Sopenharmony_ci 5377db96d56Sopenharmony_ci if (codec->encreset != NULL && (flags & MBENC_RESET)) 5387db96d56Sopenharmony_ci for (;;) { 5397db96d56Sopenharmony_ci Py_ssize_t outleft; 5407db96d56Sopenharmony_ci 5417db96d56Sopenharmony_ci outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); 5427db96d56Sopenharmony_ci r = codec->encreset(state, codec->config, &buf.outbuf, 5437db96d56Sopenharmony_ci outleft); 5447db96d56Sopenharmony_ci if (r == 0) 5457db96d56Sopenharmony_ci break; 5467db96d56Sopenharmony_ci else if (multibytecodec_encerror(codec, state, 5477db96d56Sopenharmony_ci &buf, errors, r)) 5487db96d56Sopenharmony_ci goto errorexit; 5497db96d56Sopenharmony_ci } 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci finalsize = (Py_ssize_t)((char *)buf.outbuf - 5527db96d56Sopenharmony_ci PyBytes_AS_STRING(buf.outobj)); 5537db96d56Sopenharmony_ci 5547db96d56Sopenharmony_ci if (finalsize != PyBytes_GET_SIZE(buf.outobj)) 5557db96d56Sopenharmony_ci if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) 5567db96d56Sopenharmony_ci goto errorexit; 5577db96d56Sopenharmony_ci 5587db96d56Sopenharmony_ci if (inpos_t) 5597db96d56Sopenharmony_ci *inpos_t = buf.inpos; 5607db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 5617db96d56Sopenharmony_ci return buf.outobj; 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_cierrorexit: 5647db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 5657db96d56Sopenharmony_ci Py_XDECREF(buf.outobj); 5667db96d56Sopenharmony_ci return NULL; 5677db96d56Sopenharmony_ci} 5687db96d56Sopenharmony_ci 5697db96d56Sopenharmony_ci/*[clinic input] 5707db96d56Sopenharmony_ci_multibytecodec.MultibyteCodec.encode 5717db96d56Sopenharmony_ci 5727db96d56Sopenharmony_ci input: object 5737db96d56Sopenharmony_ci errors: str(accept={str, NoneType}) = None 5747db96d56Sopenharmony_ci 5757db96d56Sopenharmony_ciReturn an encoded string version of `input'. 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci'errors' may be given to set a different error handling scheme. Default is 5787db96d56Sopenharmony_ci'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible 5797db96d56Sopenharmony_civalues are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name 5807db96d56Sopenharmony_ciregistered with codecs.register_error that can handle UnicodeEncodeErrors. 5817db96d56Sopenharmony_ci[clinic start generated code]*/ 5827db96d56Sopenharmony_ci 5837db96d56Sopenharmony_cistatic PyObject * 5847db96d56Sopenharmony_ci_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, 5857db96d56Sopenharmony_ci PyObject *input, 5867db96d56Sopenharmony_ci const char *errors) 5877db96d56Sopenharmony_ci/*[clinic end generated code: output=7b26652045ba56a9 input=606d0e128a577bae]*/ 5887db96d56Sopenharmony_ci{ 5897db96d56Sopenharmony_ci MultibyteCodec_State state; 5907db96d56Sopenharmony_ci PyObject *errorcb, *r, *ucvt; 5917db96d56Sopenharmony_ci Py_ssize_t datalen; 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci if (PyUnicode_Check(input)) 5947db96d56Sopenharmony_ci ucvt = NULL; 5957db96d56Sopenharmony_ci else { 5967db96d56Sopenharmony_ci input = ucvt = PyObject_Str(input); 5977db96d56Sopenharmony_ci if (input == NULL) 5987db96d56Sopenharmony_ci return NULL; 5997db96d56Sopenharmony_ci else if (!PyUnicode_Check(input)) { 6007db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 6017db96d56Sopenharmony_ci "couldn't convert the object to unicode."); 6027db96d56Sopenharmony_ci Py_DECREF(ucvt); 6037db96d56Sopenharmony_ci return NULL; 6047db96d56Sopenharmony_ci } 6057db96d56Sopenharmony_ci } 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_ci if (PyUnicode_READY(input) < 0) { 6087db96d56Sopenharmony_ci Py_XDECREF(ucvt); 6097db96d56Sopenharmony_ci return NULL; 6107db96d56Sopenharmony_ci } 6117db96d56Sopenharmony_ci datalen = PyUnicode_GET_LENGTH(input); 6127db96d56Sopenharmony_ci 6137db96d56Sopenharmony_ci errorcb = internal_error_callback(errors); 6147db96d56Sopenharmony_ci if (errorcb == NULL) { 6157db96d56Sopenharmony_ci Py_XDECREF(ucvt); 6167db96d56Sopenharmony_ci return NULL; 6177db96d56Sopenharmony_ci } 6187db96d56Sopenharmony_ci 6197db96d56Sopenharmony_ci if (self->codec->encinit != NULL && 6207db96d56Sopenharmony_ci self->codec->encinit(&state, self->codec->config) != 0) 6217db96d56Sopenharmony_ci goto errorexit; 6227db96d56Sopenharmony_ci r = multibytecodec_encode(self->codec, &state, 6237db96d56Sopenharmony_ci input, NULL, errorcb, 6247db96d56Sopenharmony_ci MBENC_FLUSH | MBENC_RESET); 6257db96d56Sopenharmony_ci if (r == NULL) 6267db96d56Sopenharmony_ci goto errorexit; 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_ci ERROR_DECREF(errorcb); 6297db96d56Sopenharmony_ci Py_XDECREF(ucvt); 6307db96d56Sopenharmony_ci return make_tuple(r, datalen); 6317db96d56Sopenharmony_ci 6327db96d56Sopenharmony_cierrorexit: 6337db96d56Sopenharmony_ci ERROR_DECREF(errorcb); 6347db96d56Sopenharmony_ci Py_XDECREF(ucvt); 6357db96d56Sopenharmony_ci return NULL; 6367db96d56Sopenharmony_ci} 6377db96d56Sopenharmony_ci 6387db96d56Sopenharmony_ci/*[clinic input] 6397db96d56Sopenharmony_ci_multibytecodec.MultibyteCodec.decode 6407db96d56Sopenharmony_ci 6417db96d56Sopenharmony_ci input: Py_buffer 6427db96d56Sopenharmony_ci errors: str(accept={str, NoneType}) = None 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_ciDecodes 'input'. 6457db96d56Sopenharmony_ci 6467db96d56Sopenharmony_ci'errors' may be given to set a different error handling scheme. Default is 6477db96d56Sopenharmony_ci'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible 6487db96d56Sopenharmony_civalues are 'ignore' and 'replace' as well as any other name registered with 6497db96d56Sopenharmony_cicodecs.register_error that is able to handle UnicodeDecodeErrors." 6507db96d56Sopenharmony_ci[clinic start generated code]*/ 6517db96d56Sopenharmony_ci 6527db96d56Sopenharmony_cistatic PyObject * 6537db96d56Sopenharmony_ci_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, 6547db96d56Sopenharmony_ci Py_buffer *input, 6557db96d56Sopenharmony_ci const char *errors) 6567db96d56Sopenharmony_ci/*[clinic end generated code: output=ff419f65bad6cc77 input=e0c78fc7ab190def]*/ 6577db96d56Sopenharmony_ci{ 6587db96d56Sopenharmony_ci MultibyteCodec_State state; 6597db96d56Sopenharmony_ci MultibyteDecodeBuffer buf; 6607db96d56Sopenharmony_ci PyObject *errorcb, *res; 6617db96d56Sopenharmony_ci const char *data; 6627db96d56Sopenharmony_ci Py_ssize_t datalen; 6637db96d56Sopenharmony_ci 6647db96d56Sopenharmony_ci data = input->buf; 6657db96d56Sopenharmony_ci datalen = input->len; 6667db96d56Sopenharmony_ci 6677db96d56Sopenharmony_ci errorcb = internal_error_callback(errors); 6687db96d56Sopenharmony_ci if (errorcb == NULL) { 6697db96d56Sopenharmony_ci return NULL; 6707db96d56Sopenharmony_ci } 6717db96d56Sopenharmony_ci 6727db96d56Sopenharmony_ci if (datalen == 0) { 6737db96d56Sopenharmony_ci ERROR_DECREF(errorcb); 6747db96d56Sopenharmony_ci return make_tuple(PyUnicode_New(0, 0), 0); 6757db96d56Sopenharmony_ci } 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_ci _PyUnicodeWriter_Init(&buf.writer); 6787db96d56Sopenharmony_ci buf.writer.min_length = datalen; 6797db96d56Sopenharmony_ci buf.excobj = NULL; 6807db96d56Sopenharmony_ci buf.inbuf = buf.inbuf_top = (unsigned char *)data; 6817db96d56Sopenharmony_ci buf.inbuf_end = buf.inbuf_top + datalen; 6827db96d56Sopenharmony_ci 6837db96d56Sopenharmony_ci if (self->codec->decinit != NULL && 6847db96d56Sopenharmony_ci self->codec->decinit(&state, self->codec->config) != 0) 6857db96d56Sopenharmony_ci goto errorexit; 6867db96d56Sopenharmony_ci 6877db96d56Sopenharmony_ci while (buf.inbuf < buf.inbuf_end) { 6887db96d56Sopenharmony_ci Py_ssize_t inleft, r; 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_ci inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); 6917db96d56Sopenharmony_ci 6927db96d56Sopenharmony_ci r = self->codec->decode(&state, self->codec->config, 6937db96d56Sopenharmony_ci &buf.inbuf, inleft, &buf.writer); 6947db96d56Sopenharmony_ci if (r == 0) 6957db96d56Sopenharmony_ci break; 6967db96d56Sopenharmony_ci else if (multibytecodec_decerror(self->codec, &state, 6977db96d56Sopenharmony_ci &buf, errorcb, r)) 6987db96d56Sopenharmony_ci goto errorexit; 6997db96d56Sopenharmony_ci } 7007db96d56Sopenharmony_ci 7017db96d56Sopenharmony_ci res = _PyUnicodeWriter_Finish(&buf.writer); 7027db96d56Sopenharmony_ci if (res == NULL) 7037db96d56Sopenharmony_ci goto errorexit; 7047db96d56Sopenharmony_ci 7057db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 7067db96d56Sopenharmony_ci ERROR_DECREF(errorcb); 7077db96d56Sopenharmony_ci return make_tuple(res, datalen); 7087db96d56Sopenharmony_ci 7097db96d56Sopenharmony_cierrorexit: 7107db96d56Sopenharmony_ci ERROR_DECREF(errorcb); 7117db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 7127db96d56Sopenharmony_ci _PyUnicodeWriter_Dealloc(&buf.writer); 7137db96d56Sopenharmony_ci 7147db96d56Sopenharmony_ci return NULL; 7157db96d56Sopenharmony_ci} 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_cistatic struct PyMethodDef multibytecodec_methods[] = { 7187db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF 7197db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF 7207db96d56Sopenharmony_ci {NULL, NULL}, 7217db96d56Sopenharmony_ci}; 7227db96d56Sopenharmony_ci 7237db96d56Sopenharmony_cistatic int 7247db96d56Sopenharmony_cimultibytecodec_traverse(PyObject *self, visitproc visit, void *arg) 7257db96d56Sopenharmony_ci{ 7267db96d56Sopenharmony_ci Py_VISIT(Py_TYPE(self)); 7277db96d56Sopenharmony_ci return 0; 7287db96d56Sopenharmony_ci} 7297db96d56Sopenharmony_ci 7307db96d56Sopenharmony_cistatic void 7317db96d56Sopenharmony_cimultibytecodec_dealloc(MultibyteCodecObject *self) 7327db96d56Sopenharmony_ci{ 7337db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 7347db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 7357db96d56Sopenharmony_ci tp->tp_free(self); 7367db96d56Sopenharmony_ci Py_DECREF(tp); 7377db96d56Sopenharmony_ci} 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_cistatic PyType_Slot multibytecodec_slots[] = { 7407db96d56Sopenharmony_ci {Py_tp_dealloc, multibytecodec_dealloc}, 7417db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 7427db96d56Sopenharmony_ci {Py_tp_methods, multibytecodec_methods}, 7437db96d56Sopenharmony_ci {Py_tp_traverse, multibytecodec_traverse}, 7447db96d56Sopenharmony_ci {0, NULL}, 7457db96d56Sopenharmony_ci}; 7467db96d56Sopenharmony_ci 7477db96d56Sopenharmony_cistatic PyType_Spec multibytecodec_spec = { 7487db96d56Sopenharmony_ci .name = MODULE_NAME ".MultibyteCodec", 7497db96d56Sopenharmony_ci .basicsize = sizeof(MultibyteCodecObject), 7507db96d56Sopenharmony_ci .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 7517db96d56Sopenharmony_ci Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), 7527db96d56Sopenharmony_ci .slots = multibytecodec_slots, 7537db96d56Sopenharmony_ci}; 7547db96d56Sopenharmony_ci 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci/** 7577db96d56Sopenharmony_ci * Utility functions for stateful codec mechanism 7587db96d56Sopenharmony_ci */ 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_ci#define STATEFUL_DCTX(o) ((MultibyteStatefulDecoderContext *)(o)) 7617db96d56Sopenharmony_ci#define STATEFUL_ECTX(o) ((MultibyteStatefulEncoderContext *)(o)) 7627db96d56Sopenharmony_ci 7637db96d56Sopenharmony_cistatic PyObject * 7647db96d56Sopenharmony_ciencoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, 7657db96d56Sopenharmony_ci PyObject *unistr, int final) 7667db96d56Sopenharmony_ci{ 7677db96d56Sopenharmony_ci PyObject *ucvt, *r = NULL; 7687db96d56Sopenharmony_ci PyObject *inbuf = NULL; 7697db96d56Sopenharmony_ci Py_ssize_t inpos, datalen; 7707db96d56Sopenharmony_ci PyObject *origpending = NULL; 7717db96d56Sopenharmony_ci 7727db96d56Sopenharmony_ci if (PyUnicode_Check(unistr)) 7737db96d56Sopenharmony_ci ucvt = NULL; 7747db96d56Sopenharmony_ci else { 7757db96d56Sopenharmony_ci unistr = ucvt = PyObject_Str(unistr); 7767db96d56Sopenharmony_ci if (unistr == NULL) 7777db96d56Sopenharmony_ci return NULL; 7787db96d56Sopenharmony_ci else if (!PyUnicode_Check(unistr)) { 7797db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 7807db96d56Sopenharmony_ci "couldn't convert the object to str."); 7817db96d56Sopenharmony_ci Py_DECREF(ucvt); 7827db96d56Sopenharmony_ci return NULL; 7837db96d56Sopenharmony_ci } 7847db96d56Sopenharmony_ci } 7857db96d56Sopenharmony_ci 7867db96d56Sopenharmony_ci if (ctx->pending) { 7877db96d56Sopenharmony_ci PyObject *inbuf_tmp; 7887db96d56Sopenharmony_ci 7897db96d56Sopenharmony_ci Py_INCREF(ctx->pending); 7907db96d56Sopenharmony_ci origpending = ctx->pending; 7917db96d56Sopenharmony_ci 7927db96d56Sopenharmony_ci Py_INCREF(ctx->pending); 7937db96d56Sopenharmony_ci inbuf_tmp = ctx->pending; 7947db96d56Sopenharmony_ci PyUnicode_Append(&inbuf_tmp, unistr); 7957db96d56Sopenharmony_ci if (inbuf_tmp == NULL) 7967db96d56Sopenharmony_ci goto errorexit; 7977db96d56Sopenharmony_ci Py_CLEAR(ctx->pending); 7987db96d56Sopenharmony_ci inbuf = inbuf_tmp; 7997db96d56Sopenharmony_ci } 8007db96d56Sopenharmony_ci else { 8017db96d56Sopenharmony_ci origpending = NULL; 8027db96d56Sopenharmony_ci 8037db96d56Sopenharmony_ci Py_INCREF(unistr); 8047db96d56Sopenharmony_ci inbuf = unistr; 8057db96d56Sopenharmony_ci } 8067db96d56Sopenharmony_ci if (PyUnicode_READY(inbuf) < 0) 8077db96d56Sopenharmony_ci goto errorexit; 8087db96d56Sopenharmony_ci inpos = 0; 8097db96d56Sopenharmony_ci datalen = PyUnicode_GET_LENGTH(inbuf); 8107db96d56Sopenharmony_ci 8117db96d56Sopenharmony_ci r = multibytecodec_encode(ctx->codec, &ctx->state, 8127db96d56Sopenharmony_ci inbuf, &inpos, 8137db96d56Sopenharmony_ci ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0); 8147db96d56Sopenharmony_ci if (r == NULL) { 8157db96d56Sopenharmony_ci /* recover the original pending buffer */ 8167db96d56Sopenharmony_ci Py_XSETREF(ctx->pending, origpending); 8177db96d56Sopenharmony_ci origpending = NULL; 8187db96d56Sopenharmony_ci goto errorexit; 8197db96d56Sopenharmony_ci } 8207db96d56Sopenharmony_ci Py_XDECREF(origpending); 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_ci if (inpos < datalen) { 8237db96d56Sopenharmony_ci if (datalen - inpos > MAXENCPENDING) { 8247db96d56Sopenharmony_ci /* normal codecs can't reach here */ 8257db96d56Sopenharmony_ci PyErr_SetString(PyExc_UnicodeError, 8267db96d56Sopenharmony_ci "pending buffer overflow"); 8277db96d56Sopenharmony_ci goto errorexit; 8287db96d56Sopenharmony_ci } 8297db96d56Sopenharmony_ci ctx->pending = PyUnicode_Substring(inbuf, inpos, datalen); 8307db96d56Sopenharmony_ci if (ctx->pending == NULL) { 8317db96d56Sopenharmony_ci /* normal codecs can't reach here */ 8327db96d56Sopenharmony_ci goto errorexit; 8337db96d56Sopenharmony_ci } 8347db96d56Sopenharmony_ci } 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci Py_DECREF(inbuf); 8377db96d56Sopenharmony_ci Py_XDECREF(ucvt); 8387db96d56Sopenharmony_ci return r; 8397db96d56Sopenharmony_ci 8407db96d56Sopenharmony_cierrorexit: 8417db96d56Sopenharmony_ci Py_XDECREF(r); 8427db96d56Sopenharmony_ci Py_XDECREF(ucvt); 8437db96d56Sopenharmony_ci Py_XDECREF(origpending); 8447db96d56Sopenharmony_ci Py_XDECREF(inbuf); 8457db96d56Sopenharmony_ci return NULL; 8467db96d56Sopenharmony_ci} 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_cistatic int 8497db96d56Sopenharmony_cidecoder_append_pending(MultibyteStatefulDecoderContext *ctx, 8507db96d56Sopenharmony_ci MultibyteDecodeBuffer *buf) 8517db96d56Sopenharmony_ci{ 8527db96d56Sopenharmony_ci Py_ssize_t npendings; 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 8557db96d56Sopenharmony_ci if (npendings + ctx->pendingsize > MAXDECPENDING || 8567db96d56Sopenharmony_ci npendings > PY_SSIZE_T_MAX - ctx->pendingsize) { 8577db96d56Sopenharmony_ci PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); 8587db96d56Sopenharmony_ci return -1; 8597db96d56Sopenharmony_ci } 8607db96d56Sopenharmony_ci memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings); 8617db96d56Sopenharmony_ci ctx->pendingsize += npendings; 8627db96d56Sopenharmony_ci return 0; 8637db96d56Sopenharmony_ci} 8647db96d56Sopenharmony_ci 8657db96d56Sopenharmony_cistatic int 8667db96d56Sopenharmony_cidecoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data, 8677db96d56Sopenharmony_ci Py_ssize_t size) 8687db96d56Sopenharmony_ci{ 8697db96d56Sopenharmony_ci buf->inbuf = buf->inbuf_top = (const unsigned char *)data; 8707db96d56Sopenharmony_ci buf->inbuf_end = buf->inbuf_top + size; 8717db96d56Sopenharmony_ci buf->writer.min_length += size; 8727db96d56Sopenharmony_ci return 0; 8737db96d56Sopenharmony_ci} 8747db96d56Sopenharmony_ci 8757db96d56Sopenharmony_cistatic int 8767db96d56Sopenharmony_cidecoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, 8777db96d56Sopenharmony_ci MultibyteDecodeBuffer *buf) 8787db96d56Sopenharmony_ci{ 8797db96d56Sopenharmony_ci while (buf->inbuf < buf->inbuf_end) { 8807db96d56Sopenharmony_ci Py_ssize_t inleft; 8817db96d56Sopenharmony_ci Py_ssize_t r; 8827db96d56Sopenharmony_ci 8837db96d56Sopenharmony_ci inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 8847db96d56Sopenharmony_ci 8857db96d56Sopenharmony_ci r = ctx->codec->decode(&ctx->state, ctx->codec->config, 8867db96d56Sopenharmony_ci &buf->inbuf, inleft, &buf->writer); 8877db96d56Sopenharmony_ci if (r == 0 || r == MBERR_TOOFEW) 8887db96d56Sopenharmony_ci break; 8897db96d56Sopenharmony_ci else if (multibytecodec_decerror(ctx->codec, &ctx->state, 8907db96d56Sopenharmony_ci buf, ctx->errors, r)) 8917db96d56Sopenharmony_ci return -1; 8927db96d56Sopenharmony_ci } 8937db96d56Sopenharmony_ci return 0; 8947db96d56Sopenharmony_ci} 8957db96d56Sopenharmony_ci 8967db96d56Sopenharmony_ci 8977db96d56Sopenharmony_ci/*[clinic input] 8987db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalEncoder.encode 8997db96d56Sopenharmony_ci 9007db96d56Sopenharmony_ci input: object 9017db96d56Sopenharmony_ci final: bool(accept={int}) = False 9027db96d56Sopenharmony_ci[clinic start generated code]*/ 9037db96d56Sopenharmony_ci 9047db96d56Sopenharmony_cistatic PyObject * 9057db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, 9067db96d56Sopenharmony_ci PyObject *input, 9077db96d56Sopenharmony_ci int final) 9087db96d56Sopenharmony_ci/*[clinic end generated code: output=123361b6c505e2c1 input=093a1ddbb2fc6721]*/ 9097db96d56Sopenharmony_ci{ 9107db96d56Sopenharmony_ci return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); 9117db96d56Sopenharmony_ci} 9127db96d56Sopenharmony_ci 9137db96d56Sopenharmony_ci/*[clinic input] 9147db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalEncoder.getstate 9157db96d56Sopenharmony_ci[clinic start generated code]*/ 9167db96d56Sopenharmony_ci 9177db96d56Sopenharmony_cistatic PyObject * 9187db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalEncoder_getstate_impl(MultibyteIncrementalEncoderObject *self) 9197db96d56Sopenharmony_ci/*[clinic end generated code: output=9794a5ace70d7048 input=4a2a82874ffa40bb]*/ 9207db96d56Sopenharmony_ci{ 9217db96d56Sopenharmony_ci /* state made up of 1 byte for buffer size, up to MAXENCPENDING*4 bytes 9227db96d56Sopenharmony_ci for UTF-8 encoded buffer (each character can use up to 4 9237db96d56Sopenharmony_ci bytes), and required bytes for MultibyteCodec_State.c. A byte 9247db96d56Sopenharmony_ci array is used to avoid different compilers generating different 9257db96d56Sopenharmony_ci values for the same state, e.g. as a result of struct padding. 9267db96d56Sopenharmony_ci */ 9277db96d56Sopenharmony_ci unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; 9287db96d56Sopenharmony_ci Py_ssize_t statesize; 9297db96d56Sopenharmony_ci const char *pendingbuffer = NULL; 9307db96d56Sopenharmony_ci Py_ssize_t pendingsize; 9317db96d56Sopenharmony_ci 9327db96d56Sopenharmony_ci if (self->pending != NULL) { 9337db96d56Sopenharmony_ci pendingbuffer = PyUnicode_AsUTF8AndSize(self->pending, &pendingsize); 9347db96d56Sopenharmony_ci if (pendingbuffer == NULL) { 9357db96d56Sopenharmony_ci return NULL; 9367db96d56Sopenharmony_ci } 9377db96d56Sopenharmony_ci if (pendingsize > MAXENCPENDING*4) { 9387db96d56Sopenharmony_ci PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); 9397db96d56Sopenharmony_ci return NULL; 9407db96d56Sopenharmony_ci } 9417db96d56Sopenharmony_ci statebytes[0] = (unsigned char)pendingsize; 9427db96d56Sopenharmony_ci memcpy(statebytes + 1, pendingbuffer, pendingsize); 9437db96d56Sopenharmony_ci statesize = 1 + pendingsize; 9447db96d56Sopenharmony_ci } else { 9457db96d56Sopenharmony_ci statebytes[0] = 0; 9467db96d56Sopenharmony_ci statesize = 1; 9477db96d56Sopenharmony_ci } 9487db96d56Sopenharmony_ci memcpy(statebytes+statesize, self->state.c, 9497db96d56Sopenharmony_ci sizeof(self->state.c)); 9507db96d56Sopenharmony_ci statesize += sizeof(self->state.c); 9517db96d56Sopenharmony_ci 9527db96d56Sopenharmony_ci return (PyObject *)_PyLong_FromByteArray(statebytes, statesize, 9537db96d56Sopenharmony_ci 1 /* little-endian */ , 9547db96d56Sopenharmony_ci 0 /* unsigned */ ); 9557db96d56Sopenharmony_ci} 9567db96d56Sopenharmony_ci 9577db96d56Sopenharmony_ci/*[clinic input] 9587db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalEncoder.setstate 9597db96d56Sopenharmony_ci state as statelong: object(type='PyLongObject *', subclass_of='&PyLong_Type') 9607db96d56Sopenharmony_ci / 9617db96d56Sopenharmony_ci[clinic start generated code]*/ 9627db96d56Sopenharmony_ci 9637db96d56Sopenharmony_cistatic PyObject * 9647db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEncoderObject *self, 9657db96d56Sopenharmony_ci PyLongObject *statelong) 9667db96d56Sopenharmony_ci/*[clinic end generated code: output=4e5e98ac1f4039ca input=c80fb5830d4d2f76]*/ 9677db96d56Sopenharmony_ci{ 9687db96d56Sopenharmony_ci PyObject *pending = NULL; 9697db96d56Sopenharmony_ci unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; 9707db96d56Sopenharmony_ci 9717db96d56Sopenharmony_ci if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), 9727db96d56Sopenharmony_ci 1 /* little-endian */ , 9737db96d56Sopenharmony_ci 0 /* unsigned */ ) < 0) { 9747db96d56Sopenharmony_ci goto errorexit; 9757db96d56Sopenharmony_ci } 9767db96d56Sopenharmony_ci 9777db96d56Sopenharmony_ci if (statebytes[0] > MAXENCPENDING*4) { 9787db96d56Sopenharmony_ci PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); 9797db96d56Sopenharmony_ci return NULL; 9807db96d56Sopenharmony_ci } 9817db96d56Sopenharmony_ci 9827db96d56Sopenharmony_ci pending = PyUnicode_DecodeUTF8((const char *)statebytes+1, 9837db96d56Sopenharmony_ci statebytes[0], "strict"); 9847db96d56Sopenharmony_ci if (pending == NULL) { 9857db96d56Sopenharmony_ci goto errorexit; 9867db96d56Sopenharmony_ci } 9877db96d56Sopenharmony_ci 9887db96d56Sopenharmony_ci Py_CLEAR(self->pending); 9897db96d56Sopenharmony_ci self->pending = pending; 9907db96d56Sopenharmony_ci memcpy(self->state.c, statebytes+1+statebytes[0], 9917db96d56Sopenharmony_ci sizeof(self->state.c)); 9927db96d56Sopenharmony_ci 9937db96d56Sopenharmony_ci Py_RETURN_NONE; 9947db96d56Sopenharmony_ci 9957db96d56Sopenharmony_cierrorexit: 9967db96d56Sopenharmony_ci Py_XDECREF(pending); 9977db96d56Sopenharmony_ci return NULL; 9987db96d56Sopenharmony_ci} 9997db96d56Sopenharmony_ci 10007db96d56Sopenharmony_ci/*[clinic input] 10017db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalEncoder.reset 10027db96d56Sopenharmony_ci[clinic start generated code]*/ 10037db96d56Sopenharmony_ci 10047db96d56Sopenharmony_cistatic PyObject * 10057db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self) 10067db96d56Sopenharmony_ci/*[clinic end generated code: output=b4125d8f537a253f input=930f06760707b6ea]*/ 10077db96d56Sopenharmony_ci{ 10087db96d56Sopenharmony_ci /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ 10097db96d56Sopenharmony_ci unsigned char buffer[4], *outbuf; 10107db96d56Sopenharmony_ci Py_ssize_t r; 10117db96d56Sopenharmony_ci if (self->codec->encreset != NULL) { 10127db96d56Sopenharmony_ci outbuf = buffer; 10137db96d56Sopenharmony_ci r = self->codec->encreset(&self->state, self->codec->config, 10147db96d56Sopenharmony_ci &outbuf, sizeof(buffer)); 10157db96d56Sopenharmony_ci if (r != 0) 10167db96d56Sopenharmony_ci return NULL; 10177db96d56Sopenharmony_ci } 10187db96d56Sopenharmony_ci Py_CLEAR(self->pending); 10197db96d56Sopenharmony_ci Py_RETURN_NONE; 10207db96d56Sopenharmony_ci} 10217db96d56Sopenharmony_ci 10227db96d56Sopenharmony_cistatic struct PyMethodDef mbiencoder_methods[] = { 10237db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF 10247db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_GETSTATE_METHODDEF 10257db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_SETSTATE_METHODDEF 10267db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF 10277db96d56Sopenharmony_ci {NULL, NULL}, 10287db96d56Sopenharmony_ci}; 10297db96d56Sopenharmony_ci 10307db96d56Sopenharmony_cistatic PyObject * 10317db96d56Sopenharmony_cimbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 10327db96d56Sopenharmony_ci{ 10337db96d56Sopenharmony_ci MultibyteIncrementalEncoderObject *self; 10347db96d56Sopenharmony_ci PyObject *codec = NULL; 10357db96d56Sopenharmony_ci char *errors = NULL; 10367db96d56Sopenharmony_ci 10377db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder", 10387db96d56Sopenharmony_ci incnewkwarglist, &errors)) 10397db96d56Sopenharmony_ci return NULL; 10407db96d56Sopenharmony_ci 10417db96d56Sopenharmony_ci self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0); 10427db96d56Sopenharmony_ci if (self == NULL) 10437db96d56Sopenharmony_ci return NULL; 10447db96d56Sopenharmony_ci 10457db96d56Sopenharmony_ci codec = PyObject_GetAttrString((PyObject *)type, "codec"); 10467db96d56Sopenharmony_ci if (codec == NULL) 10477db96d56Sopenharmony_ci goto errorexit; 10487db96d56Sopenharmony_ci 10497db96d56Sopenharmony_ci _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); 10507db96d56Sopenharmony_ci if (!MultibyteCodec_Check(state, codec)) { 10517db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 10527db96d56Sopenharmony_ci goto errorexit; 10537db96d56Sopenharmony_ci } 10547db96d56Sopenharmony_ci 10557db96d56Sopenharmony_ci self->codec = ((MultibyteCodecObject *)codec)->codec; 10567db96d56Sopenharmony_ci self->pending = NULL; 10577db96d56Sopenharmony_ci self->errors = internal_error_callback(errors); 10587db96d56Sopenharmony_ci if (self->errors == NULL) 10597db96d56Sopenharmony_ci goto errorexit; 10607db96d56Sopenharmony_ci if (self->codec->encinit != NULL && 10617db96d56Sopenharmony_ci self->codec->encinit(&self->state, self->codec->config) != 0) 10627db96d56Sopenharmony_ci goto errorexit; 10637db96d56Sopenharmony_ci 10647db96d56Sopenharmony_ci Py_DECREF(codec); 10657db96d56Sopenharmony_ci return (PyObject *)self; 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_cierrorexit: 10687db96d56Sopenharmony_ci Py_XDECREF(self); 10697db96d56Sopenharmony_ci Py_XDECREF(codec); 10707db96d56Sopenharmony_ci return NULL; 10717db96d56Sopenharmony_ci} 10727db96d56Sopenharmony_ci 10737db96d56Sopenharmony_cistatic int 10747db96d56Sopenharmony_cimbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds) 10757db96d56Sopenharmony_ci{ 10767db96d56Sopenharmony_ci return 0; 10777db96d56Sopenharmony_ci} 10787db96d56Sopenharmony_ci 10797db96d56Sopenharmony_cistatic int 10807db96d56Sopenharmony_cimbiencoder_traverse(MultibyteIncrementalEncoderObject *self, 10817db96d56Sopenharmony_ci visitproc visit, void *arg) 10827db96d56Sopenharmony_ci{ 10837db96d56Sopenharmony_ci if (ERROR_ISCUSTOM(self->errors)) 10847db96d56Sopenharmony_ci Py_VISIT(self->errors); 10857db96d56Sopenharmony_ci return 0; 10867db96d56Sopenharmony_ci} 10877db96d56Sopenharmony_ci 10887db96d56Sopenharmony_cistatic void 10897db96d56Sopenharmony_cimbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) 10907db96d56Sopenharmony_ci{ 10917db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 10927db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 10937db96d56Sopenharmony_ci ERROR_DECREF(self->errors); 10947db96d56Sopenharmony_ci Py_CLEAR(self->pending); 10957db96d56Sopenharmony_ci tp->tp_free(self); 10967db96d56Sopenharmony_ci Py_DECREF(tp); 10977db96d56Sopenharmony_ci} 10987db96d56Sopenharmony_ci 10997db96d56Sopenharmony_cistatic PyType_Slot encoder_slots[] = { 11007db96d56Sopenharmony_ci {Py_tp_dealloc, mbiencoder_dealloc}, 11017db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 11027db96d56Sopenharmony_ci {Py_tp_traverse, mbiencoder_traverse}, 11037db96d56Sopenharmony_ci {Py_tp_methods, mbiencoder_methods}, 11047db96d56Sopenharmony_ci {Py_tp_getset, codecctx_getsets}, 11057db96d56Sopenharmony_ci {Py_tp_init, mbiencoder_init}, 11067db96d56Sopenharmony_ci {Py_tp_new, mbiencoder_new}, 11077db96d56Sopenharmony_ci {0, NULL}, 11087db96d56Sopenharmony_ci}; 11097db96d56Sopenharmony_ci 11107db96d56Sopenharmony_cistatic PyType_Spec encoder_spec = { 11117db96d56Sopenharmony_ci .name = MODULE_NAME ".MultibyteIncrementalEncoder", 11127db96d56Sopenharmony_ci .basicsize = sizeof(MultibyteIncrementalEncoderObject), 11137db96d56Sopenharmony_ci .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | 11147db96d56Sopenharmony_ci Py_TPFLAGS_IMMUTABLETYPE), 11157db96d56Sopenharmony_ci .slots = encoder_slots, 11167db96d56Sopenharmony_ci}; 11177db96d56Sopenharmony_ci 11187db96d56Sopenharmony_ci 11197db96d56Sopenharmony_ci/*[clinic input] 11207db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalDecoder.decode 11217db96d56Sopenharmony_ci 11227db96d56Sopenharmony_ci input: Py_buffer 11237db96d56Sopenharmony_ci final: bool(accept={int}) = False 11247db96d56Sopenharmony_ci[clinic start generated code]*/ 11257db96d56Sopenharmony_ci 11267db96d56Sopenharmony_cistatic PyObject * 11277db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, 11287db96d56Sopenharmony_ci Py_buffer *input, 11297db96d56Sopenharmony_ci int final) 11307db96d56Sopenharmony_ci/*[clinic end generated code: output=b9b9090e8a9ce2ba input=c9132b24d503eb1d]*/ 11317db96d56Sopenharmony_ci{ 11327db96d56Sopenharmony_ci MultibyteDecodeBuffer buf; 11337db96d56Sopenharmony_ci char *data, *wdata = NULL; 11347db96d56Sopenharmony_ci Py_ssize_t wsize, size, origpending; 11357db96d56Sopenharmony_ci PyObject *res; 11367db96d56Sopenharmony_ci 11377db96d56Sopenharmony_ci data = input->buf; 11387db96d56Sopenharmony_ci size = input->len; 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_ci _PyUnicodeWriter_Init(&buf.writer); 11417db96d56Sopenharmony_ci buf.excobj = NULL; 11427db96d56Sopenharmony_ci origpending = self->pendingsize; 11437db96d56Sopenharmony_ci 11447db96d56Sopenharmony_ci if (self->pendingsize == 0) { 11457db96d56Sopenharmony_ci wsize = size; 11467db96d56Sopenharmony_ci wdata = data; 11477db96d56Sopenharmony_ci } 11487db96d56Sopenharmony_ci else { 11497db96d56Sopenharmony_ci if (size > PY_SSIZE_T_MAX - self->pendingsize) { 11507db96d56Sopenharmony_ci PyErr_NoMemory(); 11517db96d56Sopenharmony_ci goto errorexit; 11527db96d56Sopenharmony_ci } 11537db96d56Sopenharmony_ci wsize = size + self->pendingsize; 11547db96d56Sopenharmony_ci wdata = PyMem_Malloc(wsize); 11557db96d56Sopenharmony_ci if (wdata == NULL) { 11567db96d56Sopenharmony_ci PyErr_NoMemory(); 11577db96d56Sopenharmony_ci goto errorexit; 11587db96d56Sopenharmony_ci } 11597db96d56Sopenharmony_ci memcpy(wdata, self->pending, self->pendingsize); 11607db96d56Sopenharmony_ci memcpy(wdata + self->pendingsize, data, size); 11617db96d56Sopenharmony_ci self->pendingsize = 0; 11627db96d56Sopenharmony_ci } 11637db96d56Sopenharmony_ci 11647db96d56Sopenharmony_ci if (decoder_prepare_buffer(&buf, wdata, wsize) != 0) 11657db96d56Sopenharmony_ci goto errorexit; 11667db96d56Sopenharmony_ci 11677db96d56Sopenharmony_ci if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf)) 11687db96d56Sopenharmony_ci goto errorexit; 11697db96d56Sopenharmony_ci 11707db96d56Sopenharmony_ci if (final && buf.inbuf < buf.inbuf_end) { 11717db96d56Sopenharmony_ci if (multibytecodec_decerror(self->codec, &self->state, 11727db96d56Sopenharmony_ci &buf, self->errors, MBERR_TOOFEW)) { 11737db96d56Sopenharmony_ci /* recover the original pending buffer */ 11747db96d56Sopenharmony_ci memcpy(self->pending, wdata, origpending); 11757db96d56Sopenharmony_ci self->pendingsize = origpending; 11767db96d56Sopenharmony_ci goto errorexit; 11777db96d56Sopenharmony_ci } 11787db96d56Sopenharmony_ci } 11797db96d56Sopenharmony_ci 11807db96d56Sopenharmony_ci if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */ 11817db96d56Sopenharmony_ci if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0) 11827db96d56Sopenharmony_ci goto errorexit; 11837db96d56Sopenharmony_ci } 11847db96d56Sopenharmony_ci 11857db96d56Sopenharmony_ci res = _PyUnicodeWriter_Finish(&buf.writer); 11867db96d56Sopenharmony_ci if (res == NULL) 11877db96d56Sopenharmony_ci goto errorexit; 11887db96d56Sopenharmony_ci 11897db96d56Sopenharmony_ci if (wdata != data) 11907db96d56Sopenharmony_ci PyMem_Free(wdata); 11917db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 11927db96d56Sopenharmony_ci return res; 11937db96d56Sopenharmony_ci 11947db96d56Sopenharmony_cierrorexit: 11957db96d56Sopenharmony_ci if (wdata != NULL && wdata != data) 11967db96d56Sopenharmony_ci PyMem_Free(wdata); 11977db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 11987db96d56Sopenharmony_ci _PyUnicodeWriter_Dealloc(&buf.writer); 11997db96d56Sopenharmony_ci return NULL; 12007db96d56Sopenharmony_ci} 12017db96d56Sopenharmony_ci 12027db96d56Sopenharmony_ci/*[clinic input] 12037db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalDecoder.getstate 12047db96d56Sopenharmony_ci[clinic start generated code]*/ 12057db96d56Sopenharmony_ci 12067db96d56Sopenharmony_cistatic PyObject * 12077db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalDecoder_getstate_impl(MultibyteIncrementalDecoderObject *self) 12087db96d56Sopenharmony_ci/*[clinic end generated code: output=255009c4713b7f82 input=4006aa49bddbaa75]*/ 12097db96d56Sopenharmony_ci{ 12107db96d56Sopenharmony_ci PyObject *buffer; 12117db96d56Sopenharmony_ci PyObject *statelong; 12127db96d56Sopenharmony_ci 12137db96d56Sopenharmony_ci buffer = PyBytes_FromStringAndSize((const char *)self->pending, 12147db96d56Sopenharmony_ci self->pendingsize); 12157db96d56Sopenharmony_ci if (buffer == NULL) { 12167db96d56Sopenharmony_ci return NULL; 12177db96d56Sopenharmony_ci } 12187db96d56Sopenharmony_ci 12197db96d56Sopenharmony_ci statelong = (PyObject *)_PyLong_FromByteArray(self->state.c, 12207db96d56Sopenharmony_ci sizeof(self->state.c), 12217db96d56Sopenharmony_ci 1 /* little-endian */ , 12227db96d56Sopenharmony_ci 0 /* unsigned */ ); 12237db96d56Sopenharmony_ci if (statelong == NULL) { 12247db96d56Sopenharmony_ci Py_DECREF(buffer); 12257db96d56Sopenharmony_ci return NULL; 12267db96d56Sopenharmony_ci } 12277db96d56Sopenharmony_ci 12287db96d56Sopenharmony_ci return Py_BuildValue("NN", buffer, statelong); 12297db96d56Sopenharmony_ci} 12307db96d56Sopenharmony_ci 12317db96d56Sopenharmony_ci/*[clinic input] 12327db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalDecoder.setstate 12337db96d56Sopenharmony_ci state: object(subclass_of='&PyTuple_Type') 12347db96d56Sopenharmony_ci / 12357db96d56Sopenharmony_ci[clinic start generated code]*/ 12367db96d56Sopenharmony_ci 12377db96d56Sopenharmony_cistatic PyObject * 12387db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalDecoder_setstate_impl(MultibyteIncrementalDecoderObject *self, 12397db96d56Sopenharmony_ci PyObject *state) 12407db96d56Sopenharmony_ci/*[clinic end generated code: output=106b2fbca3e2dcc2 input=e5d794e8baba1a47]*/ 12417db96d56Sopenharmony_ci{ 12427db96d56Sopenharmony_ci PyObject *buffer; 12437db96d56Sopenharmony_ci PyLongObject *statelong; 12447db96d56Sopenharmony_ci Py_ssize_t buffersize; 12457db96d56Sopenharmony_ci const char *bufferstr; 12467db96d56Sopenharmony_ci unsigned char statebytes[8]; 12477db96d56Sopenharmony_ci 12487db96d56Sopenharmony_ci if (!PyArg_ParseTuple(state, "SO!;setstate(): illegal state argument", 12497db96d56Sopenharmony_ci &buffer, &PyLong_Type, &statelong)) 12507db96d56Sopenharmony_ci { 12517db96d56Sopenharmony_ci return NULL; 12527db96d56Sopenharmony_ci } 12537db96d56Sopenharmony_ci 12547db96d56Sopenharmony_ci if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), 12557db96d56Sopenharmony_ci 1 /* little-endian */ , 12567db96d56Sopenharmony_ci 0 /* unsigned */ ) < 0) { 12577db96d56Sopenharmony_ci return NULL; 12587db96d56Sopenharmony_ci } 12597db96d56Sopenharmony_ci 12607db96d56Sopenharmony_ci buffersize = PyBytes_Size(buffer); 12617db96d56Sopenharmony_ci if (buffersize == -1) { 12627db96d56Sopenharmony_ci return NULL; 12637db96d56Sopenharmony_ci } 12647db96d56Sopenharmony_ci 12657db96d56Sopenharmony_ci if (buffersize > MAXDECPENDING) { 12667db96d56Sopenharmony_ci PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); 12677db96d56Sopenharmony_ci return NULL; 12687db96d56Sopenharmony_ci } 12697db96d56Sopenharmony_ci 12707db96d56Sopenharmony_ci bufferstr = PyBytes_AsString(buffer); 12717db96d56Sopenharmony_ci if (bufferstr == NULL) { 12727db96d56Sopenharmony_ci return NULL; 12737db96d56Sopenharmony_ci } 12747db96d56Sopenharmony_ci self->pendingsize = buffersize; 12757db96d56Sopenharmony_ci memcpy(self->pending, bufferstr, self->pendingsize); 12767db96d56Sopenharmony_ci memcpy(self->state.c, statebytes, sizeof(statebytes)); 12777db96d56Sopenharmony_ci 12787db96d56Sopenharmony_ci Py_RETURN_NONE; 12797db96d56Sopenharmony_ci} 12807db96d56Sopenharmony_ci 12817db96d56Sopenharmony_ci/*[clinic input] 12827db96d56Sopenharmony_ci_multibytecodec.MultibyteIncrementalDecoder.reset 12837db96d56Sopenharmony_ci[clinic start generated code]*/ 12847db96d56Sopenharmony_ci 12857db96d56Sopenharmony_cistatic PyObject * 12867db96d56Sopenharmony_ci_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self) 12877db96d56Sopenharmony_ci/*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/ 12887db96d56Sopenharmony_ci{ 12897db96d56Sopenharmony_ci if (self->codec->decreset != NULL && 12907db96d56Sopenharmony_ci self->codec->decreset(&self->state, self->codec->config) != 0) 12917db96d56Sopenharmony_ci return NULL; 12927db96d56Sopenharmony_ci self->pendingsize = 0; 12937db96d56Sopenharmony_ci 12947db96d56Sopenharmony_ci Py_RETURN_NONE; 12957db96d56Sopenharmony_ci} 12967db96d56Sopenharmony_ci 12977db96d56Sopenharmony_cistatic struct PyMethodDef mbidecoder_methods[] = { 12987db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF 12997db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_GETSTATE_METHODDEF 13007db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_SETSTATE_METHODDEF 13017db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF 13027db96d56Sopenharmony_ci {NULL, NULL}, 13037db96d56Sopenharmony_ci}; 13047db96d56Sopenharmony_ci 13057db96d56Sopenharmony_cistatic PyObject * 13067db96d56Sopenharmony_cimbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 13077db96d56Sopenharmony_ci{ 13087db96d56Sopenharmony_ci MultibyteIncrementalDecoderObject *self; 13097db96d56Sopenharmony_ci PyObject *codec = NULL; 13107db96d56Sopenharmony_ci char *errors = NULL; 13117db96d56Sopenharmony_ci 13127db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder", 13137db96d56Sopenharmony_ci incnewkwarglist, &errors)) 13147db96d56Sopenharmony_ci return NULL; 13157db96d56Sopenharmony_ci 13167db96d56Sopenharmony_ci self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0); 13177db96d56Sopenharmony_ci if (self == NULL) 13187db96d56Sopenharmony_ci return NULL; 13197db96d56Sopenharmony_ci 13207db96d56Sopenharmony_ci codec = PyObject_GetAttrString((PyObject *)type, "codec"); 13217db96d56Sopenharmony_ci if (codec == NULL) 13227db96d56Sopenharmony_ci goto errorexit; 13237db96d56Sopenharmony_ci 13247db96d56Sopenharmony_ci _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); 13257db96d56Sopenharmony_ci if (!MultibyteCodec_Check(state, codec)) { 13267db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 13277db96d56Sopenharmony_ci goto errorexit; 13287db96d56Sopenharmony_ci } 13297db96d56Sopenharmony_ci 13307db96d56Sopenharmony_ci self->codec = ((MultibyteCodecObject *)codec)->codec; 13317db96d56Sopenharmony_ci self->pendingsize = 0; 13327db96d56Sopenharmony_ci self->errors = internal_error_callback(errors); 13337db96d56Sopenharmony_ci if (self->errors == NULL) 13347db96d56Sopenharmony_ci goto errorexit; 13357db96d56Sopenharmony_ci if (self->codec->decinit != NULL && 13367db96d56Sopenharmony_ci self->codec->decinit(&self->state, self->codec->config) != 0) 13377db96d56Sopenharmony_ci goto errorexit; 13387db96d56Sopenharmony_ci 13397db96d56Sopenharmony_ci Py_DECREF(codec); 13407db96d56Sopenharmony_ci return (PyObject *)self; 13417db96d56Sopenharmony_ci 13427db96d56Sopenharmony_cierrorexit: 13437db96d56Sopenharmony_ci Py_XDECREF(self); 13447db96d56Sopenharmony_ci Py_XDECREF(codec); 13457db96d56Sopenharmony_ci return NULL; 13467db96d56Sopenharmony_ci} 13477db96d56Sopenharmony_ci 13487db96d56Sopenharmony_cistatic int 13497db96d56Sopenharmony_cimbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds) 13507db96d56Sopenharmony_ci{ 13517db96d56Sopenharmony_ci return 0; 13527db96d56Sopenharmony_ci} 13537db96d56Sopenharmony_ci 13547db96d56Sopenharmony_cistatic int 13557db96d56Sopenharmony_cimbidecoder_traverse(MultibyteIncrementalDecoderObject *self, 13567db96d56Sopenharmony_ci visitproc visit, void *arg) 13577db96d56Sopenharmony_ci{ 13587db96d56Sopenharmony_ci if (ERROR_ISCUSTOM(self->errors)) 13597db96d56Sopenharmony_ci Py_VISIT(self->errors); 13607db96d56Sopenharmony_ci return 0; 13617db96d56Sopenharmony_ci} 13627db96d56Sopenharmony_ci 13637db96d56Sopenharmony_cistatic void 13647db96d56Sopenharmony_cimbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) 13657db96d56Sopenharmony_ci{ 13667db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 13677db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 13687db96d56Sopenharmony_ci ERROR_DECREF(self->errors); 13697db96d56Sopenharmony_ci tp->tp_free(self); 13707db96d56Sopenharmony_ci Py_DECREF(tp); 13717db96d56Sopenharmony_ci} 13727db96d56Sopenharmony_ci 13737db96d56Sopenharmony_cistatic PyType_Slot decoder_slots[] = { 13747db96d56Sopenharmony_ci {Py_tp_dealloc, mbidecoder_dealloc}, 13757db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 13767db96d56Sopenharmony_ci {Py_tp_traverse, mbidecoder_traverse}, 13777db96d56Sopenharmony_ci {Py_tp_methods, mbidecoder_methods}, 13787db96d56Sopenharmony_ci {Py_tp_getset, codecctx_getsets}, 13797db96d56Sopenharmony_ci {Py_tp_init, mbidecoder_init}, 13807db96d56Sopenharmony_ci {Py_tp_new, mbidecoder_new}, 13817db96d56Sopenharmony_ci {0, NULL}, 13827db96d56Sopenharmony_ci}; 13837db96d56Sopenharmony_ci 13847db96d56Sopenharmony_cistatic PyType_Spec decoder_spec = { 13857db96d56Sopenharmony_ci .name = MODULE_NAME ".MultibyteIncrementalDecoder", 13867db96d56Sopenharmony_ci .basicsize = sizeof(MultibyteIncrementalDecoderObject), 13877db96d56Sopenharmony_ci .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | 13887db96d56Sopenharmony_ci Py_TPFLAGS_IMMUTABLETYPE), 13897db96d56Sopenharmony_ci .slots = decoder_slots, 13907db96d56Sopenharmony_ci}; 13917db96d56Sopenharmony_ci 13927db96d56Sopenharmony_cistatic PyObject * 13937db96d56Sopenharmony_cimbstreamreader_iread(MultibyteStreamReaderObject *self, 13947db96d56Sopenharmony_ci const char *method, Py_ssize_t sizehint) 13957db96d56Sopenharmony_ci{ 13967db96d56Sopenharmony_ci MultibyteDecodeBuffer buf; 13977db96d56Sopenharmony_ci PyObject *cres, *res; 13987db96d56Sopenharmony_ci Py_ssize_t rsize; 13997db96d56Sopenharmony_ci 14007db96d56Sopenharmony_ci if (sizehint == 0) 14017db96d56Sopenharmony_ci return PyUnicode_New(0, 0); 14027db96d56Sopenharmony_ci 14037db96d56Sopenharmony_ci _PyUnicodeWriter_Init(&buf.writer); 14047db96d56Sopenharmony_ci buf.excobj = NULL; 14057db96d56Sopenharmony_ci cres = NULL; 14067db96d56Sopenharmony_ci 14077db96d56Sopenharmony_ci for (;;) { 14087db96d56Sopenharmony_ci int endoffile; 14097db96d56Sopenharmony_ci 14107db96d56Sopenharmony_ci if (sizehint < 0) 14117db96d56Sopenharmony_ci cres = PyObject_CallMethod(self->stream, 14127db96d56Sopenharmony_ci method, NULL); 14137db96d56Sopenharmony_ci else 14147db96d56Sopenharmony_ci cres = PyObject_CallMethod(self->stream, 14157db96d56Sopenharmony_ci method, "i", sizehint); 14167db96d56Sopenharmony_ci if (cres == NULL) 14177db96d56Sopenharmony_ci goto errorexit; 14187db96d56Sopenharmony_ci 14197db96d56Sopenharmony_ci if (!PyBytes_Check(cres)) { 14207db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 14217db96d56Sopenharmony_ci "stream function returned a " 14227db96d56Sopenharmony_ci "non-bytes object (%.100s)", 14237db96d56Sopenharmony_ci Py_TYPE(cres)->tp_name); 14247db96d56Sopenharmony_ci goto errorexit; 14257db96d56Sopenharmony_ci } 14267db96d56Sopenharmony_ci 14277db96d56Sopenharmony_ci endoffile = (PyBytes_GET_SIZE(cres) == 0); 14287db96d56Sopenharmony_ci 14297db96d56Sopenharmony_ci if (self->pendingsize > 0) { 14307db96d56Sopenharmony_ci PyObject *ctr; 14317db96d56Sopenharmony_ci char *ctrdata; 14327db96d56Sopenharmony_ci 14337db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) { 14347db96d56Sopenharmony_ci PyErr_NoMemory(); 14357db96d56Sopenharmony_ci goto errorexit; 14367db96d56Sopenharmony_ci } 14377db96d56Sopenharmony_ci rsize = PyBytes_GET_SIZE(cres) + self->pendingsize; 14387db96d56Sopenharmony_ci ctr = PyBytes_FromStringAndSize(NULL, rsize); 14397db96d56Sopenharmony_ci if (ctr == NULL) 14407db96d56Sopenharmony_ci goto errorexit; 14417db96d56Sopenharmony_ci ctrdata = PyBytes_AS_STRING(ctr); 14427db96d56Sopenharmony_ci memcpy(ctrdata, self->pending, self->pendingsize); 14437db96d56Sopenharmony_ci memcpy(ctrdata + self->pendingsize, 14447db96d56Sopenharmony_ci PyBytes_AS_STRING(cres), 14457db96d56Sopenharmony_ci PyBytes_GET_SIZE(cres)); 14467db96d56Sopenharmony_ci Py_DECREF(cres); 14477db96d56Sopenharmony_ci cres = ctr; 14487db96d56Sopenharmony_ci self->pendingsize = 0; 14497db96d56Sopenharmony_ci } 14507db96d56Sopenharmony_ci 14517db96d56Sopenharmony_ci rsize = PyBytes_GET_SIZE(cres); 14527db96d56Sopenharmony_ci if (decoder_prepare_buffer(&buf, PyBytes_AS_STRING(cres), 14537db96d56Sopenharmony_ci rsize) != 0) 14547db96d56Sopenharmony_ci goto errorexit; 14557db96d56Sopenharmony_ci 14567db96d56Sopenharmony_ci if (rsize > 0 && decoder_feed_buffer( 14577db96d56Sopenharmony_ci (MultibyteStatefulDecoderContext *)self, &buf)) 14587db96d56Sopenharmony_ci goto errorexit; 14597db96d56Sopenharmony_ci 14607db96d56Sopenharmony_ci if (endoffile || sizehint < 0) { 14617db96d56Sopenharmony_ci if (buf.inbuf < buf.inbuf_end && 14627db96d56Sopenharmony_ci multibytecodec_decerror(self->codec, &self->state, 14637db96d56Sopenharmony_ci &buf, self->errors, MBERR_TOOFEW)) 14647db96d56Sopenharmony_ci goto errorexit; 14657db96d56Sopenharmony_ci } 14667db96d56Sopenharmony_ci 14677db96d56Sopenharmony_ci if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */ 14687db96d56Sopenharmony_ci if (decoder_append_pending(STATEFUL_DCTX(self), 14697db96d56Sopenharmony_ci &buf) != 0) 14707db96d56Sopenharmony_ci goto errorexit; 14717db96d56Sopenharmony_ci } 14727db96d56Sopenharmony_ci 14737db96d56Sopenharmony_ci Py_DECREF(cres); 14747db96d56Sopenharmony_ci cres = NULL; 14757db96d56Sopenharmony_ci 14767db96d56Sopenharmony_ci if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0) 14777db96d56Sopenharmony_ci break; 14787db96d56Sopenharmony_ci 14797db96d56Sopenharmony_ci sizehint = 1; /* read 1 more byte and retry */ 14807db96d56Sopenharmony_ci } 14817db96d56Sopenharmony_ci 14827db96d56Sopenharmony_ci res = _PyUnicodeWriter_Finish(&buf.writer); 14837db96d56Sopenharmony_ci if (res == NULL) 14847db96d56Sopenharmony_ci goto errorexit; 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_ci Py_XDECREF(cres); 14877db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 14887db96d56Sopenharmony_ci return res; 14897db96d56Sopenharmony_ci 14907db96d56Sopenharmony_cierrorexit: 14917db96d56Sopenharmony_ci Py_XDECREF(cres); 14927db96d56Sopenharmony_ci Py_XDECREF(buf.excobj); 14937db96d56Sopenharmony_ci _PyUnicodeWriter_Dealloc(&buf.writer); 14947db96d56Sopenharmony_ci return NULL; 14957db96d56Sopenharmony_ci} 14967db96d56Sopenharmony_ci 14977db96d56Sopenharmony_ci/*[clinic input] 14987db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamReader.read 14997db96d56Sopenharmony_ci 15007db96d56Sopenharmony_ci sizeobj: object = None 15017db96d56Sopenharmony_ci / 15027db96d56Sopenharmony_ci[clinic start generated code]*/ 15037db96d56Sopenharmony_ci 15047db96d56Sopenharmony_cistatic PyObject * 15057db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, 15067db96d56Sopenharmony_ci PyObject *sizeobj) 15077db96d56Sopenharmony_ci/*[clinic end generated code: output=35621eb75355d5b8 input=015b0d3ff2fca485]*/ 15087db96d56Sopenharmony_ci{ 15097db96d56Sopenharmony_ci Py_ssize_t size; 15107db96d56Sopenharmony_ci 15117db96d56Sopenharmony_ci if (sizeobj == Py_None) 15127db96d56Sopenharmony_ci size = -1; 15137db96d56Sopenharmony_ci else if (PyLong_Check(sizeobj)) 15147db96d56Sopenharmony_ci size = PyLong_AsSsize_t(sizeobj); 15157db96d56Sopenharmony_ci else { 15167db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); 15177db96d56Sopenharmony_ci return NULL; 15187db96d56Sopenharmony_ci } 15197db96d56Sopenharmony_ci 15207db96d56Sopenharmony_ci if (size == -1 && PyErr_Occurred()) 15217db96d56Sopenharmony_ci return NULL; 15227db96d56Sopenharmony_ci 15237db96d56Sopenharmony_ci return mbstreamreader_iread(self, "read", size); 15247db96d56Sopenharmony_ci} 15257db96d56Sopenharmony_ci 15267db96d56Sopenharmony_ci/*[clinic input] 15277db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamReader.readline 15287db96d56Sopenharmony_ci 15297db96d56Sopenharmony_ci sizeobj: object = None 15307db96d56Sopenharmony_ci / 15317db96d56Sopenharmony_ci[clinic start generated code]*/ 15327db96d56Sopenharmony_ci 15337db96d56Sopenharmony_cistatic PyObject * 15347db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, 15357db96d56Sopenharmony_ci PyObject *sizeobj) 15367db96d56Sopenharmony_ci/*[clinic end generated code: output=4fbfaae1ed457a11 input=41ccc64f9bb0cec3]*/ 15377db96d56Sopenharmony_ci{ 15387db96d56Sopenharmony_ci Py_ssize_t size; 15397db96d56Sopenharmony_ci 15407db96d56Sopenharmony_ci if (sizeobj == Py_None) 15417db96d56Sopenharmony_ci size = -1; 15427db96d56Sopenharmony_ci else if (PyLong_Check(sizeobj)) 15437db96d56Sopenharmony_ci size = PyLong_AsSsize_t(sizeobj); 15447db96d56Sopenharmony_ci else { 15457db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); 15467db96d56Sopenharmony_ci return NULL; 15477db96d56Sopenharmony_ci } 15487db96d56Sopenharmony_ci 15497db96d56Sopenharmony_ci if (size == -1 && PyErr_Occurred()) 15507db96d56Sopenharmony_ci return NULL; 15517db96d56Sopenharmony_ci 15527db96d56Sopenharmony_ci return mbstreamreader_iread(self, "readline", size); 15537db96d56Sopenharmony_ci} 15547db96d56Sopenharmony_ci 15557db96d56Sopenharmony_ci/*[clinic input] 15567db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamReader.readlines 15577db96d56Sopenharmony_ci 15587db96d56Sopenharmony_ci sizehintobj: object = None 15597db96d56Sopenharmony_ci / 15607db96d56Sopenharmony_ci[clinic start generated code]*/ 15617db96d56Sopenharmony_ci 15627db96d56Sopenharmony_cistatic PyObject * 15637db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, 15647db96d56Sopenharmony_ci PyObject *sizehintobj) 15657db96d56Sopenharmony_ci/*[clinic end generated code: output=e7c4310768ed2ad4 input=54932f5d4d88e880]*/ 15667db96d56Sopenharmony_ci{ 15677db96d56Sopenharmony_ci PyObject *r, *sr; 15687db96d56Sopenharmony_ci Py_ssize_t sizehint; 15697db96d56Sopenharmony_ci 15707db96d56Sopenharmony_ci if (sizehintobj == Py_None) 15717db96d56Sopenharmony_ci sizehint = -1; 15727db96d56Sopenharmony_ci else if (PyLong_Check(sizehintobj)) 15737db96d56Sopenharmony_ci sizehint = PyLong_AsSsize_t(sizehintobj); 15747db96d56Sopenharmony_ci else { 15757db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); 15767db96d56Sopenharmony_ci return NULL; 15777db96d56Sopenharmony_ci } 15787db96d56Sopenharmony_ci 15797db96d56Sopenharmony_ci if (sizehint == -1 && PyErr_Occurred()) 15807db96d56Sopenharmony_ci return NULL; 15817db96d56Sopenharmony_ci 15827db96d56Sopenharmony_ci r = mbstreamreader_iread(self, "read", sizehint); 15837db96d56Sopenharmony_ci if (r == NULL) 15847db96d56Sopenharmony_ci return NULL; 15857db96d56Sopenharmony_ci 15867db96d56Sopenharmony_ci sr = PyUnicode_Splitlines(r, 1); 15877db96d56Sopenharmony_ci Py_DECREF(r); 15887db96d56Sopenharmony_ci return sr; 15897db96d56Sopenharmony_ci} 15907db96d56Sopenharmony_ci 15917db96d56Sopenharmony_ci/*[clinic input] 15927db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamReader.reset 15937db96d56Sopenharmony_ci[clinic start generated code]*/ 15947db96d56Sopenharmony_ci 15957db96d56Sopenharmony_cistatic PyObject * 15967db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self) 15977db96d56Sopenharmony_ci/*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/ 15987db96d56Sopenharmony_ci{ 15997db96d56Sopenharmony_ci if (self->codec->decreset != NULL && 16007db96d56Sopenharmony_ci self->codec->decreset(&self->state, self->codec->config) != 0) 16017db96d56Sopenharmony_ci return NULL; 16027db96d56Sopenharmony_ci self->pendingsize = 0; 16037db96d56Sopenharmony_ci 16047db96d56Sopenharmony_ci Py_RETURN_NONE; 16057db96d56Sopenharmony_ci} 16067db96d56Sopenharmony_ci 16077db96d56Sopenharmony_cistatic struct PyMethodDef mbstreamreader_methods[] = { 16087db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF 16097db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF 16107db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF 16117db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF 16127db96d56Sopenharmony_ci {NULL, NULL}, 16137db96d56Sopenharmony_ci}; 16147db96d56Sopenharmony_ci 16157db96d56Sopenharmony_cistatic PyMemberDef mbstreamreader_members[] = { 16167db96d56Sopenharmony_ci {"stream", T_OBJECT, 16177db96d56Sopenharmony_ci offsetof(MultibyteStreamReaderObject, stream), 16187db96d56Sopenharmony_ci READONLY, NULL}, 16197db96d56Sopenharmony_ci {NULL,} 16207db96d56Sopenharmony_ci}; 16217db96d56Sopenharmony_ci 16227db96d56Sopenharmony_cistatic PyObject * 16237db96d56Sopenharmony_cimbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 16247db96d56Sopenharmony_ci{ 16257db96d56Sopenharmony_ci MultibyteStreamReaderObject *self; 16267db96d56Sopenharmony_ci PyObject *stream, *codec = NULL; 16277db96d56Sopenharmony_ci char *errors = NULL; 16287db96d56Sopenharmony_ci 16297db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader", 16307db96d56Sopenharmony_ci streamkwarglist, &stream, &errors)) 16317db96d56Sopenharmony_ci return NULL; 16327db96d56Sopenharmony_ci 16337db96d56Sopenharmony_ci self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0); 16347db96d56Sopenharmony_ci if (self == NULL) 16357db96d56Sopenharmony_ci return NULL; 16367db96d56Sopenharmony_ci 16377db96d56Sopenharmony_ci codec = PyObject_GetAttrString((PyObject *)type, "codec"); 16387db96d56Sopenharmony_ci if (codec == NULL) 16397db96d56Sopenharmony_ci goto errorexit; 16407db96d56Sopenharmony_ci 16417db96d56Sopenharmony_ci _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); 16427db96d56Sopenharmony_ci if (!MultibyteCodec_Check(state, codec)) { 16437db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 16447db96d56Sopenharmony_ci goto errorexit; 16457db96d56Sopenharmony_ci } 16467db96d56Sopenharmony_ci 16477db96d56Sopenharmony_ci self->codec = ((MultibyteCodecObject *)codec)->codec; 16487db96d56Sopenharmony_ci self->stream = stream; 16497db96d56Sopenharmony_ci Py_INCREF(stream); 16507db96d56Sopenharmony_ci self->pendingsize = 0; 16517db96d56Sopenharmony_ci self->errors = internal_error_callback(errors); 16527db96d56Sopenharmony_ci if (self->errors == NULL) 16537db96d56Sopenharmony_ci goto errorexit; 16547db96d56Sopenharmony_ci if (self->codec->decinit != NULL && 16557db96d56Sopenharmony_ci self->codec->decinit(&self->state, self->codec->config) != 0) 16567db96d56Sopenharmony_ci goto errorexit; 16577db96d56Sopenharmony_ci 16587db96d56Sopenharmony_ci Py_DECREF(codec); 16597db96d56Sopenharmony_ci return (PyObject *)self; 16607db96d56Sopenharmony_ci 16617db96d56Sopenharmony_cierrorexit: 16627db96d56Sopenharmony_ci Py_XDECREF(self); 16637db96d56Sopenharmony_ci Py_XDECREF(codec); 16647db96d56Sopenharmony_ci return NULL; 16657db96d56Sopenharmony_ci} 16667db96d56Sopenharmony_ci 16677db96d56Sopenharmony_cistatic int 16687db96d56Sopenharmony_cimbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds) 16697db96d56Sopenharmony_ci{ 16707db96d56Sopenharmony_ci return 0; 16717db96d56Sopenharmony_ci} 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_cistatic int 16747db96d56Sopenharmony_cimbstreamreader_traverse(MultibyteStreamReaderObject *self, 16757db96d56Sopenharmony_ci visitproc visit, void *arg) 16767db96d56Sopenharmony_ci{ 16777db96d56Sopenharmony_ci if (ERROR_ISCUSTOM(self->errors)) 16787db96d56Sopenharmony_ci Py_VISIT(self->errors); 16797db96d56Sopenharmony_ci Py_VISIT(self->stream); 16807db96d56Sopenharmony_ci return 0; 16817db96d56Sopenharmony_ci} 16827db96d56Sopenharmony_ci 16837db96d56Sopenharmony_cistatic void 16847db96d56Sopenharmony_cimbstreamreader_dealloc(MultibyteStreamReaderObject *self) 16857db96d56Sopenharmony_ci{ 16867db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 16877db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 16887db96d56Sopenharmony_ci ERROR_DECREF(self->errors); 16897db96d56Sopenharmony_ci Py_XDECREF(self->stream); 16907db96d56Sopenharmony_ci tp->tp_free(self); 16917db96d56Sopenharmony_ci Py_DECREF(tp); 16927db96d56Sopenharmony_ci} 16937db96d56Sopenharmony_ci 16947db96d56Sopenharmony_cistatic PyType_Slot reader_slots[] = { 16957db96d56Sopenharmony_ci {Py_tp_dealloc, mbstreamreader_dealloc}, 16967db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 16977db96d56Sopenharmony_ci {Py_tp_traverse, mbstreamreader_traverse}, 16987db96d56Sopenharmony_ci {Py_tp_methods, mbstreamreader_methods}, 16997db96d56Sopenharmony_ci {Py_tp_members, mbstreamreader_members}, 17007db96d56Sopenharmony_ci {Py_tp_getset, codecctx_getsets}, 17017db96d56Sopenharmony_ci {Py_tp_init, mbstreamreader_init}, 17027db96d56Sopenharmony_ci {Py_tp_new, mbstreamreader_new}, 17037db96d56Sopenharmony_ci {0, NULL}, 17047db96d56Sopenharmony_ci}; 17057db96d56Sopenharmony_ci 17067db96d56Sopenharmony_cistatic PyType_Spec reader_spec = { 17077db96d56Sopenharmony_ci .name = MODULE_NAME ".MultibyteStreamReader", 17087db96d56Sopenharmony_ci .basicsize = sizeof(MultibyteStreamReaderObject), 17097db96d56Sopenharmony_ci .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | 17107db96d56Sopenharmony_ci Py_TPFLAGS_IMMUTABLETYPE), 17117db96d56Sopenharmony_ci .slots = reader_slots, 17127db96d56Sopenharmony_ci}; 17137db96d56Sopenharmony_ci 17147db96d56Sopenharmony_cistatic int 17157db96d56Sopenharmony_cimbstreamwriter_iwrite(MultibyteStreamWriterObject *self, 17167db96d56Sopenharmony_ci PyObject *unistr, PyObject *str_write) 17177db96d56Sopenharmony_ci{ 17187db96d56Sopenharmony_ci PyObject *str, *wr; 17197db96d56Sopenharmony_ci 17207db96d56Sopenharmony_ci str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0); 17217db96d56Sopenharmony_ci if (str == NULL) 17227db96d56Sopenharmony_ci return -1; 17237db96d56Sopenharmony_ci 17247db96d56Sopenharmony_ci wr = _PyObject_CallMethodOneArg(self->stream, str_write, str); 17257db96d56Sopenharmony_ci Py_DECREF(str); 17267db96d56Sopenharmony_ci if (wr == NULL) 17277db96d56Sopenharmony_ci return -1; 17287db96d56Sopenharmony_ci 17297db96d56Sopenharmony_ci Py_DECREF(wr); 17307db96d56Sopenharmony_ci return 0; 17317db96d56Sopenharmony_ci} 17327db96d56Sopenharmony_ci 17337db96d56Sopenharmony_ci/*[clinic input] 17347db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamWriter.write 17357db96d56Sopenharmony_ci 17367db96d56Sopenharmony_ci cls: defining_class 17377db96d56Sopenharmony_ci strobj: object 17387db96d56Sopenharmony_ci / 17397db96d56Sopenharmony_ci[clinic start generated code]*/ 17407db96d56Sopenharmony_ci 17417db96d56Sopenharmony_cistatic PyObject * 17427db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamWriter_write_impl(MultibyteStreamWriterObject *self, 17437db96d56Sopenharmony_ci PyTypeObject *cls, 17447db96d56Sopenharmony_ci PyObject *strobj) 17457db96d56Sopenharmony_ci/*[clinic end generated code: output=68ade3aea26410ac input=199f26f68bd8425a]*/ 17467db96d56Sopenharmony_ci{ 17477db96d56Sopenharmony_ci _multibytecodec_state *state = PyType_GetModuleState(cls); 17487db96d56Sopenharmony_ci assert(state != NULL); 17497db96d56Sopenharmony_ci if (mbstreamwriter_iwrite(self, strobj, state->str_write)) { 17507db96d56Sopenharmony_ci return NULL; 17517db96d56Sopenharmony_ci } 17527db96d56Sopenharmony_ci Py_RETURN_NONE; 17537db96d56Sopenharmony_ci} 17547db96d56Sopenharmony_ci 17557db96d56Sopenharmony_ci/*[clinic input] 17567db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamWriter.writelines 17577db96d56Sopenharmony_ci 17587db96d56Sopenharmony_ci cls: defining_class 17597db96d56Sopenharmony_ci lines: object 17607db96d56Sopenharmony_ci / 17617db96d56Sopenharmony_ci[clinic start generated code]*/ 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_cistatic PyObject * 17647db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamWriter_writelines_impl(MultibyteStreamWriterObject *self, 17657db96d56Sopenharmony_ci PyTypeObject *cls, 17667db96d56Sopenharmony_ci PyObject *lines) 17677db96d56Sopenharmony_ci/*[clinic end generated code: output=b4c99d2cf23ffb88 input=a6d5fe7c74972a34]*/ 17687db96d56Sopenharmony_ci{ 17697db96d56Sopenharmony_ci PyObject *strobj; 17707db96d56Sopenharmony_ci int i, r; 17717db96d56Sopenharmony_ci 17727db96d56Sopenharmony_ci if (!PySequence_Check(lines)) { 17737db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 17747db96d56Sopenharmony_ci "arg must be a sequence object"); 17757db96d56Sopenharmony_ci return NULL; 17767db96d56Sopenharmony_ci } 17777db96d56Sopenharmony_ci 17787db96d56Sopenharmony_ci _multibytecodec_state *state = PyType_GetModuleState(cls); 17797db96d56Sopenharmony_ci assert(state != NULL); 17807db96d56Sopenharmony_ci for (i = 0; i < PySequence_Length(lines); i++) { 17817db96d56Sopenharmony_ci /* length can be changed even within this loop */ 17827db96d56Sopenharmony_ci strobj = PySequence_GetItem(lines, i); 17837db96d56Sopenharmony_ci if (strobj == NULL) 17847db96d56Sopenharmony_ci return NULL; 17857db96d56Sopenharmony_ci 17867db96d56Sopenharmony_ci r = mbstreamwriter_iwrite(self, strobj, state->str_write); 17877db96d56Sopenharmony_ci Py_DECREF(strobj); 17887db96d56Sopenharmony_ci if (r == -1) 17897db96d56Sopenharmony_ci return NULL; 17907db96d56Sopenharmony_ci } 17917db96d56Sopenharmony_ci /* PySequence_Length() can fail */ 17927db96d56Sopenharmony_ci if (PyErr_Occurred()) 17937db96d56Sopenharmony_ci return NULL; 17947db96d56Sopenharmony_ci 17957db96d56Sopenharmony_ci Py_RETURN_NONE; 17967db96d56Sopenharmony_ci} 17977db96d56Sopenharmony_ci 17987db96d56Sopenharmony_ci/*[clinic input] 17997db96d56Sopenharmony_ci _multibytecodec.MultibyteStreamWriter.reset 18007db96d56Sopenharmony_ci 18017db96d56Sopenharmony_ci cls: defining_class 18027db96d56Sopenharmony_ci / 18037db96d56Sopenharmony_ci 18047db96d56Sopenharmony_ci[clinic start generated code]*/ 18057db96d56Sopenharmony_ci 18067db96d56Sopenharmony_cistatic PyObject * 18077db96d56Sopenharmony_ci_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self, 18087db96d56Sopenharmony_ci PyTypeObject *cls) 18097db96d56Sopenharmony_ci/*[clinic end generated code: output=32ef224c2a38aa3d input=28af6a9cd38d1979]*/ 18107db96d56Sopenharmony_ci{ 18117db96d56Sopenharmony_ci PyObject *pwrt; 18127db96d56Sopenharmony_ci 18137db96d56Sopenharmony_ci if (!self->pending) 18147db96d56Sopenharmony_ci Py_RETURN_NONE; 18157db96d56Sopenharmony_ci 18167db96d56Sopenharmony_ci pwrt = multibytecodec_encode(self->codec, &self->state, 18177db96d56Sopenharmony_ci self->pending, NULL, self->errors, 18187db96d56Sopenharmony_ci MBENC_FLUSH | MBENC_RESET); 18197db96d56Sopenharmony_ci /* some pending buffer can be truncated when UnicodeEncodeError is 18207db96d56Sopenharmony_ci * raised on 'strict' mode. but, 'reset' method is designed to 18217db96d56Sopenharmony_ci * reset the pending buffer or states so failed string sequence 18227db96d56Sopenharmony_ci * ought to be missed */ 18237db96d56Sopenharmony_ci Py_CLEAR(self->pending); 18247db96d56Sopenharmony_ci if (pwrt == NULL) 18257db96d56Sopenharmony_ci return NULL; 18267db96d56Sopenharmony_ci 18277db96d56Sopenharmony_ci assert(PyBytes_Check(pwrt)); 18287db96d56Sopenharmony_ci 18297db96d56Sopenharmony_ci _multibytecodec_state *state = PyType_GetModuleState(cls); 18307db96d56Sopenharmony_ci assert(state != NULL); 18317db96d56Sopenharmony_ci 18327db96d56Sopenharmony_ci if (PyBytes_Size(pwrt) > 0) { 18337db96d56Sopenharmony_ci PyObject *wr; 18347db96d56Sopenharmony_ci 18357db96d56Sopenharmony_ci wr = _PyObject_CallMethodOneArg(self->stream, state->str_write, pwrt); 18367db96d56Sopenharmony_ci if (wr == NULL) { 18377db96d56Sopenharmony_ci Py_DECREF(pwrt); 18387db96d56Sopenharmony_ci return NULL; 18397db96d56Sopenharmony_ci } 18407db96d56Sopenharmony_ci } 18417db96d56Sopenharmony_ci Py_DECREF(pwrt); 18427db96d56Sopenharmony_ci 18437db96d56Sopenharmony_ci Py_RETURN_NONE; 18447db96d56Sopenharmony_ci} 18457db96d56Sopenharmony_ci 18467db96d56Sopenharmony_cistatic PyObject * 18477db96d56Sopenharmony_cimbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 18487db96d56Sopenharmony_ci{ 18497db96d56Sopenharmony_ci MultibyteStreamWriterObject *self; 18507db96d56Sopenharmony_ci PyObject *stream, *codec = NULL; 18517db96d56Sopenharmony_ci char *errors = NULL; 18527db96d56Sopenharmony_ci 18537db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter", 18547db96d56Sopenharmony_ci streamkwarglist, &stream, &errors)) 18557db96d56Sopenharmony_ci return NULL; 18567db96d56Sopenharmony_ci 18577db96d56Sopenharmony_ci self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0); 18587db96d56Sopenharmony_ci if (self == NULL) 18597db96d56Sopenharmony_ci return NULL; 18607db96d56Sopenharmony_ci 18617db96d56Sopenharmony_ci codec = PyObject_GetAttrString((PyObject *)type, "codec"); 18627db96d56Sopenharmony_ci if (codec == NULL) 18637db96d56Sopenharmony_ci goto errorexit; 18647db96d56Sopenharmony_ci 18657db96d56Sopenharmony_ci _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); 18667db96d56Sopenharmony_ci if (!MultibyteCodec_Check(state, codec)) { 18677db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 18687db96d56Sopenharmony_ci goto errorexit; 18697db96d56Sopenharmony_ci } 18707db96d56Sopenharmony_ci 18717db96d56Sopenharmony_ci self->codec = ((MultibyteCodecObject *)codec)->codec; 18727db96d56Sopenharmony_ci self->stream = stream; 18737db96d56Sopenharmony_ci Py_INCREF(stream); 18747db96d56Sopenharmony_ci self->pending = NULL; 18757db96d56Sopenharmony_ci self->errors = internal_error_callback(errors); 18767db96d56Sopenharmony_ci if (self->errors == NULL) 18777db96d56Sopenharmony_ci goto errorexit; 18787db96d56Sopenharmony_ci if (self->codec->encinit != NULL && 18797db96d56Sopenharmony_ci self->codec->encinit(&self->state, self->codec->config) != 0) 18807db96d56Sopenharmony_ci goto errorexit; 18817db96d56Sopenharmony_ci 18827db96d56Sopenharmony_ci Py_DECREF(codec); 18837db96d56Sopenharmony_ci return (PyObject *)self; 18847db96d56Sopenharmony_ci 18857db96d56Sopenharmony_cierrorexit: 18867db96d56Sopenharmony_ci Py_XDECREF(self); 18877db96d56Sopenharmony_ci Py_XDECREF(codec); 18887db96d56Sopenharmony_ci return NULL; 18897db96d56Sopenharmony_ci} 18907db96d56Sopenharmony_ci 18917db96d56Sopenharmony_cistatic int 18927db96d56Sopenharmony_cimbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds) 18937db96d56Sopenharmony_ci{ 18947db96d56Sopenharmony_ci return 0; 18957db96d56Sopenharmony_ci} 18967db96d56Sopenharmony_ci 18977db96d56Sopenharmony_cistatic int 18987db96d56Sopenharmony_cimbstreamwriter_traverse(MultibyteStreamWriterObject *self, 18997db96d56Sopenharmony_ci visitproc visit, void *arg) 19007db96d56Sopenharmony_ci{ 19017db96d56Sopenharmony_ci if (ERROR_ISCUSTOM(self->errors)) 19027db96d56Sopenharmony_ci Py_VISIT(self->errors); 19037db96d56Sopenharmony_ci Py_VISIT(self->stream); 19047db96d56Sopenharmony_ci return 0; 19057db96d56Sopenharmony_ci} 19067db96d56Sopenharmony_ci 19077db96d56Sopenharmony_cistatic void 19087db96d56Sopenharmony_cimbstreamwriter_dealloc(MultibyteStreamWriterObject *self) 19097db96d56Sopenharmony_ci{ 19107db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 19117db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 19127db96d56Sopenharmony_ci ERROR_DECREF(self->errors); 19137db96d56Sopenharmony_ci Py_XDECREF(self->stream); 19147db96d56Sopenharmony_ci tp->tp_free(self); 19157db96d56Sopenharmony_ci Py_DECREF(tp); 19167db96d56Sopenharmony_ci} 19177db96d56Sopenharmony_ci 19187db96d56Sopenharmony_cistatic struct PyMethodDef mbstreamwriter_methods[] = { 19197db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF 19207db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF 19217db96d56Sopenharmony_ci _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF 19227db96d56Sopenharmony_ci {NULL, NULL}, 19237db96d56Sopenharmony_ci}; 19247db96d56Sopenharmony_ci 19257db96d56Sopenharmony_cistatic PyMemberDef mbstreamwriter_members[] = { 19267db96d56Sopenharmony_ci {"stream", T_OBJECT, 19277db96d56Sopenharmony_ci offsetof(MultibyteStreamWriterObject, stream), 19287db96d56Sopenharmony_ci READONLY, NULL}, 19297db96d56Sopenharmony_ci {NULL,} 19307db96d56Sopenharmony_ci}; 19317db96d56Sopenharmony_ci 19327db96d56Sopenharmony_cistatic PyType_Slot writer_slots[] = { 19337db96d56Sopenharmony_ci {Py_tp_dealloc, mbstreamwriter_dealloc}, 19347db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 19357db96d56Sopenharmony_ci {Py_tp_traverse, mbstreamwriter_traverse}, 19367db96d56Sopenharmony_ci {Py_tp_methods, mbstreamwriter_methods}, 19377db96d56Sopenharmony_ci {Py_tp_members, mbstreamwriter_members}, 19387db96d56Sopenharmony_ci {Py_tp_getset, codecctx_getsets}, 19397db96d56Sopenharmony_ci {Py_tp_init, mbstreamwriter_init}, 19407db96d56Sopenharmony_ci {Py_tp_new, mbstreamwriter_new}, 19417db96d56Sopenharmony_ci {0, NULL}, 19427db96d56Sopenharmony_ci}; 19437db96d56Sopenharmony_ci 19447db96d56Sopenharmony_cistatic PyType_Spec writer_spec = { 19457db96d56Sopenharmony_ci .name = MODULE_NAME ".MultibyteStreamWriter", 19467db96d56Sopenharmony_ci .basicsize = sizeof(MultibyteStreamWriterObject), 19477db96d56Sopenharmony_ci .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | 19487db96d56Sopenharmony_ci Py_TPFLAGS_IMMUTABLETYPE), 19497db96d56Sopenharmony_ci .slots = writer_slots, 19507db96d56Sopenharmony_ci}; 19517db96d56Sopenharmony_ci 19527db96d56Sopenharmony_ci 19537db96d56Sopenharmony_ci/*[clinic input] 19547db96d56Sopenharmony_ci_multibytecodec.__create_codec 19557db96d56Sopenharmony_ci 19567db96d56Sopenharmony_ci arg: object 19577db96d56Sopenharmony_ci / 19587db96d56Sopenharmony_ci[clinic start generated code]*/ 19597db96d56Sopenharmony_ci 19607db96d56Sopenharmony_cistatic PyObject * 19617db96d56Sopenharmony_ci_multibytecodec___create_codec(PyObject *module, PyObject *arg) 19627db96d56Sopenharmony_ci/*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/ 19637db96d56Sopenharmony_ci{ 19647db96d56Sopenharmony_ci MultibyteCodecObject *self; 19657db96d56Sopenharmony_ci MultibyteCodec *codec; 19667db96d56Sopenharmony_ci 19677db96d56Sopenharmony_ci if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) { 19687db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "argument type invalid"); 19697db96d56Sopenharmony_ci return NULL; 19707db96d56Sopenharmony_ci } 19717db96d56Sopenharmony_ci 19727db96d56Sopenharmony_ci codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME); 19737db96d56Sopenharmony_ci if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) 19747db96d56Sopenharmony_ci return NULL; 19757db96d56Sopenharmony_ci 19767db96d56Sopenharmony_ci _multibytecodec_state *state = _multibytecodec_get_state(module); 19777db96d56Sopenharmony_ci self = PyObject_GC_New(MultibyteCodecObject, state->multibytecodec_type); 19787db96d56Sopenharmony_ci if (self == NULL) 19797db96d56Sopenharmony_ci return NULL; 19807db96d56Sopenharmony_ci self->codec = codec; 19817db96d56Sopenharmony_ci 19827db96d56Sopenharmony_ci PyObject_GC_Track(self); 19837db96d56Sopenharmony_ci return (PyObject *)self; 19847db96d56Sopenharmony_ci} 19857db96d56Sopenharmony_ci 19867db96d56Sopenharmony_cistatic int 19877db96d56Sopenharmony_ci_multibytecodec_traverse(PyObject *mod, visitproc visit, void *arg) 19887db96d56Sopenharmony_ci{ 19897db96d56Sopenharmony_ci _multibytecodec_state *state = _multibytecodec_get_state(mod); 19907db96d56Sopenharmony_ci Py_VISIT(state->multibytecodec_type); 19917db96d56Sopenharmony_ci Py_VISIT(state->encoder_type); 19927db96d56Sopenharmony_ci Py_VISIT(state->decoder_type); 19937db96d56Sopenharmony_ci Py_VISIT(state->reader_type); 19947db96d56Sopenharmony_ci Py_VISIT(state->writer_type); 19957db96d56Sopenharmony_ci return 0; 19967db96d56Sopenharmony_ci} 19977db96d56Sopenharmony_ci 19987db96d56Sopenharmony_cistatic int 19997db96d56Sopenharmony_ci_multibytecodec_clear(PyObject *mod) 20007db96d56Sopenharmony_ci{ 20017db96d56Sopenharmony_ci _multibytecodec_state *state = _multibytecodec_get_state(mod); 20027db96d56Sopenharmony_ci Py_CLEAR(state->multibytecodec_type); 20037db96d56Sopenharmony_ci Py_CLEAR(state->encoder_type); 20047db96d56Sopenharmony_ci Py_CLEAR(state->decoder_type); 20057db96d56Sopenharmony_ci Py_CLEAR(state->reader_type); 20067db96d56Sopenharmony_ci Py_CLEAR(state->writer_type); 20077db96d56Sopenharmony_ci Py_CLEAR(state->str_write); 20087db96d56Sopenharmony_ci return 0; 20097db96d56Sopenharmony_ci} 20107db96d56Sopenharmony_ci 20117db96d56Sopenharmony_cistatic void 20127db96d56Sopenharmony_ci_multibytecodec_free(void *mod) 20137db96d56Sopenharmony_ci{ 20147db96d56Sopenharmony_ci _multibytecodec_clear((PyObject *)mod); 20157db96d56Sopenharmony_ci} 20167db96d56Sopenharmony_ci 20177db96d56Sopenharmony_ci#define CREATE_TYPE(module, type, spec) \ 20187db96d56Sopenharmony_ci do { \ 20197db96d56Sopenharmony_ci type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ 20207db96d56Sopenharmony_ci if (!type) { \ 20217db96d56Sopenharmony_ci return -1; \ 20227db96d56Sopenharmony_ci } \ 20237db96d56Sopenharmony_ci } while (0) 20247db96d56Sopenharmony_ci 20257db96d56Sopenharmony_ci#define ADD_TYPE(module, type) \ 20267db96d56Sopenharmony_ci do { \ 20277db96d56Sopenharmony_ci if (PyModule_AddType(module, type) < 0) { \ 20287db96d56Sopenharmony_ci return -1; \ 20297db96d56Sopenharmony_ci } \ 20307db96d56Sopenharmony_ci } while (0) 20317db96d56Sopenharmony_ci 20327db96d56Sopenharmony_cistatic int 20337db96d56Sopenharmony_ci_multibytecodec_exec(PyObject *mod) 20347db96d56Sopenharmony_ci{ 20357db96d56Sopenharmony_ci _multibytecodec_state *state = _multibytecodec_get_state(mod); 20367db96d56Sopenharmony_ci state->str_write = PyUnicode_InternFromString("write"); 20377db96d56Sopenharmony_ci if (state->str_write == NULL) { 20387db96d56Sopenharmony_ci return -1; 20397db96d56Sopenharmony_ci } 20407db96d56Sopenharmony_ci CREATE_TYPE(mod, state->multibytecodec_type, &multibytecodec_spec); 20417db96d56Sopenharmony_ci CREATE_TYPE(mod, state->encoder_type, &encoder_spec); 20427db96d56Sopenharmony_ci CREATE_TYPE(mod, state->decoder_type, &decoder_spec); 20437db96d56Sopenharmony_ci CREATE_TYPE(mod, state->reader_type, &reader_spec); 20447db96d56Sopenharmony_ci CREATE_TYPE(mod, state->writer_type, &writer_spec); 20457db96d56Sopenharmony_ci 20467db96d56Sopenharmony_ci ADD_TYPE(mod, state->encoder_type); 20477db96d56Sopenharmony_ci ADD_TYPE(mod, state->decoder_type); 20487db96d56Sopenharmony_ci ADD_TYPE(mod, state->reader_type); 20497db96d56Sopenharmony_ci ADD_TYPE(mod, state->writer_type); 20507db96d56Sopenharmony_ci return 0; 20517db96d56Sopenharmony_ci} 20527db96d56Sopenharmony_ci 20537db96d56Sopenharmony_ci#undef CREATE_TYPE 20547db96d56Sopenharmony_ci#undef ADD_TYPE 20557db96d56Sopenharmony_ci 20567db96d56Sopenharmony_cistatic struct PyMethodDef _multibytecodec_methods[] = { 20577db96d56Sopenharmony_ci _MULTIBYTECODEC___CREATE_CODEC_METHODDEF 20587db96d56Sopenharmony_ci {NULL, NULL}, 20597db96d56Sopenharmony_ci}; 20607db96d56Sopenharmony_ci 20617db96d56Sopenharmony_cistatic PyModuleDef_Slot _multibytecodec_slots[] = { 20627db96d56Sopenharmony_ci {Py_mod_exec, _multibytecodec_exec}, 20637db96d56Sopenharmony_ci {0, NULL} 20647db96d56Sopenharmony_ci}; 20657db96d56Sopenharmony_ci 20667db96d56Sopenharmony_cistatic struct PyModuleDef _multibytecodecmodule = { 20677db96d56Sopenharmony_ci .m_base = PyModuleDef_HEAD_INIT, 20687db96d56Sopenharmony_ci .m_name = "_multibytecodec", 20697db96d56Sopenharmony_ci .m_size = sizeof(_multibytecodec_state), 20707db96d56Sopenharmony_ci .m_methods = _multibytecodec_methods, 20717db96d56Sopenharmony_ci .m_slots = _multibytecodec_slots, 20727db96d56Sopenharmony_ci .m_traverse = _multibytecodec_traverse, 20737db96d56Sopenharmony_ci .m_clear = _multibytecodec_clear, 20747db96d56Sopenharmony_ci .m_free = _multibytecodec_free, 20757db96d56Sopenharmony_ci}; 20767db96d56Sopenharmony_ci 20777db96d56Sopenharmony_ciPyMODINIT_FUNC 20787db96d56Sopenharmony_ciPyInit__multibytecodec(void) 20797db96d56Sopenharmony_ci{ 20807db96d56Sopenharmony_ci return PyModuleDef_Init(&_multibytecodecmodule); 20817db96d56Sopenharmony_ci} 2082