xref: /third_party/python/Modules/_io/textio.c (revision 7db96d56)
17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ci    An implementation of Text I/O as defined by PEP 3116 - "New I/O"
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci    Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper.
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci    Written by Amaury Forgeot d'Arc and Antoine Pitrou
77db96d56Sopenharmony_ci*/
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
107db96d56Sopenharmony_ci#include "Python.h"
117db96d56Sopenharmony_ci#include "pycore_interp.h"        // PyInterpreterState.fs_codec
127db96d56Sopenharmony_ci#include "pycore_long.h"          // _PyLong_GetZero()
137db96d56Sopenharmony_ci#include "pycore_fileutils.h"     // _Py_GetLocaleEncoding()
147db96d56Sopenharmony_ci#include "pycore_object.h"
157db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyInterpreterState_GET()
167db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
177db96d56Sopenharmony_ci#include "_iomodule.h"
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci/*[clinic input]
207db96d56Sopenharmony_cimodule _io
217db96d56Sopenharmony_ciclass _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type"
227db96d56Sopenharmony_ciclass _io.TextIOWrapper "textio *" "&TextIOWrapper_Type"
237db96d56Sopenharmony_ci[clinic start generated code]*/
247db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed072384f8aada2c]*/
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci/* TextIOBase */
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_doc,
297db96d56Sopenharmony_ci    "Base class for text I/O.\n"
307db96d56Sopenharmony_ci    "\n"
317db96d56Sopenharmony_ci    "This class provides a character and line based interface to stream\n"
327db96d56Sopenharmony_ci    "I/O. There is no readinto method because Python's character strings\n"
337db96d56Sopenharmony_ci    "are immutable.\n"
347db96d56Sopenharmony_ci    );
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_cistatic PyObject *
377db96d56Sopenharmony_ci_unsupported(const char *message)
387db96d56Sopenharmony_ci{
397db96d56Sopenharmony_ci    _PyIO_State *state = IO_STATE();
407db96d56Sopenharmony_ci    if (state != NULL)
417db96d56Sopenharmony_ci        PyErr_SetString(state->unsupported_operation, message);
427db96d56Sopenharmony_ci    return NULL;
437db96d56Sopenharmony_ci}
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_detach_doc,
467db96d56Sopenharmony_ci    "Separate the underlying buffer from the TextIOBase and return it.\n"
477db96d56Sopenharmony_ci    "\n"
487db96d56Sopenharmony_ci    "After the underlying buffer has been detached, the TextIO is in an\n"
497db96d56Sopenharmony_ci    "unusable state.\n"
507db96d56Sopenharmony_ci    );
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_cistatic PyObject *
537db96d56Sopenharmony_citextiobase_detach(PyObject *self, PyObject *Py_UNUSED(ignored))
547db96d56Sopenharmony_ci{
557db96d56Sopenharmony_ci    return _unsupported("detach");
567db96d56Sopenharmony_ci}
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_read_doc,
597db96d56Sopenharmony_ci    "Read at most n characters from stream.\n"
607db96d56Sopenharmony_ci    "\n"
617db96d56Sopenharmony_ci    "Read from underlying buffer until we have n characters or we hit EOF.\n"
627db96d56Sopenharmony_ci    "If n is negative or omitted, read until EOF.\n"
637db96d56Sopenharmony_ci    );
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_cistatic PyObject *
667db96d56Sopenharmony_citextiobase_read(PyObject *self, PyObject *args)
677db96d56Sopenharmony_ci{
687db96d56Sopenharmony_ci    return _unsupported("read");
697db96d56Sopenharmony_ci}
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_readline_doc,
727db96d56Sopenharmony_ci    "Read until newline or EOF.\n"
737db96d56Sopenharmony_ci    "\n"
747db96d56Sopenharmony_ci    "Returns an empty string if EOF is hit immediately.\n"
757db96d56Sopenharmony_ci    );
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_cistatic PyObject *
787db96d56Sopenharmony_citextiobase_readline(PyObject *self, PyObject *args)
797db96d56Sopenharmony_ci{
807db96d56Sopenharmony_ci    return _unsupported("readline");
817db96d56Sopenharmony_ci}
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_write_doc,
847db96d56Sopenharmony_ci    "Write string to stream.\n"
857db96d56Sopenharmony_ci    "Returns the number of characters written (which is always equal to\n"
867db96d56Sopenharmony_ci    "the length of the string).\n"
877db96d56Sopenharmony_ci    );
887db96d56Sopenharmony_ci
897db96d56Sopenharmony_cistatic PyObject *
907db96d56Sopenharmony_citextiobase_write(PyObject *self, PyObject *args)
917db96d56Sopenharmony_ci{
927db96d56Sopenharmony_ci    return _unsupported("write");
937db96d56Sopenharmony_ci}
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_encoding_doc,
967db96d56Sopenharmony_ci    "Encoding of the text stream.\n"
977db96d56Sopenharmony_ci    "\n"
987db96d56Sopenharmony_ci    "Subclasses should override.\n"
997db96d56Sopenharmony_ci    );
1007db96d56Sopenharmony_ci
1017db96d56Sopenharmony_cistatic PyObject *
1027db96d56Sopenharmony_citextiobase_encoding_get(PyObject *self, void *context)
1037db96d56Sopenharmony_ci{
1047db96d56Sopenharmony_ci    Py_RETURN_NONE;
1057db96d56Sopenharmony_ci}
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_newlines_doc,
1087db96d56Sopenharmony_ci    "Line endings translated so far.\n"
1097db96d56Sopenharmony_ci    "\n"
1107db96d56Sopenharmony_ci    "Only line endings translated during reading are considered.\n"
1117db96d56Sopenharmony_ci    "\n"
1127db96d56Sopenharmony_ci    "Subclasses should override.\n"
1137db96d56Sopenharmony_ci    );
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_cistatic PyObject *
1167db96d56Sopenharmony_citextiobase_newlines_get(PyObject *self, void *context)
1177db96d56Sopenharmony_ci{
1187db96d56Sopenharmony_ci    Py_RETURN_NONE;
1197db96d56Sopenharmony_ci}
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ciPyDoc_STRVAR(textiobase_errors_doc,
1227db96d56Sopenharmony_ci    "The error setting of the decoder or encoder.\n"
1237db96d56Sopenharmony_ci    "\n"
1247db96d56Sopenharmony_ci    "Subclasses should override.\n"
1257db96d56Sopenharmony_ci    );
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_cistatic PyObject *
1287db96d56Sopenharmony_citextiobase_errors_get(PyObject *self, void *context)
1297db96d56Sopenharmony_ci{
1307db96d56Sopenharmony_ci    Py_RETURN_NONE;
1317db96d56Sopenharmony_ci}
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci
1347db96d56Sopenharmony_cistatic PyMethodDef textiobase_methods[] = {
1357db96d56Sopenharmony_ci    {"detach", textiobase_detach, METH_NOARGS, textiobase_detach_doc},
1367db96d56Sopenharmony_ci    {"read", textiobase_read, METH_VARARGS, textiobase_read_doc},
1377db96d56Sopenharmony_ci    {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc},
1387db96d56Sopenharmony_ci    {"write", textiobase_write, METH_VARARGS, textiobase_write_doc},
1397db96d56Sopenharmony_ci    {NULL, NULL}
1407db96d56Sopenharmony_ci};
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_cistatic PyGetSetDef textiobase_getset[] = {
1437db96d56Sopenharmony_ci    {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc},
1447db96d56Sopenharmony_ci    {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc},
1457db96d56Sopenharmony_ci    {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc},
1467db96d56Sopenharmony_ci    {NULL}
1477db96d56Sopenharmony_ci};
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ciPyTypeObject PyTextIOBase_Type = {
1507db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
1517db96d56Sopenharmony_ci    "_io._TextIOBase",          /*tp_name*/
1527db96d56Sopenharmony_ci    0,                          /*tp_basicsize*/
1537db96d56Sopenharmony_ci    0,                          /*tp_itemsize*/
1547db96d56Sopenharmony_ci    0,                          /*tp_dealloc*/
1557db96d56Sopenharmony_ci    0,                          /*tp_vectorcall_offset*/
1567db96d56Sopenharmony_ci    0,                          /*tp_getattr*/
1577db96d56Sopenharmony_ci    0,                          /*tp_setattr*/
1587db96d56Sopenharmony_ci    0,                          /*tp_as_async*/
1597db96d56Sopenharmony_ci    0,                          /*tp_repr*/
1607db96d56Sopenharmony_ci    0,                          /*tp_as_number*/
1617db96d56Sopenharmony_ci    0,                          /*tp_as_sequence*/
1627db96d56Sopenharmony_ci    0,                          /*tp_as_mapping*/
1637db96d56Sopenharmony_ci    0,                          /*tp_hash */
1647db96d56Sopenharmony_ci    0,                          /*tp_call*/
1657db96d56Sopenharmony_ci    0,                          /*tp_str*/
1667db96d56Sopenharmony_ci    0,                          /*tp_getattro*/
1677db96d56Sopenharmony_ci    0,                          /*tp_setattro*/
1687db96d56Sopenharmony_ci    0,                          /*tp_as_buffer*/
1697db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
1707db96d56Sopenharmony_ci    textiobase_doc,             /* tp_doc */
1717db96d56Sopenharmony_ci    0,                          /* tp_traverse */
1727db96d56Sopenharmony_ci    0,                          /* tp_clear */
1737db96d56Sopenharmony_ci    0,                          /* tp_richcompare */
1747db96d56Sopenharmony_ci    0,                          /* tp_weaklistoffset */
1757db96d56Sopenharmony_ci    0,                          /* tp_iter */
1767db96d56Sopenharmony_ci    0,                          /* tp_iternext */
1777db96d56Sopenharmony_ci    textiobase_methods,         /* tp_methods */
1787db96d56Sopenharmony_ci    0,                          /* tp_members */
1797db96d56Sopenharmony_ci    textiobase_getset,          /* tp_getset */
1807db96d56Sopenharmony_ci    &PyIOBase_Type,             /* tp_base */
1817db96d56Sopenharmony_ci    0,                          /* tp_dict */
1827db96d56Sopenharmony_ci    0,                          /* tp_descr_get */
1837db96d56Sopenharmony_ci    0,                          /* tp_descr_set */
1847db96d56Sopenharmony_ci    0,                          /* tp_dictoffset */
1857db96d56Sopenharmony_ci    0,                          /* tp_init */
1867db96d56Sopenharmony_ci    0,                          /* tp_alloc */
1877db96d56Sopenharmony_ci    0,                          /* tp_new */
1887db96d56Sopenharmony_ci    0,                          /* tp_free */
1897db96d56Sopenharmony_ci    0,                          /* tp_is_gc */
1907db96d56Sopenharmony_ci    0,                          /* tp_bases */
1917db96d56Sopenharmony_ci    0,                          /* tp_mro */
1927db96d56Sopenharmony_ci    0,                          /* tp_cache */
1937db96d56Sopenharmony_ci    0,                          /* tp_subclasses */
1947db96d56Sopenharmony_ci    0,                          /* tp_weaklist */
1957db96d56Sopenharmony_ci    0,                          /* tp_del */
1967db96d56Sopenharmony_ci    0,                          /* tp_version_tag */
1977db96d56Sopenharmony_ci    0,                          /* tp_finalize */
1987db96d56Sopenharmony_ci};
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci/* IncrementalNewlineDecoder */
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_citypedef struct {
2047db96d56Sopenharmony_ci    PyObject_HEAD
2057db96d56Sopenharmony_ci    PyObject *decoder;
2067db96d56Sopenharmony_ci    PyObject *errors;
2077db96d56Sopenharmony_ci    unsigned int pendingcr: 1;
2087db96d56Sopenharmony_ci    unsigned int translate: 1;
2097db96d56Sopenharmony_ci    unsigned int seennl: 3;
2107db96d56Sopenharmony_ci} nldecoder_object;
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci/*[clinic input]
2137db96d56Sopenharmony_ci_io.IncrementalNewlineDecoder.__init__
2147db96d56Sopenharmony_ci    decoder: object
2157db96d56Sopenharmony_ci    translate: int
2167db96d56Sopenharmony_ci    errors: object(c_default="NULL") = "strict"
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ciCodec used when reading a file in universal newlines mode.
2197db96d56Sopenharmony_ci
2207db96d56Sopenharmony_ciIt wraps another incremental decoder, translating \r\n and \r into \n.
2217db96d56Sopenharmony_ciIt also records the types of newlines encountered.  When used with
2227db96d56Sopenharmony_citranslate=False, it ensures that the newline sequence is returned in
2237db96d56Sopenharmony_cione piece. When used with decoder=None, it expects unicode strings as
2247db96d56Sopenharmony_cidecode input and translates newlines without first invoking an external
2257db96d56Sopenharmony_cidecoder.
2267db96d56Sopenharmony_ci[clinic start generated code]*/
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_cistatic int
2297db96d56Sopenharmony_ci_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self,
2307db96d56Sopenharmony_ci                                            PyObject *decoder, int translate,
2317db96d56Sopenharmony_ci                                            PyObject *errors)
2327db96d56Sopenharmony_ci/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/
2337db96d56Sopenharmony_ci{
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci    if (errors == NULL) {
2367db96d56Sopenharmony_ci        errors = Py_NewRef(&_Py_ID(strict));
2377db96d56Sopenharmony_ci    }
2387db96d56Sopenharmony_ci    else {
2397db96d56Sopenharmony_ci        errors = Py_NewRef(errors);
2407db96d56Sopenharmony_ci    }
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci    Py_XSETREF(self->errors, errors);
2437db96d56Sopenharmony_ci    Py_XSETREF(self->decoder, Py_NewRef(decoder));
2447db96d56Sopenharmony_ci    self->translate = translate ? 1 : 0;
2457db96d56Sopenharmony_ci    self->seennl = 0;
2467db96d56Sopenharmony_ci    self->pendingcr = 0;
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci    return 0;
2497db96d56Sopenharmony_ci}
2507db96d56Sopenharmony_ci
2517db96d56Sopenharmony_cistatic void
2527db96d56Sopenharmony_ciincrementalnewlinedecoder_dealloc(nldecoder_object *self)
2537db96d56Sopenharmony_ci{
2547db96d56Sopenharmony_ci    Py_CLEAR(self->decoder);
2557db96d56Sopenharmony_ci    Py_CLEAR(self->errors);
2567db96d56Sopenharmony_ci    Py_TYPE(self)->tp_free((PyObject *)self);
2577db96d56Sopenharmony_ci}
2587db96d56Sopenharmony_ci
2597db96d56Sopenharmony_cistatic int
2607db96d56Sopenharmony_cicheck_decoded(PyObject *decoded)
2617db96d56Sopenharmony_ci{
2627db96d56Sopenharmony_ci    if (decoded == NULL)
2637db96d56Sopenharmony_ci        return -1;
2647db96d56Sopenharmony_ci    if (!PyUnicode_Check(decoded)) {
2657db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
2667db96d56Sopenharmony_ci                     "decoder should return a string result, not '%.200s'",
2677db96d56Sopenharmony_ci                     Py_TYPE(decoded)->tp_name);
2687db96d56Sopenharmony_ci        Py_DECREF(decoded);
2697db96d56Sopenharmony_ci        return -1;
2707db96d56Sopenharmony_ci    }
2717db96d56Sopenharmony_ci    if (PyUnicode_READY(decoded) < 0) {
2727db96d56Sopenharmony_ci        Py_DECREF(decoded);
2737db96d56Sopenharmony_ci        return -1;
2747db96d56Sopenharmony_ci    }
2757db96d56Sopenharmony_ci    return 0;
2767db96d56Sopenharmony_ci}
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ci#define CHECK_INITIALIZED_DECODER(self) \
2797db96d56Sopenharmony_ci    if (self->errors == NULL) { \
2807db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, \
2817db96d56Sopenharmony_ci                        "IncrementalNewlineDecoder.__init__() not called"); \
2827db96d56Sopenharmony_ci        return NULL; \
2837db96d56Sopenharmony_ci    }
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci#define SEEN_CR   1
2867db96d56Sopenharmony_ci#define SEEN_LF   2
2877db96d56Sopenharmony_ci#define SEEN_CRLF 4
2887db96d56Sopenharmony_ci#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF)
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ciPyObject *
2917db96d56Sopenharmony_ci_PyIncrementalNewlineDecoder_decode(PyObject *myself,
2927db96d56Sopenharmony_ci                                    PyObject *input, int final)
2937db96d56Sopenharmony_ci{
2947db96d56Sopenharmony_ci    PyObject *output;
2957db96d56Sopenharmony_ci    Py_ssize_t output_len;
2967db96d56Sopenharmony_ci    nldecoder_object *self = (nldecoder_object *) myself;
2977db96d56Sopenharmony_ci
2987db96d56Sopenharmony_ci    CHECK_INITIALIZED_DECODER(self);
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci    /* decode input (with the eventual \r from a previous pass) */
3017db96d56Sopenharmony_ci    if (self->decoder != Py_None) {
3027db96d56Sopenharmony_ci        output = PyObject_CallMethodObjArgs(self->decoder,
3037db96d56Sopenharmony_ci            &_Py_ID(decode), input, final ? Py_True : Py_False, NULL);
3047db96d56Sopenharmony_ci    }
3057db96d56Sopenharmony_ci    else {
3067db96d56Sopenharmony_ci        output = input;
3077db96d56Sopenharmony_ci        Py_INCREF(output);
3087db96d56Sopenharmony_ci    }
3097db96d56Sopenharmony_ci
3107db96d56Sopenharmony_ci    if (check_decoded(output) < 0)
3117db96d56Sopenharmony_ci        return NULL;
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci    output_len = PyUnicode_GET_LENGTH(output);
3147db96d56Sopenharmony_ci    if (self->pendingcr && (final || output_len > 0)) {
3157db96d56Sopenharmony_ci        /* Prefix output with CR */
3167db96d56Sopenharmony_ci        int kind;
3177db96d56Sopenharmony_ci        PyObject *modified;
3187db96d56Sopenharmony_ci        char *out;
3197db96d56Sopenharmony_ci
3207db96d56Sopenharmony_ci        modified = PyUnicode_New(output_len + 1,
3217db96d56Sopenharmony_ci                                 PyUnicode_MAX_CHAR_VALUE(output));
3227db96d56Sopenharmony_ci        if (modified == NULL)
3237db96d56Sopenharmony_ci            goto error;
3247db96d56Sopenharmony_ci        kind = PyUnicode_KIND(modified);
3257db96d56Sopenharmony_ci        out = PyUnicode_DATA(modified);
3267db96d56Sopenharmony_ci        PyUnicode_WRITE(kind, out, 0, '\r');
3277db96d56Sopenharmony_ci        memcpy(out + kind, PyUnicode_DATA(output), kind * output_len);
3287db96d56Sopenharmony_ci        Py_DECREF(output);
3297db96d56Sopenharmony_ci        output = modified; /* output remains ready */
3307db96d56Sopenharmony_ci        self->pendingcr = 0;
3317db96d56Sopenharmony_ci        output_len++;
3327db96d56Sopenharmony_ci    }
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci    /* retain last \r even when not translating data:
3357db96d56Sopenharmony_ci     * then readline() is sure to get \r\n in one pass
3367db96d56Sopenharmony_ci     */
3377db96d56Sopenharmony_ci    if (!final) {
3387db96d56Sopenharmony_ci        if (output_len > 0
3397db96d56Sopenharmony_ci            && PyUnicode_READ_CHAR(output, output_len - 1) == '\r')
3407db96d56Sopenharmony_ci        {
3417db96d56Sopenharmony_ci            PyObject *modified = PyUnicode_Substring(output, 0, output_len -1);
3427db96d56Sopenharmony_ci            if (modified == NULL)
3437db96d56Sopenharmony_ci                goto error;
3447db96d56Sopenharmony_ci            Py_DECREF(output);
3457db96d56Sopenharmony_ci            output = modified;
3467db96d56Sopenharmony_ci            self->pendingcr = 1;
3477db96d56Sopenharmony_ci        }
3487db96d56Sopenharmony_ci    }
3497db96d56Sopenharmony_ci
3507db96d56Sopenharmony_ci    /* Record which newlines are read and do newline translation if desired,
3517db96d56Sopenharmony_ci       all in one pass. */
3527db96d56Sopenharmony_ci    {
3537db96d56Sopenharmony_ci        const void *in_str;
3547db96d56Sopenharmony_ci        Py_ssize_t len;
3557db96d56Sopenharmony_ci        int seennl = self->seennl;
3567db96d56Sopenharmony_ci        int only_lf = 0;
3577db96d56Sopenharmony_ci        int kind;
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci        in_str = PyUnicode_DATA(output);
3607db96d56Sopenharmony_ci        len = PyUnicode_GET_LENGTH(output);
3617db96d56Sopenharmony_ci        kind = PyUnicode_KIND(output);
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci        if (len == 0)
3647db96d56Sopenharmony_ci            return output;
3657db96d56Sopenharmony_ci
3667db96d56Sopenharmony_ci        /* If, up to now, newlines are consistently \n, do a quick check
3677db96d56Sopenharmony_ci           for the \r *byte* with the libc's optimized memchr.
3687db96d56Sopenharmony_ci           */
3697db96d56Sopenharmony_ci        if (seennl == SEEN_LF || seennl == 0) {
3707db96d56Sopenharmony_ci            only_lf = (memchr(in_str, '\r', kind * len) == NULL);
3717db96d56Sopenharmony_ci        }
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_ci        if (only_lf) {
3747db96d56Sopenharmony_ci            /* If not already seen, quick scan for a possible "\n" character.
3757db96d56Sopenharmony_ci               (there's nothing else to be done, even when in translation mode)
3767db96d56Sopenharmony_ci            */
3777db96d56Sopenharmony_ci            if (seennl == 0 &&
3787db96d56Sopenharmony_ci                memchr(in_str, '\n', kind * len) != NULL) {
3797db96d56Sopenharmony_ci                if (kind == PyUnicode_1BYTE_KIND)
3807db96d56Sopenharmony_ci                    seennl |= SEEN_LF;
3817db96d56Sopenharmony_ci                else {
3827db96d56Sopenharmony_ci                    Py_ssize_t i = 0;
3837db96d56Sopenharmony_ci                    for (;;) {
3847db96d56Sopenharmony_ci                        Py_UCS4 c;
3857db96d56Sopenharmony_ci                        /* Fast loop for non-control characters */
3867db96d56Sopenharmony_ci                        while (PyUnicode_READ(kind, in_str, i) > '\n')
3877db96d56Sopenharmony_ci                            i++;
3887db96d56Sopenharmony_ci                        c = PyUnicode_READ(kind, in_str, i++);
3897db96d56Sopenharmony_ci                        if (c == '\n') {
3907db96d56Sopenharmony_ci                            seennl |= SEEN_LF;
3917db96d56Sopenharmony_ci                            break;
3927db96d56Sopenharmony_ci                        }
3937db96d56Sopenharmony_ci                        if (i >= len)
3947db96d56Sopenharmony_ci                            break;
3957db96d56Sopenharmony_ci                    }
3967db96d56Sopenharmony_ci                }
3977db96d56Sopenharmony_ci            }
3987db96d56Sopenharmony_ci            /* Finished: we have scanned for newlines, and none of them
3997db96d56Sopenharmony_ci               need translating */
4007db96d56Sopenharmony_ci        }
4017db96d56Sopenharmony_ci        else if (!self->translate) {
4027db96d56Sopenharmony_ci            Py_ssize_t i = 0;
4037db96d56Sopenharmony_ci            /* We have already seen all newline types, no need to scan again */
4047db96d56Sopenharmony_ci            if (seennl == SEEN_ALL)
4057db96d56Sopenharmony_ci                goto endscan;
4067db96d56Sopenharmony_ci            for (;;) {
4077db96d56Sopenharmony_ci                Py_UCS4 c;
4087db96d56Sopenharmony_ci                /* Fast loop for non-control characters */
4097db96d56Sopenharmony_ci                while (PyUnicode_READ(kind, in_str, i) > '\r')
4107db96d56Sopenharmony_ci                    i++;
4117db96d56Sopenharmony_ci                c = PyUnicode_READ(kind, in_str, i++);
4127db96d56Sopenharmony_ci                if (c == '\n')
4137db96d56Sopenharmony_ci                    seennl |= SEEN_LF;
4147db96d56Sopenharmony_ci                else if (c == '\r') {
4157db96d56Sopenharmony_ci                    if (PyUnicode_READ(kind, in_str, i) == '\n') {
4167db96d56Sopenharmony_ci                        seennl |= SEEN_CRLF;
4177db96d56Sopenharmony_ci                        i++;
4187db96d56Sopenharmony_ci                    }
4197db96d56Sopenharmony_ci                    else
4207db96d56Sopenharmony_ci                        seennl |= SEEN_CR;
4217db96d56Sopenharmony_ci                }
4227db96d56Sopenharmony_ci                if (i >= len)
4237db96d56Sopenharmony_ci                    break;
4247db96d56Sopenharmony_ci                if (seennl == SEEN_ALL)
4257db96d56Sopenharmony_ci                    break;
4267db96d56Sopenharmony_ci            }
4277db96d56Sopenharmony_ci        endscan:
4287db96d56Sopenharmony_ci            ;
4297db96d56Sopenharmony_ci        }
4307db96d56Sopenharmony_ci        else {
4317db96d56Sopenharmony_ci            void *translated;
4327db96d56Sopenharmony_ci            int kind = PyUnicode_KIND(output);
4337db96d56Sopenharmony_ci            const void *in_str = PyUnicode_DATA(output);
4347db96d56Sopenharmony_ci            Py_ssize_t in, out;
4357db96d56Sopenharmony_ci            /* XXX: Previous in-place translation here is disabled as
4367db96d56Sopenharmony_ci               resizing is not possible anymore */
4377db96d56Sopenharmony_ci            /* We could try to optimize this so that we only do a copy
4387db96d56Sopenharmony_ci               when there is something to translate. On the other hand,
4397db96d56Sopenharmony_ci               we already know there is a \r byte, so chances are high
4407db96d56Sopenharmony_ci               that something needs to be done. */
4417db96d56Sopenharmony_ci            translated = PyMem_Malloc(kind * len);
4427db96d56Sopenharmony_ci            if (translated == NULL) {
4437db96d56Sopenharmony_ci                PyErr_NoMemory();
4447db96d56Sopenharmony_ci                goto error;
4457db96d56Sopenharmony_ci            }
4467db96d56Sopenharmony_ci            in = out = 0;
4477db96d56Sopenharmony_ci            for (;;) {
4487db96d56Sopenharmony_ci                Py_UCS4 c;
4497db96d56Sopenharmony_ci                /* Fast loop for non-control characters */
4507db96d56Sopenharmony_ci                while ((c = PyUnicode_READ(kind, in_str, in++)) > '\r')
4517db96d56Sopenharmony_ci                    PyUnicode_WRITE(kind, translated, out++, c);
4527db96d56Sopenharmony_ci                if (c == '\n') {
4537db96d56Sopenharmony_ci                    PyUnicode_WRITE(kind, translated, out++, c);
4547db96d56Sopenharmony_ci                    seennl |= SEEN_LF;
4557db96d56Sopenharmony_ci                    continue;
4567db96d56Sopenharmony_ci                }
4577db96d56Sopenharmony_ci                if (c == '\r') {
4587db96d56Sopenharmony_ci                    if (PyUnicode_READ(kind, in_str, in) == '\n') {
4597db96d56Sopenharmony_ci                        in++;
4607db96d56Sopenharmony_ci                        seennl |= SEEN_CRLF;
4617db96d56Sopenharmony_ci                    }
4627db96d56Sopenharmony_ci                    else
4637db96d56Sopenharmony_ci                        seennl |= SEEN_CR;
4647db96d56Sopenharmony_ci                    PyUnicode_WRITE(kind, translated, out++, '\n');
4657db96d56Sopenharmony_ci                    continue;
4667db96d56Sopenharmony_ci                }
4677db96d56Sopenharmony_ci                if (in > len)
4687db96d56Sopenharmony_ci                    break;
4697db96d56Sopenharmony_ci                PyUnicode_WRITE(kind, translated, out++, c);
4707db96d56Sopenharmony_ci            }
4717db96d56Sopenharmony_ci            Py_DECREF(output);
4727db96d56Sopenharmony_ci            output = PyUnicode_FromKindAndData(kind, translated, out);
4737db96d56Sopenharmony_ci            PyMem_Free(translated);
4747db96d56Sopenharmony_ci            if (!output)
4757db96d56Sopenharmony_ci                return NULL;
4767db96d56Sopenharmony_ci        }
4777db96d56Sopenharmony_ci        self->seennl |= seennl;
4787db96d56Sopenharmony_ci    }
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci    return output;
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci  error:
4837db96d56Sopenharmony_ci    Py_DECREF(output);
4847db96d56Sopenharmony_ci    return NULL;
4857db96d56Sopenharmony_ci}
4867db96d56Sopenharmony_ci
4877db96d56Sopenharmony_ci/*[clinic input]
4887db96d56Sopenharmony_ci_io.IncrementalNewlineDecoder.decode
4897db96d56Sopenharmony_ci    input: object
4907db96d56Sopenharmony_ci    final: bool(accept={int}) = False
4917db96d56Sopenharmony_ci[clinic start generated code]*/
4927db96d56Sopenharmony_ci
4937db96d56Sopenharmony_cistatic PyObject *
4947db96d56Sopenharmony_ci_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self,
4957db96d56Sopenharmony_ci                                          PyObject *input, int final)
4967db96d56Sopenharmony_ci/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/
4977db96d56Sopenharmony_ci{
4987db96d56Sopenharmony_ci    return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final);
4997db96d56Sopenharmony_ci}
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci/*[clinic input]
5027db96d56Sopenharmony_ci_io.IncrementalNewlineDecoder.getstate
5037db96d56Sopenharmony_ci[clinic start generated code]*/
5047db96d56Sopenharmony_ci
5057db96d56Sopenharmony_cistatic PyObject *
5067db96d56Sopenharmony_ci_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self)
5077db96d56Sopenharmony_ci/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/
5087db96d56Sopenharmony_ci{
5097db96d56Sopenharmony_ci    PyObject *buffer;
5107db96d56Sopenharmony_ci    unsigned long long flag;
5117db96d56Sopenharmony_ci
5127db96d56Sopenharmony_ci    CHECK_INITIALIZED_DECODER(self);
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ci    if (self->decoder != Py_None) {
5157db96d56Sopenharmony_ci        PyObject *state = PyObject_CallMethodNoArgs(self->decoder,
5167db96d56Sopenharmony_ci           &_Py_ID(getstate));
5177db96d56Sopenharmony_ci        if (state == NULL)
5187db96d56Sopenharmony_ci            return NULL;
5197db96d56Sopenharmony_ci        if (!PyTuple_Check(state)) {
5207db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
5217db96d56Sopenharmony_ci                            "illegal decoder state");
5227db96d56Sopenharmony_ci            Py_DECREF(state);
5237db96d56Sopenharmony_ci            return NULL;
5247db96d56Sopenharmony_ci        }
5257db96d56Sopenharmony_ci        if (!PyArg_ParseTuple(state, "OK;illegal decoder state",
5267db96d56Sopenharmony_ci                              &buffer, &flag))
5277db96d56Sopenharmony_ci        {
5287db96d56Sopenharmony_ci            Py_DECREF(state);
5297db96d56Sopenharmony_ci            return NULL;
5307db96d56Sopenharmony_ci        }
5317db96d56Sopenharmony_ci        Py_INCREF(buffer);
5327db96d56Sopenharmony_ci        Py_DECREF(state);
5337db96d56Sopenharmony_ci    }
5347db96d56Sopenharmony_ci    else {
5357db96d56Sopenharmony_ci        buffer = PyBytes_FromString("");
5367db96d56Sopenharmony_ci        flag = 0;
5377db96d56Sopenharmony_ci    }
5387db96d56Sopenharmony_ci    flag <<= 1;
5397db96d56Sopenharmony_ci    if (self->pendingcr)
5407db96d56Sopenharmony_ci        flag |= 1;
5417db96d56Sopenharmony_ci    return Py_BuildValue("NK", buffer, flag);
5427db96d56Sopenharmony_ci}
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_ci/*[clinic input]
5457db96d56Sopenharmony_ci_io.IncrementalNewlineDecoder.setstate
5467db96d56Sopenharmony_ci    state: object
5477db96d56Sopenharmony_ci    /
5487db96d56Sopenharmony_ci[clinic start generated code]*/
5497db96d56Sopenharmony_ci
5507db96d56Sopenharmony_cistatic PyObject *
5517db96d56Sopenharmony_ci_io_IncrementalNewlineDecoder_setstate(nldecoder_object *self,
5527db96d56Sopenharmony_ci                                       PyObject *state)
5537db96d56Sopenharmony_ci/*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/
5547db96d56Sopenharmony_ci{
5557db96d56Sopenharmony_ci    PyObject *buffer;
5567db96d56Sopenharmony_ci    unsigned long long flag;
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci    CHECK_INITIALIZED_DECODER(self);
5597db96d56Sopenharmony_ci
5607db96d56Sopenharmony_ci    if (!PyTuple_Check(state)) {
5617db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "state argument must be a tuple");
5627db96d56Sopenharmony_ci        return NULL;
5637db96d56Sopenharmony_ci    }
5647db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(state, "OK;setstate(): illegal state argument",
5657db96d56Sopenharmony_ci                          &buffer, &flag))
5667db96d56Sopenharmony_ci    {
5677db96d56Sopenharmony_ci        return NULL;
5687db96d56Sopenharmony_ci    }
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ci    self->pendingcr = (int) (flag & 1);
5717db96d56Sopenharmony_ci    flag >>= 1;
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_ci    if (self->decoder != Py_None) {
5747db96d56Sopenharmony_ci        return _PyObject_CallMethod(self->decoder, &_Py_ID(setstate),
5757db96d56Sopenharmony_ci                                    "((OK))", buffer, flag);
5767db96d56Sopenharmony_ci    }
5777db96d56Sopenharmony_ci    else {
5787db96d56Sopenharmony_ci        Py_RETURN_NONE;
5797db96d56Sopenharmony_ci    }
5807db96d56Sopenharmony_ci}
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci/*[clinic input]
5837db96d56Sopenharmony_ci_io.IncrementalNewlineDecoder.reset
5847db96d56Sopenharmony_ci[clinic start generated code]*/
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_cistatic PyObject *
5877db96d56Sopenharmony_ci_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self)
5887db96d56Sopenharmony_ci/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/
5897db96d56Sopenharmony_ci{
5907db96d56Sopenharmony_ci    CHECK_INITIALIZED_DECODER(self);
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci    self->seennl = 0;
5937db96d56Sopenharmony_ci    self->pendingcr = 0;
5947db96d56Sopenharmony_ci    if (self->decoder != Py_None)
5957db96d56Sopenharmony_ci        return PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
5967db96d56Sopenharmony_ci    else
5977db96d56Sopenharmony_ci        Py_RETURN_NONE;
5987db96d56Sopenharmony_ci}
5997db96d56Sopenharmony_ci
6007db96d56Sopenharmony_cistatic PyObject *
6017db96d56Sopenharmony_ciincrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
6027db96d56Sopenharmony_ci{
6037db96d56Sopenharmony_ci    CHECK_INITIALIZED_DECODER(self);
6047db96d56Sopenharmony_ci
6057db96d56Sopenharmony_ci    switch (self->seennl) {
6067db96d56Sopenharmony_ci    case SEEN_CR:
6077db96d56Sopenharmony_ci        return PyUnicode_FromString("\r");
6087db96d56Sopenharmony_ci    case SEEN_LF:
6097db96d56Sopenharmony_ci        return PyUnicode_FromString("\n");
6107db96d56Sopenharmony_ci    case SEEN_CRLF:
6117db96d56Sopenharmony_ci        return PyUnicode_FromString("\r\n");
6127db96d56Sopenharmony_ci    case SEEN_CR | SEEN_LF:
6137db96d56Sopenharmony_ci        return Py_BuildValue("ss", "\r", "\n");
6147db96d56Sopenharmony_ci    case SEEN_CR | SEEN_CRLF:
6157db96d56Sopenharmony_ci        return Py_BuildValue("ss", "\r", "\r\n");
6167db96d56Sopenharmony_ci    case SEEN_LF | SEEN_CRLF:
6177db96d56Sopenharmony_ci        return Py_BuildValue("ss", "\n", "\r\n");
6187db96d56Sopenharmony_ci    case SEEN_CR | SEEN_LF | SEEN_CRLF:
6197db96d56Sopenharmony_ci        return Py_BuildValue("sss", "\r", "\n", "\r\n");
6207db96d56Sopenharmony_ci    default:
6217db96d56Sopenharmony_ci        Py_RETURN_NONE;
6227db96d56Sopenharmony_ci   }
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_ci}
6257db96d56Sopenharmony_ci
6267db96d56Sopenharmony_ci/* TextIOWrapper */
6277db96d56Sopenharmony_ci
6287db96d56Sopenharmony_citypedef PyObject *
6297db96d56Sopenharmony_ci        (*encodefunc_t)(PyObject *, PyObject *);
6307db96d56Sopenharmony_ci
6317db96d56Sopenharmony_citypedef struct
6327db96d56Sopenharmony_ci{
6337db96d56Sopenharmony_ci    PyObject_HEAD
6347db96d56Sopenharmony_ci    int ok; /* initialized? */
6357db96d56Sopenharmony_ci    int detached;
6367db96d56Sopenharmony_ci    Py_ssize_t chunk_size;
6377db96d56Sopenharmony_ci    PyObject *buffer;
6387db96d56Sopenharmony_ci    PyObject *encoding;
6397db96d56Sopenharmony_ci    PyObject *encoder;
6407db96d56Sopenharmony_ci    PyObject *decoder;
6417db96d56Sopenharmony_ci    PyObject *readnl;
6427db96d56Sopenharmony_ci    PyObject *errors;
6437db96d56Sopenharmony_ci    const char *writenl; /* ASCII-encoded; NULL stands for \n */
6447db96d56Sopenharmony_ci    char line_buffering;
6457db96d56Sopenharmony_ci    char write_through;
6467db96d56Sopenharmony_ci    char readuniversal;
6477db96d56Sopenharmony_ci    char readtranslate;
6487db96d56Sopenharmony_ci    char writetranslate;
6497db96d56Sopenharmony_ci    char seekable;
6507db96d56Sopenharmony_ci    char has_read1;
6517db96d56Sopenharmony_ci    char telling;
6527db96d56Sopenharmony_ci    char finalizing;
6537db96d56Sopenharmony_ci    /* Specialized encoding func (see below) */
6547db96d56Sopenharmony_ci    encodefunc_t encodefunc;
6557db96d56Sopenharmony_ci    /* Whether or not it's the start of the stream */
6567db96d56Sopenharmony_ci    char encoding_start_of_stream;
6577db96d56Sopenharmony_ci
6587db96d56Sopenharmony_ci    /* Reads and writes are internally buffered in order to speed things up.
6597db96d56Sopenharmony_ci       However, any read will first flush the write buffer if itsn't empty.
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ci       Please also note that text to be written is first encoded before being
6627db96d56Sopenharmony_ci       buffered. This is necessary so that encoding errors are immediately
6637db96d56Sopenharmony_ci       reported to the caller, but it unfortunately means that the
6647db96d56Sopenharmony_ci       IncrementalEncoder (whose encode() method is always written in Python)
6657db96d56Sopenharmony_ci       becomes a bottleneck for small writes.
6667db96d56Sopenharmony_ci    */
6677db96d56Sopenharmony_ci    PyObject *decoded_chars;       /* buffer for text returned from decoder */
6687db96d56Sopenharmony_ci    Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */
6697db96d56Sopenharmony_ci    PyObject *pending_bytes;       // data waiting to be written.
6707db96d56Sopenharmony_ci                                   // ascii unicode, bytes, or list of them.
6717db96d56Sopenharmony_ci    Py_ssize_t pending_bytes_count;
6727db96d56Sopenharmony_ci
6737db96d56Sopenharmony_ci    /* snapshot is either NULL, or a tuple (dec_flags, next_input) where
6747db96d56Sopenharmony_ci     * dec_flags is the second (integer) item of the decoder state and
6757db96d56Sopenharmony_ci     * next_input is the chunk of input bytes that comes next after the
6767db96d56Sopenharmony_ci     * snapshot point.  We use this to reconstruct decoder states in tell().
6777db96d56Sopenharmony_ci     */
6787db96d56Sopenharmony_ci    PyObject *snapshot;
6797db96d56Sopenharmony_ci    /* Bytes-to-characters ratio for the current chunk. Serves as input for
6807db96d56Sopenharmony_ci       the heuristic in tell(). */
6817db96d56Sopenharmony_ci    double b2cratio;
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_ci    /* Cache raw object if it's a FileIO object */
6847db96d56Sopenharmony_ci    PyObject *raw;
6857db96d56Sopenharmony_ci
6867db96d56Sopenharmony_ci    PyObject *weakreflist;
6877db96d56Sopenharmony_ci    PyObject *dict;
6887db96d56Sopenharmony_ci} textio;
6897db96d56Sopenharmony_ci
6907db96d56Sopenharmony_cistatic void
6917db96d56Sopenharmony_citextiowrapper_set_decoded_chars(textio *self, PyObject *chars);
6927db96d56Sopenharmony_ci
6937db96d56Sopenharmony_ci/* A couple of specialized cases in order to bypass the slow incremental
6947db96d56Sopenharmony_ci   encoding methods for the most popular encodings. */
6957db96d56Sopenharmony_ci
6967db96d56Sopenharmony_cistatic PyObject *
6977db96d56Sopenharmony_ciascii_encode(textio *self, PyObject *text)
6987db96d56Sopenharmony_ci{
6997db96d56Sopenharmony_ci    return _PyUnicode_AsASCIIString(text, PyUnicode_AsUTF8(self->errors));
7007db96d56Sopenharmony_ci}
7017db96d56Sopenharmony_ci
7027db96d56Sopenharmony_cistatic PyObject *
7037db96d56Sopenharmony_ciutf16be_encode(textio *self, PyObject *text)
7047db96d56Sopenharmony_ci{
7057db96d56Sopenharmony_ci    return _PyUnicode_EncodeUTF16(text,
7067db96d56Sopenharmony_ci                                  PyUnicode_AsUTF8(self->errors), 1);
7077db96d56Sopenharmony_ci}
7087db96d56Sopenharmony_ci
7097db96d56Sopenharmony_cistatic PyObject *
7107db96d56Sopenharmony_ciutf16le_encode(textio *self, PyObject *text)
7117db96d56Sopenharmony_ci{
7127db96d56Sopenharmony_ci    return _PyUnicode_EncodeUTF16(text,
7137db96d56Sopenharmony_ci                                  PyUnicode_AsUTF8(self->errors), -1);
7147db96d56Sopenharmony_ci}
7157db96d56Sopenharmony_ci
7167db96d56Sopenharmony_cistatic PyObject *
7177db96d56Sopenharmony_ciutf16_encode(textio *self, PyObject *text)
7187db96d56Sopenharmony_ci{
7197db96d56Sopenharmony_ci    if (!self->encoding_start_of_stream) {
7207db96d56Sopenharmony_ci        /* Skip the BOM and use native byte ordering */
7217db96d56Sopenharmony_ci#if PY_BIG_ENDIAN
7227db96d56Sopenharmony_ci        return utf16be_encode(self, text);
7237db96d56Sopenharmony_ci#else
7247db96d56Sopenharmony_ci        return utf16le_encode(self, text);
7257db96d56Sopenharmony_ci#endif
7267db96d56Sopenharmony_ci    }
7277db96d56Sopenharmony_ci    return _PyUnicode_EncodeUTF16(text,
7287db96d56Sopenharmony_ci                                  PyUnicode_AsUTF8(self->errors), 0);
7297db96d56Sopenharmony_ci}
7307db96d56Sopenharmony_ci
7317db96d56Sopenharmony_cistatic PyObject *
7327db96d56Sopenharmony_ciutf32be_encode(textio *self, PyObject *text)
7337db96d56Sopenharmony_ci{
7347db96d56Sopenharmony_ci    return _PyUnicode_EncodeUTF32(text,
7357db96d56Sopenharmony_ci                                  PyUnicode_AsUTF8(self->errors), 1);
7367db96d56Sopenharmony_ci}
7377db96d56Sopenharmony_ci
7387db96d56Sopenharmony_cistatic PyObject *
7397db96d56Sopenharmony_ciutf32le_encode(textio *self, PyObject *text)
7407db96d56Sopenharmony_ci{
7417db96d56Sopenharmony_ci    return _PyUnicode_EncodeUTF32(text,
7427db96d56Sopenharmony_ci                                  PyUnicode_AsUTF8(self->errors), -1);
7437db96d56Sopenharmony_ci}
7447db96d56Sopenharmony_ci
7457db96d56Sopenharmony_cistatic PyObject *
7467db96d56Sopenharmony_ciutf32_encode(textio *self, PyObject *text)
7477db96d56Sopenharmony_ci{
7487db96d56Sopenharmony_ci    if (!self->encoding_start_of_stream) {
7497db96d56Sopenharmony_ci        /* Skip the BOM and use native byte ordering */
7507db96d56Sopenharmony_ci#if PY_BIG_ENDIAN
7517db96d56Sopenharmony_ci        return utf32be_encode(self, text);
7527db96d56Sopenharmony_ci#else
7537db96d56Sopenharmony_ci        return utf32le_encode(self, text);
7547db96d56Sopenharmony_ci#endif
7557db96d56Sopenharmony_ci    }
7567db96d56Sopenharmony_ci    return _PyUnicode_EncodeUTF32(text,
7577db96d56Sopenharmony_ci                                  PyUnicode_AsUTF8(self->errors), 0);
7587db96d56Sopenharmony_ci}
7597db96d56Sopenharmony_ci
7607db96d56Sopenharmony_cistatic PyObject *
7617db96d56Sopenharmony_ciutf8_encode(textio *self, PyObject *text)
7627db96d56Sopenharmony_ci{
7637db96d56Sopenharmony_ci    return _PyUnicode_AsUTF8String(text, PyUnicode_AsUTF8(self->errors));
7647db96d56Sopenharmony_ci}
7657db96d56Sopenharmony_ci
7667db96d56Sopenharmony_cistatic PyObject *
7677db96d56Sopenharmony_cilatin1_encode(textio *self, PyObject *text)
7687db96d56Sopenharmony_ci{
7697db96d56Sopenharmony_ci    return _PyUnicode_AsLatin1String(text, PyUnicode_AsUTF8(self->errors));
7707db96d56Sopenharmony_ci}
7717db96d56Sopenharmony_ci
7727db96d56Sopenharmony_ci// Return true when encoding can be skipped when text is ascii.
7737db96d56Sopenharmony_cistatic inline int
7747db96d56Sopenharmony_ciis_asciicompat_encoding(encodefunc_t f)
7757db96d56Sopenharmony_ci{
7767db96d56Sopenharmony_ci    return f == (encodefunc_t) ascii_encode
7777db96d56Sopenharmony_ci        || f == (encodefunc_t) latin1_encode
7787db96d56Sopenharmony_ci        || f == (encodefunc_t) utf8_encode;
7797db96d56Sopenharmony_ci}
7807db96d56Sopenharmony_ci
7817db96d56Sopenharmony_ci/* Map normalized encoding names onto the specialized encoding funcs */
7827db96d56Sopenharmony_ci
7837db96d56Sopenharmony_citypedef struct {
7847db96d56Sopenharmony_ci    const char *name;
7857db96d56Sopenharmony_ci    encodefunc_t encodefunc;
7867db96d56Sopenharmony_ci} encodefuncentry;
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_cistatic const encodefuncentry encodefuncs[] = {
7897db96d56Sopenharmony_ci    {"ascii",       (encodefunc_t) ascii_encode},
7907db96d56Sopenharmony_ci    {"iso8859-1",   (encodefunc_t) latin1_encode},
7917db96d56Sopenharmony_ci    {"utf-8",       (encodefunc_t) utf8_encode},
7927db96d56Sopenharmony_ci    {"utf-16-be",   (encodefunc_t) utf16be_encode},
7937db96d56Sopenharmony_ci    {"utf-16-le",   (encodefunc_t) utf16le_encode},
7947db96d56Sopenharmony_ci    {"utf-16",      (encodefunc_t) utf16_encode},
7957db96d56Sopenharmony_ci    {"utf-32-be",   (encodefunc_t) utf32be_encode},
7967db96d56Sopenharmony_ci    {"utf-32-le",   (encodefunc_t) utf32le_encode},
7977db96d56Sopenharmony_ci    {"utf-32",      (encodefunc_t) utf32_encode},
7987db96d56Sopenharmony_ci    {NULL, NULL}
7997db96d56Sopenharmony_ci};
8007db96d56Sopenharmony_ci
8017db96d56Sopenharmony_cistatic int
8027db96d56Sopenharmony_civalidate_newline(const char *newline)
8037db96d56Sopenharmony_ci{
8047db96d56Sopenharmony_ci    if (newline && newline[0] != '\0'
8057db96d56Sopenharmony_ci        && !(newline[0] == '\n' && newline[1] == '\0')
8067db96d56Sopenharmony_ci        && !(newline[0] == '\r' && newline[1] == '\0')
8077db96d56Sopenharmony_ci        && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
8087db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
8097db96d56Sopenharmony_ci                     "illegal newline value: %s", newline);
8107db96d56Sopenharmony_ci        return -1;
8117db96d56Sopenharmony_ci    }
8127db96d56Sopenharmony_ci    return 0;
8137db96d56Sopenharmony_ci}
8147db96d56Sopenharmony_ci
8157db96d56Sopenharmony_cistatic int
8167db96d56Sopenharmony_ciset_newline(textio *self, const char *newline)
8177db96d56Sopenharmony_ci{
8187db96d56Sopenharmony_ci    PyObject *old = self->readnl;
8197db96d56Sopenharmony_ci    if (newline == NULL) {
8207db96d56Sopenharmony_ci        self->readnl = NULL;
8217db96d56Sopenharmony_ci    }
8227db96d56Sopenharmony_ci    else {
8237db96d56Sopenharmony_ci        self->readnl = PyUnicode_FromString(newline);
8247db96d56Sopenharmony_ci        if (self->readnl == NULL) {
8257db96d56Sopenharmony_ci            self->readnl = old;
8267db96d56Sopenharmony_ci            return -1;
8277db96d56Sopenharmony_ci        }
8287db96d56Sopenharmony_ci    }
8297db96d56Sopenharmony_ci    self->readuniversal = (newline == NULL || newline[0] == '\0');
8307db96d56Sopenharmony_ci    self->readtranslate = (newline == NULL);
8317db96d56Sopenharmony_ci    self->writetranslate = (newline == NULL || newline[0] != '\0');
8327db96d56Sopenharmony_ci    if (!self->readuniversal && self->readnl != NULL) {
8337db96d56Sopenharmony_ci        // validate_newline() accepts only ASCII newlines.
8347db96d56Sopenharmony_ci        assert(PyUnicode_KIND(self->readnl) == PyUnicode_1BYTE_KIND);
8357db96d56Sopenharmony_ci        self->writenl = (const char *)PyUnicode_1BYTE_DATA(self->readnl);
8367db96d56Sopenharmony_ci        if (strcmp(self->writenl, "\n") == 0) {
8377db96d56Sopenharmony_ci            self->writenl = NULL;
8387db96d56Sopenharmony_ci        }
8397db96d56Sopenharmony_ci    }
8407db96d56Sopenharmony_ci    else {
8417db96d56Sopenharmony_ci#ifdef MS_WINDOWS
8427db96d56Sopenharmony_ci        self->writenl = "\r\n";
8437db96d56Sopenharmony_ci#else
8447db96d56Sopenharmony_ci        self->writenl = NULL;
8457db96d56Sopenharmony_ci#endif
8467db96d56Sopenharmony_ci    }
8477db96d56Sopenharmony_ci    Py_XDECREF(old);
8487db96d56Sopenharmony_ci    return 0;
8497db96d56Sopenharmony_ci}
8507db96d56Sopenharmony_ci
8517db96d56Sopenharmony_cistatic int
8527db96d56Sopenharmony_ci_textiowrapper_set_decoder(textio *self, PyObject *codec_info,
8537db96d56Sopenharmony_ci                           const char *errors)
8547db96d56Sopenharmony_ci{
8557db96d56Sopenharmony_ci    PyObject *res;
8567db96d56Sopenharmony_ci    int r;
8577db96d56Sopenharmony_ci
8587db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(readable));
8597db96d56Sopenharmony_ci    if (res == NULL)
8607db96d56Sopenharmony_ci        return -1;
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ci    r = PyObject_IsTrue(res);
8637db96d56Sopenharmony_ci    Py_DECREF(res);
8647db96d56Sopenharmony_ci    if (r == -1)
8657db96d56Sopenharmony_ci        return -1;
8667db96d56Sopenharmony_ci
8677db96d56Sopenharmony_ci    if (r != 1)
8687db96d56Sopenharmony_ci        return 0;
8697db96d56Sopenharmony_ci
8707db96d56Sopenharmony_ci    Py_CLEAR(self->decoder);
8717db96d56Sopenharmony_ci    self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info, errors);
8727db96d56Sopenharmony_ci    if (self->decoder == NULL)
8737db96d56Sopenharmony_ci        return -1;
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_ci    if (self->readuniversal) {
8767db96d56Sopenharmony_ci        PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs(
8777db96d56Sopenharmony_ci            (PyObject *)&PyIncrementalNewlineDecoder_Type,
8787db96d56Sopenharmony_ci            self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
8797db96d56Sopenharmony_ci        if (incrementalDecoder == NULL)
8807db96d56Sopenharmony_ci            return -1;
8817db96d56Sopenharmony_ci        Py_CLEAR(self->decoder);
8827db96d56Sopenharmony_ci        self->decoder = incrementalDecoder;
8837db96d56Sopenharmony_ci    }
8847db96d56Sopenharmony_ci
8857db96d56Sopenharmony_ci    return 0;
8867db96d56Sopenharmony_ci}
8877db96d56Sopenharmony_ci
8887db96d56Sopenharmony_cistatic PyObject*
8897db96d56Sopenharmony_ci_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof)
8907db96d56Sopenharmony_ci{
8917db96d56Sopenharmony_ci    PyObject *chars;
8927db96d56Sopenharmony_ci
8937db96d56Sopenharmony_ci    if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type))
8947db96d56Sopenharmony_ci        chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof);
8957db96d56Sopenharmony_ci    else
8967db96d56Sopenharmony_ci        chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes,
8977db96d56Sopenharmony_ci                                           eof ? Py_True : Py_False, NULL);
8987db96d56Sopenharmony_ci
8997db96d56Sopenharmony_ci    if (check_decoded(chars) < 0)
9007db96d56Sopenharmony_ci        // check_decoded already decreases refcount
9017db96d56Sopenharmony_ci        return NULL;
9027db96d56Sopenharmony_ci
9037db96d56Sopenharmony_ci    return chars;
9047db96d56Sopenharmony_ci}
9057db96d56Sopenharmony_ci
9067db96d56Sopenharmony_cistatic int
9077db96d56Sopenharmony_ci_textiowrapper_set_encoder(textio *self, PyObject *codec_info,
9087db96d56Sopenharmony_ci                           const char *errors)
9097db96d56Sopenharmony_ci{
9107db96d56Sopenharmony_ci    PyObject *res;
9117db96d56Sopenharmony_ci    int r;
9127db96d56Sopenharmony_ci
9137db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(writable));
9147db96d56Sopenharmony_ci    if (res == NULL)
9157db96d56Sopenharmony_ci        return -1;
9167db96d56Sopenharmony_ci
9177db96d56Sopenharmony_ci    r = PyObject_IsTrue(res);
9187db96d56Sopenharmony_ci    Py_DECREF(res);
9197db96d56Sopenharmony_ci    if (r == -1)
9207db96d56Sopenharmony_ci        return -1;
9217db96d56Sopenharmony_ci
9227db96d56Sopenharmony_ci    if (r != 1)
9237db96d56Sopenharmony_ci        return 0;
9247db96d56Sopenharmony_ci
9257db96d56Sopenharmony_ci    Py_CLEAR(self->encoder);
9267db96d56Sopenharmony_ci    self->encodefunc = NULL;
9277db96d56Sopenharmony_ci    self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info, errors);
9287db96d56Sopenharmony_ci    if (self->encoder == NULL)
9297db96d56Sopenharmony_ci        return -1;
9307db96d56Sopenharmony_ci
9317db96d56Sopenharmony_ci    /* Get the normalized named of the codec */
9327db96d56Sopenharmony_ci    if (_PyObject_LookupAttr(codec_info, &_Py_ID(name), &res) < 0) {
9337db96d56Sopenharmony_ci        return -1;
9347db96d56Sopenharmony_ci    }
9357db96d56Sopenharmony_ci    if (res != NULL && PyUnicode_Check(res)) {
9367db96d56Sopenharmony_ci        const encodefuncentry *e = encodefuncs;
9377db96d56Sopenharmony_ci        while (e->name != NULL) {
9387db96d56Sopenharmony_ci            if (_PyUnicode_EqualToASCIIString(res, e->name)) {
9397db96d56Sopenharmony_ci                self->encodefunc = e->encodefunc;
9407db96d56Sopenharmony_ci                break;
9417db96d56Sopenharmony_ci            }
9427db96d56Sopenharmony_ci            e++;
9437db96d56Sopenharmony_ci        }
9447db96d56Sopenharmony_ci    }
9457db96d56Sopenharmony_ci    Py_XDECREF(res);
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci    return 0;
9487db96d56Sopenharmony_ci}
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_cistatic int
9517db96d56Sopenharmony_ci_textiowrapper_fix_encoder_state(textio *self)
9527db96d56Sopenharmony_ci{
9537db96d56Sopenharmony_ci    if (!self->seekable || !self->encoder) {
9547db96d56Sopenharmony_ci        return 0;
9557db96d56Sopenharmony_ci    }
9567db96d56Sopenharmony_ci
9577db96d56Sopenharmony_ci    self->encoding_start_of_stream = 1;
9587db96d56Sopenharmony_ci
9597db96d56Sopenharmony_ci    PyObject *cookieObj = PyObject_CallMethodNoArgs(
9607db96d56Sopenharmony_ci        self->buffer, &_Py_ID(tell));
9617db96d56Sopenharmony_ci    if (cookieObj == NULL) {
9627db96d56Sopenharmony_ci        return -1;
9637db96d56Sopenharmony_ci    }
9647db96d56Sopenharmony_ci
9657db96d56Sopenharmony_ci    int cmp = PyObject_RichCompareBool(cookieObj, _PyLong_GetZero(), Py_EQ);
9667db96d56Sopenharmony_ci    Py_DECREF(cookieObj);
9677db96d56Sopenharmony_ci    if (cmp < 0) {
9687db96d56Sopenharmony_ci        return -1;
9697db96d56Sopenharmony_ci    }
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_ci    if (cmp == 0) {
9727db96d56Sopenharmony_ci        self->encoding_start_of_stream = 0;
9737db96d56Sopenharmony_ci        PyObject *res = PyObject_CallMethodOneArg(
9747db96d56Sopenharmony_ci            self->encoder, &_Py_ID(setstate), _PyLong_GetZero());
9757db96d56Sopenharmony_ci        if (res == NULL) {
9767db96d56Sopenharmony_ci            return -1;
9777db96d56Sopenharmony_ci        }
9787db96d56Sopenharmony_ci        Py_DECREF(res);
9797db96d56Sopenharmony_ci    }
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci    return 0;
9827db96d56Sopenharmony_ci}
9837db96d56Sopenharmony_ci
9847db96d56Sopenharmony_cistatic int
9857db96d56Sopenharmony_ciio_check_errors(PyObject *errors)
9867db96d56Sopenharmony_ci{
9877db96d56Sopenharmony_ci    assert(errors != NULL && errors != Py_None);
9887db96d56Sopenharmony_ci
9897db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
9907db96d56Sopenharmony_ci#ifndef Py_DEBUG
9917db96d56Sopenharmony_ci    /* In release mode, only check in development mode (-X dev) */
9927db96d56Sopenharmony_ci    if (!_PyInterpreterState_GetConfig(interp)->dev_mode) {
9937db96d56Sopenharmony_ci        return 0;
9947db96d56Sopenharmony_ci    }
9957db96d56Sopenharmony_ci#else
9967db96d56Sopenharmony_ci    /* Always check in debug mode */
9977db96d56Sopenharmony_ci#endif
9987db96d56Sopenharmony_ci
9997db96d56Sopenharmony_ci    /* Avoid calling PyCodec_LookupError() before the codec registry is ready:
10007db96d56Sopenharmony_ci       before_PyUnicode_InitEncodings() is called. */
10017db96d56Sopenharmony_ci    if (!interp->unicode.fs_codec.encoding) {
10027db96d56Sopenharmony_ci        return 0;
10037db96d56Sopenharmony_ci    }
10047db96d56Sopenharmony_ci
10057db96d56Sopenharmony_ci    Py_ssize_t name_length;
10067db96d56Sopenharmony_ci    const char *name = PyUnicode_AsUTF8AndSize(errors, &name_length);
10077db96d56Sopenharmony_ci    if (name == NULL) {
10087db96d56Sopenharmony_ci        return -1;
10097db96d56Sopenharmony_ci    }
10107db96d56Sopenharmony_ci    if (strlen(name) != (size_t)name_length) {
10117db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, "embedded null character in errors");
10127db96d56Sopenharmony_ci        return -1;
10137db96d56Sopenharmony_ci    }
10147db96d56Sopenharmony_ci    PyObject *handler = PyCodec_LookupError(name);
10157db96d56Sopenharmony_ci    if (handler != NULL) {
10167db96d56Sopenharmony_ci        Py_DECREF(handler);
10177db96d56Sopenharmony_ci        return 0;
10187db96d56Sopenharmony_ci    }
10197db96d56Sopenharmony_ci    return -1;
10207db96d56Sopenharmony_ci}
10217db96d56Sopenharmony_ci
10227db96d56Sopenharmony_ci
10237db96d56Sopenharmony_ci
10247db96d56Sopenharmony_ci/*[clinic input]
10257db96d56Sopenharmony_ci_io.TextIOWrapper.__init__
10267db96d56Sopenharmony_ci    buffer: object
10277db96d56Sopenharmony_ci    encoding: str(accept={str, NoneType}) = None
10287db96d56Sopenharmony_ci    errors: object = None
10297db96d56Sopenharmony_ci    newline: str(accept={str, NoneType}) = None
10307db96d56Sopenharmony_ci    line_buffering: bool(accept={int}) = False
10317db96d56Sopenharmony_ci    write_through: bool(accept={int}) = False
10327db96d56Sopenharmony_ci
10337db96d56Sopenharmony_ciCharacter and line based layer over a BufferedIOBase object, buffer.
10347db96d56Sopenharmony_ci
10357db96d56Sopenharmony_ciencoding gives the name of the encoding that the stream will be
10367db96d56Sopenharmony_cidecoded or encoded with. It defaults to locale.getencoding().
10377db96d56Sopenharmony_ci
10387db96d56Sopenharmony_cierrors determines the strictness of encoding and decoding (see
10397db96d56Sopenharmony_cihelp(codecs.Codec) or the documentation for codecs.register) and
10407db96d56Sopenharmony_cidefaults to "strict".
10417db96d56Sopenharmony_ci
10427db96d56Sopenharmony_cinewline controls how line endings are handled. It can be None, '',
10437db96d56Sopenharmony_ci'\n', '\r', and '\r\n'.  It works as follows:
10447db96d56Sopenharmony_ci
10457db96d56Sopenharmony_ci* On input, if newline is None, universal newlines mode is
10467db96d56Sopenharmony_ci  enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
10477db96d56Sopenharmony_ci  these are translated into '\n' before being returned to the
10487db96d56Sopenharmony_ci  caller. If it is '', universal newline mode is enabled, but line
10497db96d56Sopenharmony_ci  endings are returned to the caller untranslated. If it has any of
10507db96d56Sopenharmony_ci  the other legal values, input lines are only terminated by the given
10517db96d56Sopenharmony_ci  string, and the line ending is returned to the caller untranslated.
10527db96d56Sopenharmony_ci
10537db96d56Sopenharmony_ci* On output, if newline is None, any '\n' characters written are
10547db96d56Sopenharmony_ci  translated to the system default line separator, os.linesep. If
10557db96d56Sopenharmony_ci  newline is '' or '\n', no translation takes place. If newline is any
10567db96d56Sopenharmony_ci  of the other legal values, any '\n' characters written are translated
10577db96d56Sopenharmony_ci  to the given string.
10587db96d56Sopenharmony_ci
10597db96d56Sopenharmony_ciIf line_buffering is True, a call to flush is implied when a call to
10607db96d56Sopenharmony_ciwrite contains a newline character.
10617db96d56Sopenharmony_ci[clinic start generated code]*/
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_cistatic int
10647db96d56Sopenharmony_ci_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
10657db96d56Sopenharmony_ci                                const char *encoding, PyObject *errors,
10667db96d56Sopenharmony_ci                                const char *newline, int line_buffering,
10677db96d56Sopenharmony_ci                                int write_through)
10687db96d56Sopenharmony_ci/*[clinic end generated code: output=72267c0c01032ed2 input=72590963698f289b]*/
10697db96d56Sopenharmony_ci{
10707db96d56Sopenharmony_ci    PyObject *raw, *codec_info = NULL;
10717db96d56Sopenharmony_ci    PyObject *res;
10727db96d56Sopenharmony_ci    int r;
10737db96d56Sopenharmony_ci
10747db96d56Sopenharmony_ci    self->ok = 0;
10757db96d56Sopenharmony_ci    self->detached = 0;
10767db96d56Sopenharmony_ci
10777db96d56Sopenharmony_ci    if (encoding == NULL) {
10787db96d56Sopenharmony_ci        PyInterpreterState *interp = _PyInterpreterState_GET();
10797db96d56Sopenharmony_ci        if (_PyInterpreterState_GetConfig(interp)->warn_default_encoding) {
10807db96d56Sopenharmony_ci            if (PyErr_WarnEx(PyExc_EncodingWarning,
10817db96d56Sopenharmony_ci                             "'encoding' argument not specified", 1)) {
10827db96d56Sopenharmony_ci                return -1;
10837db96d56Sopenharmony_ci            }
10847db96d56Sopenharmony_ci        }
10857db96d56Sopenharmony_ci    }
10867db96d56Sopenharmony_ci
10877db96d56Sopenharmony_ci    if (errors == Py_None) {
10887db96d56Sopenharmony_ci        errors = &_Py_ID(strict);
10897db96d56Sopenharmony_ci    }
10907db96d56Sopenharmony_ci    else if (!PyUnicode_Check(errors)) {
10917db96d56Sopenharmony_ci        // Check 'errors' argument here because Argument Clinic doesn't support
10927db96d56Sopenharmony_ci        // 'str(accept={str, NoneType})' converter.
10937db96d56Sopenharmony_ci        PyErr_Format(
10947db96d56Sopenharmony_ci            PyExc_TypeError,
10957db96d56Sopenharmony_ci            "TextIOWrapper() argument 'errors' must be str or None, not %.50s",
10967db96d56Sopenharmony_ci            Py_TYPE(errors)->tp_name);
10977db96d56Sopenharmony_ci        return -1;
10987db96d56Sopenharmony_ci    }
10997db96d56Sopenharmony_ci    else if (io_check_errors(errors)) {
11007db96d56Sopenharmony_ci        return -1;
11017db96d56Sopenharmony_ci    }
11027db96d56Sopenharmony_ci
11037db96d56Sopenharmony_ci    if (validate_newline(newline) < 0) {
11047db96d56Sopenharmony_ci        return -1;
11057db96d56Sopenharmony_ci    }
11067db96d56Sopenharmony_ci
11077db96d56Sopenharmony_ci    Py_CLEAR(self->buffer);
11087db96d56Sopenharmony_ci    Py_CLEAR(self->encoding);
11097db96d56Sopenharmony_ci    Py_CLEAR(self->encoder);
11107db96d56Sopenharmony_ci    Py_CLEAR(self->decoder);
11117db96d56Sopenharmony_ci    Py_CLEAR(self->readnl);
11127db96d56Sopenharmony_ci    Py_CLEAR(self->decoded_chars);
11137db96d56Sopenharmony_ci    Py_CLEAR(self->pending_bytes);
11147db96d56Sopenharmony_ci    Py_CLEAR(self->snapshot);
11157db96d56Sopenharmony_ci    Py_CLEAR(self->errors);
11167db96d56Sopenharmony_ci    Py_CLEAR(self->raw);
11177db96d56Sopenharmony_ci    self->decoded_chars_used = 0;
11187db96d56Sopenharmony_ci    self->pending_bytes_count = 0;
11197db96d56Sopenharmony_ci    self->encodefunc = NULL;
11207db96d56Sopenharmony_ci    self->b2cratio = 0.0;
11217db96d56Sopenharmony_ci
11227db96d56Sopenharmony_ci    if (encoding == NULL && _PyRuntime.preconfig.utf8_mode) {
11237db96d56Sopenharmony_ci        _Py_DECLARE_STR(utf_8, "utf-8");
11247db96d56Sopenharmony_ci        self->encoding = Py_NewRef(&_Py_STR(utf_8));
11257db96d56Sopenharmony_ci    }
11267db96d56Sopenharmony_ci    else if (encoding == NULL || (strcmp(encoding, "locale") == 0)) {
11277db96d56Sopenharmony_ci        self->encoding = _Py_GetLocaleEncodingObject();
11287db96d56Sopenharmony_ci        if (self->encoding == NULL) {
11297db96d56Sopenharmony_ci            goto error;
11307db96d56Sopenharmony_ci        }
11317db96d56Sopenharmony_ci        assert(PyUnicode_Check(self->encoding));
11327db96d56Sopenharmony_ci    }
11337db96d56Sopenharmony_ci
11347db96d56Sopenharmony_ci    if (self->encoding != NULL) {
11357db96d56Sopenharmony_ci        encoding = PyUnicode_AsUTF8(self->encoding);
11367db96d56Sopenharmony_ci        if (encoding == NULL)
11377db96d56Sopenharmony_ci            goto error;
11387db96d56Sopenharmony_ci    }
11397db96d56Sopenharmony_ci    else if (encoding != NULL) {
11407db96d56Sopenharmony_ci        self->encoding = PyUnicode_FromString(encoding);
11417db96d56Sopenharmony_ci        if (self->encoding == NULL)
11427db96d56Sopenharmony_ci            goto error;
11437db96d56Sopenharmony_ci    }
11447db96d56Sopenharmony_ci    else {
11457db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OSError,
11467db96d56Sopenharmony_ci                        "could not determine default encoding");
11477db96d56Sopenharmony_ci        goto error;
11487db96d56Sopenharmony_ci    }
11497db96d56Sopenharmony_ci
11507db96d56Sopenharmony_ci    /* Check we have been asked for a real text encoding */
11517db96d56Sopenharmony_ci    codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()");
11527db96d56Sopenharmony_ci    if (codec_info == NULL) {
11537db96d56Sopenharmony_ci        Py_CLEAR(self->encoding);
11547db96d56Sopenharmony_ci        goto error;
11557db96d56Sopenharmony_ci    }
11567db96d56Sopenharmony_ci
11577db96d56Sopenharmony_ci    /* XXX: Failures beyond this point have the potential to leak elements
11587db96d56Sopenharmony_ci     * of the partially constructed object (like self->encoding)
11597db96d56Sopenharmony_ci     */
11607db96d56Sopenharmony_ci
11617db96d56Sopenharmony_ci    Py_INCREF(errors);
11627db96d56Sopenharmony_ci    self->errors = errors;
11637db96d56Sopenharmony_ci    self->chunk_size = 8192;
11647db96d56Sopenharmony_ci    self->line_buffering = line_buffering;
11657db96d56Sopenharmony_ci    self->write_through = write_through;
11667db96d56Sopenharmony_ci    if (set_newline(self, newline) < 0) {
11677db96d56Sopenharmony_ci        goto error;
11687db96d56Sopenharmony_ci    }
11697db96d56Sopenharmony_ci
11707db96d56Sopenharmony_ci    self->buffer = buffer;
11717db96d56Sopenharmony_ci    Py_INCREF(buffer);
11727db96d56Sopenharmony_ci
11737db96d56Sopenharmony_ci    /* Build the decoder object */
11747db96d56Sopenharmony_ci    if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0)
11757db96d56Sopenharmony_ci        goto error;
11767db96d56Sopenharmony_ci
11777db96d56Sopenharmony_ci    /* Build the encoder object */
11787db96d56Sopenharmony_ci    if (_textiowrapper_set_encoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0)
11797db96d56Sopenharmony_ci        goto error;
11807db96d56Sopenharmony_ci
11817db96d56Sopenharmony_ci    /* Finished sorting out the codec details */
11827db96d56Sopenharmony_ci    Py_CLEAR(codec_info);
11837db96d56Sopenharmony_ci
11847db96d56Sopenharmony_ci    if (Py_IS_TYPE(buffer, &PyBufferedReader_Type) ||
11857db96d56Sopenharmony_ci        Py_IS_TYPE(buffer, &PyBufferedWriter_Type) ||
11867db96d56Sopenharmony_ci        Py_IS_TYPE(buffer, &PyBufferedRandom_Type))
11877db96d56Sopenharmony_ci    {
11887db96d56Sopenharmony_ci        if (_PyObject_LookupAttr(buffer, &_Py_ID(raw), &raw) < 0)
11897db96d56Sopenharmony_ci            goto error;
11907db96d56Sopenharmony_ci        /* Cache the raw FileIO object to speed up 'closed' checks */
11917db96d56Sopenharmony_ci        if (raw != NULL) {
11927db96d56Sopenharmony_ci            if (Py_IS_TYPE(raw, &PyFileIO_Type))
11937db96d56Sopenharmony_ci                self->raw = raw;
11947db96d56Sopenharmony_ci            else
11957db96d56Sopenharmony_ci                Py_DECREF(raw);
11967db96d56Sopenharmony_ci        }
11977db96d56Sopenharmony_ci    }
11987db96d56Sopenharmony_ci
11997db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs(buffer, &_Py_ID(seekable));
12007db96d56Sopenharmony_ci    if (res == NULL)
12017db96d56Sopenharmony_ci        goto error;
12027db96d56Sopenharmony_ci    r = PyObject_IsTrue(res);
12037db96d56Sopenharmony_ci    Py_DECREF(res);
12047db96d56Sopenharmony_ci    if (r < 0)
12057db96d56Sopenharmony_ci        goto error;
12067db96d56Sopenharmony_ci    self->seekable = self->telling = r;
12077db96d56Sopenharmony_ci
12087db96d56Sopenharmony_ci    r = _PyObject_LookupAttr(buffer, &_Py_ID(read1), &res);
12097db96d56Sopenharmony_ci    if (r < 0) {
12107db96d56Sopenharmony_ci        goto error;
12117db96d56Sopenharmony_ci    }
12127db96d56Sopenharmony_ci    Py_XDECREF(res);
12137db96d56Sopenharmony_ci    self->has_read1 = r;
12147db96d56Sopenharmony_ci
12157db96d56Sopenharmony_ci    self->encoding_start_of_stream = 0;
12167db96d56Sopenharmony_ci    if (_textiowrapper_fix_encoder_state(self) < 0) {
12177db96d56Sopenharmony_ci        goto error;
12187db96d56Sopenharmony_ci    }
12197db96d56Sopenharmony_ci
12207db96d56Sopenharmony_ci    self->ok = 1;
12217db96d56Sopenharmony_ci    return 0;
12227db96d56Sopenharmony_ci
12237db96d56Sopenharmony_ci  error:
12247db96d56Sopenharmony_ci    Py_XDECREF(codec_info);
12257db96d56Sopenharmony_ci    return -1;
12267db96d56Sopenharmony_ci}
12277db96d56Sopenharmony_ci
12287db96d56Sopenharmony_ci/* Return *default_value* if ob is None, 0 if ob is false, 1 if ob is true,
12297db96d56Sopenharmony_ci * -1 on error.
12307db96d56Sopenharmony_ci */
12317db96d56Sopenharmony_cistatic int
12327db96d56Sopenharmony_ciconvert_optional_bool(PyObject *obj, int default_value)
12337db96d56Sopenharmony_ci{
12347db96d56Sopenharmony_ci    long v;
12357db96d56Sopenharmony_ci    if (obj == Py_None) {
12367db96d56Sopenharmony_ci        v = default_value;
12377db96d56Sopenharmony_ci    }
12387db96d56Sopenharmony_ci    else {
12397db96d56Sopenharmony_ci        v = PyLong_AsLong(obj);
12407db96d56Sopenharmony_ci        if (v == -1 && PyErr_Occurred())
12417db96d56Sopenharmony_ci            return -1;
12427db96d56Sopenharmony_ci    }
12437db96d56Sopenharmony_ci    return v != 0;
12447db96d56Sopenharmony_ci}
12457db96d56Sopenharmony_ci
12467db96d56Sopenharmony_cistatic int
12477db96d56Sopenharmony_citextiowrapper_change_encoding(textio *self, PyObject *encoding,
12487db96d56Sopenharmony_ci                              PyObject *errors, int newline_changed)
12497db96d56Sopenharmony_ci{
12507db96d56Sopenharmony_ci    /* Use existing settings where new settings are not specified */
12517db96d56Sopenharmony_ci    if (encoding == Py_None && errors == Py_None && !newline_changed) {
12527db96d56Sopenharmony_ci        return 0;  // no change
12537db96d56Sopenharmony_ci    }
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_ci    if (encoding == Py_None) {
12567db96d56Sopenharmony_ci        encoding = self->encoding;
12577db96d56Sopenharmony_ci        if (errors == Py_None) {
12587db96d56Sopenharmony_ci            errors = self->errors;
12597db96d56Sopenharmony_ci        }
12607db96d56Sopenharmony_ci        Py_INCREF(encoding);
12617db96d56Sopenharmony_ci    }
12627db96d56Sopenharmony_ci    else {
12637db96d56Sopenharmony_ci        if (_PyUnicode_EqualToASCIIString(encoding, "locale")) {
12647db96d56Sopenharmony_ci            encoding = _Py_GetLocaleEncodingObject();
12657db96d56Sopenharmony_ci            if (encoding == NULL) {
12667db96d56Sopenharmony_ci                return -1;
12677db96d56Sopenharmony_ci            }
12687db96d56Sopenharmony_ci        } else {
12697db96d56Sopenharmony_ci            Py_INCREF(encoding);
12707db96d56Sopenharmony_ci        }
12717db96d56Sopenharmony_ci        if (errors == Py_None) {
12727db96d56Sopenharmony_ci            errors = &_Py_ID(strict);
12737db96d56Sopenharmony_ci        }
12747db96d56Sopenharmony_ci    }
12757db96d56Sopenharmony_ci
12767db96d56Sopenharmony_ci    const char *c_errors = PyUnicode_AsUTF8(errors);
12777db96d56Sopenharmony_ci    if (c_errors == NULL) {
12787db96d56Sopenharmony_ci        Py_DECREF(encoding);
12797db96d56Sopenharmony_ci        return -1;
12807db96d56Sopenharmony_ci    }
12817db96d56Sopenharmony_ci
12827db96d56Sopenharmony_ci    // Create new encoder & decoder
12837db96d56Sopenharmony_ci    PyObject *codec_info = _PyCodec_LookupTextEncoding(
12847db96d56Sopenharmony_ci        PyUnicode_AsUTF8(encoding), "codecs.open()");
12857db96d56Sopenharmony_ci    if (codec_info == NULL) {
12867db96d56Sopenharmony_ci        Py_DECREF(encoding);
12877db96d56Sopenharmony_ci        return -1;
12887db96d56Sopenharmony_ci    }
12897db96d56Sopenharmony_ci    if (_textiowrapper_set_decoder(self, codec_info, c_errors) != 0 ||
12907db96d56Sopenharmony_ci            _textiowrapper_set_encoder(self, codec_info, c_errors) != 0) {
12917db96d56Sopenharmony_ci        Py_DECREF(codec_info);
12927db96d56Sopenharmony_ci        Py_DECREF(encoding);
12937db96d56Sopenharmony_ci        return -1;
12947db96d56Sopenharmony_ci    }
12957db96d56Sopenharmony_ci    Py_DECREF(codec_info);
12967db96d56Sopenharmony_ci
12977db96d56Sopenharmony_ci    Py_INCREF(errors);
12987db96d56Sopenharmony_ci    Py_SETREF(self->encoding, encoding);
12997db96d56Sopenharmony_ci    Py_SETREF(self->errors, errors);
13007db96d56Sopenharmony_ci
13017db96d56Sopenharmony_ci    return _textiowrapper_fix_encoder_state(self);
13027db96d56Sopenharmony_ci}
13037db96d56Sopenharmony_ci
13047db96d56Sopenharmony_ci/*[clinic input]
13057db96d56Sopenharmony_ci_io.TextIOWrapper.reconfigure
13067db96d56Sopenharmony_ci    *
13077db96d56Sopenharmony_ci    encoding: object = None
13087db96d56Sopenharmony_ci    errors: object = None
13097db96d56Sopenharmony_ci    newline as newline_obj: object(c_default="NULL") = None
13107db96d56Sopenharmony_ci    line_buffering as line_buffering_obj: object = None
13117db96d56Sopenharmony_ci    write_through as write_through_obj: object = None
13127db96d56Sopenharmony_ci
13137db96d56Sopenharmony_ciReconfigure the text stream with new parameters.
13147db96d56Sopenharmony_ci
13157db96d56Sopenharmony_ciThis also does an implicit stream flush.
13167db96d56Sopenharmony_ci
13177db96d56Sopenharmony_ci[clinic start generated code]*/
13187db96d56Sopenharmony_ci
13197db96d56Sopenharmony_cistatic PyObject *
13207db96d56Sopenharmony_ci_io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding,
13217db96d56Sopenharmony_ci                                   PyObject *errors, PyObject *newline_obj,
13227db96d56Sopenharmony_ci                                   PyObject *line_buffering_obj,
13237db96d56Sopenharmony_ci                                   PyObject *write_through_obj)
13247db96d56Sopenharmony_ci/*[clinic end generated code: output=52b812ff4b3d4b0f input=671e82136e0f5822]*/
13257db96d56Sopenharmony_ci{
13267db96d56Sopenharmony_ci    int line_buffering;
13277db96d56Sopenharmony_ci    int write_through;
13287db96d56Sopenharmony_ci    const char *newline = NULL;
13297db96d56Sopenharmony_ci
13307db96d56Sopenharmony_ci    /* Check if something is in the read buffer */
13317db96d56Sopenharmony_ci    if (self->decoded_chars != NULL) {
13327db96d56Sopenharmony_ci        if (encoding != Py_None || errors != Py_None || newline_obj != NULL) {
13337db96d56Sopenharmony_ci            _unsupported("It is not possible to set the encoding or newline "
13347db96d56Sopenharmony_ci                         "of stream after the first read");
13357db96d56Sopenharmony_ci            return NULL;
13367db96d56Sopenharmony_ci        }
13377db96d56Sopenharmony_ci    }
13387db96d56Sopenharmony_ci
13397db96d56Sopenharmony_ci    if (newline_obj != NULL && newline_obj != Py_None) {
13407db96d56Sopenharmony_ci        newline = PyUnicode_AsUTF8(newline_obj);
13417db96d56Sopenharmony_ci        if (newline == NULL || validate_newline(newline) < 0) {
13427db96d56Sopenharmony_ci            return NULL;
13437db96d56Sopenharmony_ci        }
13447db96d56Sopenharmony_ci    }
13457db96d56Sopenharmony_ci
13467db96d56Sopenharmony_ci    line_buffering = convert_optional_bool(line_buffering_obj,
13477db96d56Sopenharmony_ci                                           self->line_buffering);
13487db96d56Sopenharmony_ci    write_through = convert_optional_bool(write_through_obj,
13497db96d56Sopenharmony_ci                                          self->write_through);
13507db96d56Sopenharmony_ci    if (line_buffering < 0 || write_through < 0) {
13517db96d56Sopenharmony_ci        return NULL;
13527db96d56Sopenharmony_ci    }
13537db96d56Sopenharmony_ci
13547db96d56Sopenharmony_ci    PyObject *res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
13557db96d56Sopenharmony_ci    if (res == NULL) {
13567db96d56Sopenharmony_ci        return NULL;
13577db96d56Sopenharmony_ci    }
13587db96d56Sopenharmony_ci    Py_DECREF(res);
13597db96d56Sopenharmony_ci    self->b2cratio = 0;
13607db96d56Sopenharmony_ci
13617db96d56Sopenharmony_ci    if (newline_obj != NULL && set_newline(self, newline) < 0) {
13627db96d56Sopenharmony_ci        return NULL;
13637db96d56Sopenharmony_ci    }
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_ci    if (textiowrapper_change_encoding(
13667db96d56Sopenharmony_ci            self, encoding, errors, newline_obj != NULL) < 0) {
13677db96d56Sopenharmony_ci        return NULL;
13687db96d56Sopenharmony_ci    }
13697db96d56Sopenharmony_ci
13707db96d56Sopenharmony_ci    self->line_buffering = line_buffering;
13717db96d56Sopenharmony_ci    self->write_through = write_through;
13727db96d56Sopenharmony_ci    Py_RETURN_NONE;
13737db96d56Sopenharmony_ci}
13747db96d56Sopenharmony_ci
13757db96d56Sopenharmony_cistatic int
13767db96d56Sopenharmony_citextiowrapper_clear(textio *self)
13777db96d56Sopenharmony_ci{
13787db96d56Sopenharmony_ci    self->ok = 0;
13797db96d56Sopenharmony_ci    Py_CLEAR(self->buffer);
13807db96d56Sopenharmony_ci    Py_CLEAR(self->encoding);
13817db96d56Sopenharmony_ci    Py_CLEAR(self->encoder);
13827db96d56Sopenharmony_ci    Py_CLEAR(self->decoder);
13837db96d56Sopenharmony_ci    Py_CLEAR(self->readnl);
13847db96d56Sopenharmony_ci    Py_CLEAR(self->decoded_chars);
13857db96d56Sopenharmony_ci    Py_CLEAR(self->pending_bytes);
13867db96d56Sopenharmony_ci    Py_CLEAR(self->snapshot);
13877db96d56Sopenharmony_ci    Py_CLEAR(self->errors);
13887db96d56Sopenharmony_ci    Py_CLEAR(self->raw);
13897db96d56Sopenharmony_ci
13907db96d56Sopenharmony_ci    Py_CLEAR(self->dict);
13917db96d56Sopenharmony_ci    return 0;
13927db96d56Sopenharmony_ci}
13937db96d56Sopenharmony_ci
13947db96d56Sopenharmony_cistatic void
13957db96d56Sopenharmony_citextiowrapper_dealloc(textio *self)
13967db96d56Sopenharmony_ci{
13977db96d56Sopenharmony_ci    self->finalizing = 1;
13987db96d56Sopenharmony_ci    if (_PyIOBase_finalize((PyObject *) self) < 0)
13997db96d56Sopenharmony_ci        return;
14007db96d56Sopenharmony_ci    self->ok = 0;
14017db96d56Sopenharmony_ci    _PyObject_GC_UNTRACK(self);
14027db96d56Sopenharmony_ci    if (self->weakreflist != NULL)
14037db96d56Sopenharmony_ci        PyObject_ClearWeakRefs((PyObject *)self);
14047db96d56Sopenharmony_ci    textiowrapper_clear(self);
14057db96d56Sopenharmony_ci    Py_TYPE(self)->tp_free((PyObject *)self);
14067db96d56Sopenharmony_ci}
14077db96d56Sopenharmony_ci
14087db96d56Sopenharmony_cistatic int
14097db96d56Sopenharmony_citextiowrapper_traverse(textio *self, visitproc visit, void *arg)
14107db96d56Sopenharmony_ci{
14117db96d56Sopenharmony_ci    Py_VISIT(self->buffer);
14127db96d56Sopenharmony_ci    Py_VISIT(self->encoding);
14137db96d56Sopenharmony_ci    Py_VISIT(self->encoder);
14147db96d56Sopenharmony_ci    Py_VISIT(self->decoder);
14157db96d56Sopenharmony_ci    Py_VISIT(self->readnl);
14167db96d56Sopenharmony_ci    Py_VISIT(self->decoded_chars);
14177db96d56Sopenharmony_ci    Py_VISIT(self->pending_bytes);
14187db96d56Sopenharmony_ci    Py_VISIT(self->snapshot);
14197db96d56Sopenharmony_ci    Py_VISIT(self->errors);
14207db96d56Sopenharmony_ci    Py_VISIT(self->raw);
14217db96d56Sopenharmony_ci
14227db96d56Sopenharmony_ci    Py_VISIT(self->dict);
14237db96d56Sopenharmony_ci    return 0;
14247db96d56Sopenharmony_ci}
14257db96d56Sopenharmony_ci
14267db96d56Sopenharmony_cistatic PyObject *
14277db96d56Sopenharmony_citextiowrapper_closed_get(textio *self, void *context);
14287db96d56Sopenharmony_ci
14297db96d56Sopenharmony_ci/* This macro takes some shortcuts to make the common case faster. */
14307db96d56Sopenharmony_ci#define CHECK_CLOSED(self) \
14317db96d56Sopenharmony_ci    do { \
14327db96d56Sopenharmony_ci        int r; \
14337db96d56Sopenharmony_ci        PyObject *_res; \
14347db96d56Sopenharmony_ci        if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) { \
14357db96d56Sopenharmony_ci            if (self->raw != NULL) \
14367db96d56Sopenharmony_ci                r = _PyFileIO_closed(self->raw); \
14377db96d56Sopenharmony_ci            else { \
14387db96d56Sopenharmony_ci                _res = textiowrapper_closed_get(self, NULL); \
14397db96d56Sopenharmony_ci                if (_res == NULL) \
14407db96d56Sopenharmony_ci                    return NULL; \
14417db96d56Sopenharmony_ci                r = PyObject_IsTrue(_res); \
14427db96d56Sopenharmony_ci                Py_DECREF(_res); \
14437db96d56Sopenharmony_ci                if (r < 0) \
14447db96d56Sopenharmony_ci                    return NULL; \
14457db96d56Sopenharmony_ci            } \
14467db96d56Sopenharmony_ci            if (r > 0) { \
14477db96d56Sopenharmony_ci                PyErr_SetString(PyExc_ValueError, \
14487db96d56Sopenharmony_ci                                "I/O operation on closed file."); \
14497db96d56Sopenharmony_ci                return NULL; \
14507db96d56Sopenharmony_ci            } \
14517db96d56Sopenharmony_ci        } \
14527db96d56Sopenharmony_ci        else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \
14537db96d56Sopenharmony_ci            return NULL; \
14547db96d56Sopenharmony_ci    } while (0)
14557db96d56Sopenharmony_ci
14567db96d56Sopenharmony_ci#define CHECK_INITIALIZED(self) \
14577db96d56Sopenharmony_ci    if (self->ok <= 0) { \
14587db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, \
14597db96d56Sopenharmony_ci            "I/O operation on uninitialized object"); \
14607db96d56Sopenharmony_ci        return NULL; \
14617db96d56Sopenharmony_ci    }
14627db96d56Sopenharmony_ci
14637db96d56Sopenharmony_ci#define CHECK_ATTACHED(self) \
14647db96d56Sopenharmony_ci    CHECK_INITIALIZED(self); \
14657db96d56Sopenharmony_ci    if (self->detached) { \
14667db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, \
14677db96d56Sopenharmony_ci             "underlying buffer has been detached"); \
14687db96d56Sopenharmony_ci        return NULL; \
14697db96d56Sopenharmony_ci    }
14707db96d56Sopenharmony_ci
14717db96d56Sopenharmony_ci#define CHECK_ATTACHED_INT(self) \
14727db96d56Sopenharmony_ci    if (self->ok <= 0) { \
14737db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, \
14747db96d56Sopenharmony_ci            "I/O operation on uninitialized object"); \
14757db96d56Sopenharmony_ci        return -1; \
14767db96d56Sopenharmony_ci    } else if (self->detached) { \
14777db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError, \
14787db96d56Sopenharmony_ci             "underlying buffer has been detached"); \
14797db96d56Sopenharmony_ci        return -1; \
14807db96d56Sopenharmony_ci    }
14817db96d56Sopenharmony_ci
14827db96d56Sopenharmony_ci
14837db96d56Sopenharmony_ci/*[clinic input]
14847db96d56Sopenharmony_ci_io.TextIOWrapper.detach
14857db96d56Sopenharmony_ci[clinic start generated code]*/
14867db96d56Sopenharmony_ci
14877db96d56Sopenharmony_cistatic PyObject *
14887db96d56Sopenharmony_ci_io_TextIOWrapper_detach_impl(textio *self)
14897db96d56Sopenharmony_ci/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/
14907db96d56Sopenharmony_ci{
14917db96d56Sopenharmony_ci    PyObject *buffer, *res;
14927db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
14937db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
14947db96d56Sopenharmony_ci    if (res == NULL)
14957db96d56Sopenharmony_ci        return NULL;
14967db96d56Sopenharmony_ci    Py_DECREF(res);
14977db96d56Sopenharmony_ci    buffer = self->buffer;
14987db96d56Sopenharmony_ci    self->buffer = NULL;
14997db96d56Sopenharmony_ci    self->detached = 1;
15007db96d56Sopenharmony_ci    return buffer;
15017db96d56Sopenharmony_ci}
15027db96d56Sopenharmony_ci
15037db96d56Sopenharmony_ci/* Flush the internal write buffer. This doesn't explicitly flush the
15047db96d56Sopenharmony_ci   underlying buffered object, though. */
15057db96d56Sopenharmony_cistatic int
15067db96d56Sopenharmony_ci_textiowrapper_writeflush(textio *self)
15077db96d56Sopenharmony_ci{
15087db96d56Sopenharmony_ci    if (self->pending_bytes == NULL)
15097db96d56Sopenharmony_ci        return 0;
15107db96d56Sopenharmony_ci
15117db96d56Sopenharmony_ci    PyObject *pending = self->pending_bytes;
15127db96d56Sopenharmony_ci    PyObject *b;
15137db96d56Sopenharmony_ci
15147db96d56Sopenharmony_ci    if (PyBytes_Check(pending)) {
15157db96d56Sopenharmony_ci        b = pending;
15167db96d56Sopenharmony_ci        Py_INCREF(b);
15177db96d56Sopenharmony_ci    }
15187db96d56Sopenharmony_ci    else if (PyUnicode_Check(pending)) {
15197db96d56Sopenharmony_ci        assert(PyUnicode_IS_ASCII(pending));
15207db96d56Sopenharmony_ci        assert(PyUnicode_GET_LENGTH(pending) == self->pending_bytes_count);
15217db96d56Sopenharmony_ci        b = PyBytes_FromStringAndSize(
15227db96d56Sopenharmony_ci                PyUnicode_DATA(pending), PyUnicode_GET_LENGTH(pending));
15237db96d56Sopenharmony_ci        if (b == NULL) {
15247db96d56Sopenharmony_ci            return -1;
15257db96d56Sopenharmony_ci        }
15267db96d56Sopenharmony_ci    }
15277db96d56Sopenharmony_ci    else {
15287db96d56Sopenharmony_ci        assert(PyList_Check(pending));
15297db96d56Sopenharmony_ci        b = PyBytes_FromStringAndSize(NULL, self->pending_bytes_count);
15307db96d56Sopenharmony_ci        if (b == NULL) {
15317db96d56Sopenharmony_ci            return -1;
15327db96d56Sopenharmony_ci        }
15337db96d56Sopenharmony_ci
15347db96d56Sopenharmony_ci        char *buf = PyBytes_AsString(b);
15357db96d56Sopenharmony_ci        Py_ssize_t pos = 0;
15367db96d56Sopenharmony_ci
15377db96d56Sopenharmony_ci        for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pending); i++) {
15387db96d56Sopenharmony_ci            PyObject *obj = PyList_GET_ITEM(pending, i);
15397db96d56Sopenharmony_ci            char *src;
15407db96d56Sopenharmony_ci            Py_ssize_t len;
15417db96d56Sopenharmony_ci            if (PyUnicode_Check(obj)) {
15427db96d56Sopenharmony_ci                assert(PyUnicode_IS_ASCII(obj));
15437db96d56Sopenharmony_ci                src = PyUnicode_DATA(obj);
15447db96d56Sopenharmony_ci                len = PyUnicode_GET_LENGTH(obj);
15457db96d56Sopenharmony_ci            }
15467db96d56Sopenharmony_ci            else {
15477db96d56Sopenharmony_ci                assert(PyBytes_Check(obj));
15487db96d56Sopenharmony_ci                if (PyBytes_AsStringAndSize(obj, &src, &len) < 0) {
15497db96d56Sopenharmony_ci                    Py_DECREF(b);
15507db96d56Sopenharmony_ci                    return -1;
15517db96d56Sopenharmony_ci                }
15527db96d56Sopenharmony_ci            }
15537db96d56Sopenharmony_ci            memcpy(buf + pos, src, len);
15547db96d56Sopenharmony_ci            pos += len;
15557db96d56Sopenharmony_ci        }
15567db96d56Sopenharmony_ci        assert(pos == self->pending_bytes_count);
15577db96d56Sopenharmony_ci    }
15587db96d56Sopenharmony_ci
15597db96d56Sopenharmony_ci    self->pending_bytes_count = 0;
15607db96d56Sopenharmony_ci    self->pending_bytes = NULL;
15617db96d56Sopenharmony_ci    Py_DECREF(pending);
15627db96d56Sopenharmony_ci
15637db96d56Sopenharmony_ci    PyObject *ret;
15647db96d56Sopenharmony_ci    do {
15657db96d56Sopenharmony_ci        ret = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(write), b);
15667db96d56Sopenharmony_ci    } while (ret == NULL && _PyIO_trap_eintr());
15677db96d56Sopenharmony_ci    Py_DECREF(b);
15687db96d56Sopenharmony_ci    // NOTE: We cleared buffer but we don't know how many bytes are actually written
15697db96d56Sopenharmony_ci    // when an error occurred.
15707db96d56Sopenharmony_ci    if (ret == NULL)
15717db96d56Sopenharmony_ci        return -1;
15727db96d56Sopenharmony_ci    Py_DECREF(ret);
15737db96d56Sopenharmony_ci    return 0;
15747db96d56Sopenharmony_ci}
15757db96d56Sopenharmony_ci
15767db96d56Sopenharmony_ci/*[clinic input]
15777db96d56Sopenharmony_ci_io.TextIOWrapper.write
15787db96d56Sopenharmony_ci    text: unicode
15797db96d56Sopenharmony_ci    /
15807db96d56Sopenharmony_ci[clinic start generated code]*/
15817db96d56Sopenharmony_ci
15827db96d56Sopenharmony_cistatic PyObject *
15837db96d56Sopenharmony_ci_io_TextIOWrapper_write_impl(textio *self, PyObject *text)
15847db96d56Sopenharmony_ci/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/
15857db96d56Sopenharmony_ci{
15867db96d56Sopenharmony_ci    PyObject *ret;
15877db96d56Sopenharmony_ci    PyObject *b;
15887db96d56Sopenharmony_ci    Py_ssize_t textlen;
15897db96d56Sopenharmony_ci    int haslf = 0;
15907db96d56Sopenharmony_ci    int needflush = 0, text_needflush = 0;
15917db96d56Sopenharmony_ci
15927db96d56Sopenharmony_ci    if (PyUnicode_READY(text) == -1)
15937db96d56Sopenharmony_ci        return NULL;
15947db96d56Sopenharmony_ci
15957db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
15967db96d56Sopenharmony_ci    CHECK_CLOSED(self);
15977db96d56Sopenharmony_ci
15987db96d56Sopenharmony_ci    if (self->encoder == NULL)
15997db96d56Sopenharmony_ci        return _unsupported("not writable");
16007db96d56Sopenharmony_ci
16017db96d56Sopenharmony_ci    Py_INCREF(text);
16027db96d56Sopenharmony_ci
16037db96d56Sopenharmony_ci    textlen = PyUnicode_GET_LENGTH(text);
16047db96d56Sopenharmony_ci
16057db96d56Sopenharmony_ci    if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
16067db96d56Sopenharmony_ci        if (PyUnicode_FindChar(text, '\n', 0, PyUnicode_GET_LENGTH(text), 1) != -1)
16077db96d56Sopenharmony_ci            haslf = 1;
16087db96d56Sopenharmony_ci
16097db96d56Sopenharmony_ci    if (haslf && self->writetranslate && self->writenl != NULL) {
16107db96d56Sopenharmony_ci        PyObject *newtext = _PyObject_CallMethod(text, &_Py_ID(replace),
16117db96d56Sopenharmony_ci                                                 "ss", "\n", self->writenl);
16127db96d56Sopenharmony_ci        Py_DECREF(text);
16137db96d56Sopenharmony_ci        if (newtext == NULL)
16147db96d56Sopenharmony_ci            return NULL;
16157db96d56Sopenharmony_ci        text = newtext;
16167db96d56Sopenharmony_ci    }
16177db96d56Sopenharmony_ci
16187db96d56Sopenharmony_ci    if (self->write_through)
16197db96d56Sopenharmony_ci        text_needflush = 1;
16207db96d56Sopenharmony_ci    if (self->line_buffering &&
16217db96d56Sopenharmony_ci        (haslf ||
16227db96d56Sopenharmony_ci         PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
16237db96d56Sopenharmony_ci        needflush = 1;
16247db96d56Sopenharmony_ci
16257db96d56Sopenharmony_ci    /* XXX What if we were just reading? */
16267db96d56Sopenharmony_ci    if (self->encodefunc != NULL) {
16277db96d56Sopenharmony_ci        if (PyUnicode_IS_ASCII(text) &&
16287db96d56Sopenharmony_ci                // See bpo-43260
16297db96d56Sopenharmony_ci                PyUnicode_GET_LENGTH(text) <= self->chunk_size &&
16307db96d56Sopenharmony_ci                is_asciicompat_encoding(self->encodefunc)) {
16317db96d56Sopenharmony_ci            b = text;
16327db96d56Sopenharmony_ci            Py_INCREF(b);
16337db96d56Sopenharmony_ci        }
16347db96d56Sopenharmony_ci        else {
16357db96d56Sopenharmony_ci            b = (*self->encodefunc)((PyObject *) self, text);
16367db96d56Sopenharmony_ci        }
16377db96d56Sopenharmony_ci        self->encoding_start_of_stream = 0;
16387db96d56Sopenharmony_ci    }
16397db96d56Sopenharmony_ci    else {
16407db96d56Sopenharmony_ci        b = PyObject_CallMethodOneArg(self->encoder, &_Py_ID(encode), text);
16417db96d56Sopenharmony_ci    }
16427db96d56Sopenharmony_ci
16437db96d56Sopenharmony_ci    Py_DECREF(text);
16447db96d56Sopenharmony_ci    if (b == NULL)
16457db96d56Sopenharmony_ci        return NULL;
16467db96d56Sopenharmony_ci    if (b != text && !PyBytes_Check(b)) {
16477db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
16487db96d56Sopenharmony_ci                     "encoder should return a bytes object, not '%.200s'",
16497db96d56Sopenharmony_ci                     Py_TYPE(b)->tp_name);
16507db96d56Sopenharmony_ci        Py_DECREF(b);
16517db96d56Sopenharmony_ci        return NULL;
16527db96d56Sopenharmony_ci    }
16537db96d56Sopenharmony_ci
16547db96d56Sopenharmony_ci    Py_ssize_t bytes_len;
16557db96d56Sopenharmony_ci    if (b == text) {
16567db96d56Sopenharmony_ci        bytes_len = PyUnicode_GET_LENGTH(b);
16577db96d56Sopenharmony_ci    }
16587db96d56Sopenharmony_ci    else {
16597db96d56Sopenharmony_ci        bytes_len = PyBytes_GET_SIZE(b);
16607db96d56Sopenharmony_ci    }
16617db96d56Sopenharmony_ci
16627db96d56Sopenharmony_ci    if (self->pending_bytes == NULL) {
16637db96d56Sopenharmony_ci        self->pending_bytes_count = 0;
16647db96d56Sopenharmony_ci        self->pending_bytes = b;
16657db96d56Sopenharmony_ci    }
16667db96d56Sopenharmony_ci    else if (self->pending_bytes_count + bytes_len > self->chunk_size) {
16677db96d56Sopenharmony_ci        // Prevent to concatenate more than chunk_size data.
16687db96d56Sopenharmony_ci        if (_textiowrapper_writeflush(self) < 0) {
16697db96d56Sopenharmony_ci            Py_DECREF(b);
16707db96d56Sopenharmony_ci            return NULL;
16717db96d56Sopenharmony_ci        }
16727db96d56Sopenharmony_ci        self->pending_bytes = b;
16737db96d56Sopenharmony_ci    }
16747db96d56Sopenharmony_ci    else if (!PyList_CheckExact(self->pending_bytes)) {
16757db96d56Sopenharmony_ci        PyObject *list = PyList_New(2);
16767db96d56Sopenharmony_ci        if (list == NULL) {
16777db96d56Sopenharmony_ci            Py_DECREF(b);
16787db96d56Sopenharmony_ci            return NULL;
16797db96d56Sopenharmony_ci        }
16807db96d56Sopenharmony_ci        PyList_SET_ITEM(list, 0, self->pending_bytes);
16817db96d56Sopenharmony_ci        PyList_SET_ITEM(list, 1, b);
16827db96d56Sopenharmony_ci        self->pending_bytes = list;
16837db96d56Sopenharmony_ci    }
16847db96d56Sopenharmony_ci    else {
16857db96d56Sopenharmony_ci        if (PyList_Append(self->pending_bytes, b) < 0) {
16867db96d56Sopenharmony_ci            Py_DECREF(b);
16877db96d56Sopenharmony_ci            return NULL;
16887db96d56Sopenharmony_ci        }
16897db96d56Sopenharmony_ci        Py_DECREF(b);
16907db96d56Sopenharmony_ci    }
16917db96d56Sopenharmony_ci
16927db96d56Sopenharmony_ci    self->pending_bytes_count += bytes_len;
16937db96d56Sopenharmony_ci    if (self->pending_bytes_count >= self->chunk_size || needflush ||
16947db96d56Sopenharmony_ci        text_needflush) {
16957db96d56Sopenharmony_ci        if (_textiowrapper_writeflush(self) < 0)
16967db96d56Sopenharmony_ci            return NULL;
16977db96d56Sopenharmony_ci    }
16987db96d56Sopenharmony_ci
16997db96d56Sopenharmony_ci    if (needflush) {
17007db96d56Sopenharmony_ci        ret = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(flush));
17017db96d56Sopenharmony_ci        if (ret == NULL)
17027db96d56Sopenharmony_ci            return NULL;
17037db96d56Sopenharmony_ci        Py_DECREF(ret);
17047db96d56Sopenharmony_ci    }
17057db96d56Sopenharmony_ci
17067db96d56Sopenharmony_ci    textiowrapper_set_decoded_chars(self, NULL);
17077db96d56Sopenharmony_ci    Py_CLEAR(self->snapshot);
17087db96d56Sopenharmony_ci
17097db96d56Sopenharmony_ci    if (self->decoder) {
17107db96d56Sopenharmony_ci        ret = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
17117db96d56Sopenharmony_ci        if (ret == NULL)
17127db96d56Sopenharmony_ci            return NULL;
17137db96d56Sopenharmony_ci        Py_DECREF(ret);
17147db96d56Sopenharmony_ci    }
17157db96d56Sopenharmony_ci
17167db96d56Sopenharmony_ci    return PyLong_FromSsize_t(textlen);
17177db96d56Sopenharmony_ci}
17187db96d56Sopenharmony_ci
17197db96d56Sopenharmony_ci/* Steal a reference to chars and store it in the decoded_char buffer;
17207db96d56Sopenharmony_ci */
17217db96d56Sopenharmony_cistatic void
17227db96d56Sopenharmony_citextiowrapper_set_decoded_chars(textio *self, PyObject *chars)
17237db96d56Sopenharmony_ci{
17247db96d56Sopenharmony_ci    Py_XSETREF(self->decoded_chars, chars);
17257db96d56Sopenharmony_ci    self->decoded_chars_used = 0;
17267db96d56Sopenharmony_ci}
17277db96d56Sopenharmony_ci
17287db96d56Sopenharmony_cistatic PyObject *
17297db96d56Sopenharmony_citextiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
17307db96d56Sopenharmony_ci{
17317db96d56Sopenharmony_ci    PyObject *chars;
17327db96d56Sopenharmony_ci    Py_ssize_t avail;
17337db96d56Sopenharmony_ci
17347db96d56Sopenharmony_ci    if (self->decoded_chars == NULL)
17357db96d56Sopenharmony_ci        return PyUnicode_FromStringAndSize(NULL, 0);
17367db96d56Sopenharmony_ci
17377db96d56Sopenharmony_ci    /* decoded_chars is guaranteed to be "ready". */
17387db96d56Sopenharmony_ci    avail = (PyUnicode_GET_LENGTH(self->decoded_chars)
17397db96d56Sopenharmony_ci             - self->decoded_chars_used);
17407db96d56Sopenharmony_ci
17417db96d56Sopenharmony_ci    assert(avail >= 0);
17427db96d56Sopenharmony_ci
17437db96d56Sopenharmony_ci    if (n < 0 || n > avail)
17447db96d56Sopenharmony_ci        n = avail;
17457db96d56Sopenharmony_ci
17467db96d56Sopenharmony_ci    if (self->decoded_chars_used > 0 || n < avail) {
17477db96d56Sopenharmony_ci        chars = PyUnicode_Substring(self->decoded_chars,
17487db96d56Sopenharmony_ci                                    self->decoded_chars_used,
17497db96d56Sopenharmony_ci                                    self->decoded_chars_used + n);
17507db96d56Sopenharmony_ci        if (chars == NULL)
17517db96d56Sopenharmony_ci            return NULL;
17527db96d56Sopenharmony_ci    }
17537db96d56Sopenharmony_ci    else {
17547db96d56Sopenharmony_ci        chars = self->decoded_chars;
17557db96d56Sopenharmony_ci        Py_INCREF(chars);
17567db96d56Sopenharmony_ci    }
17577db96d56Sopenharmony_ci
17587db96d56Sopenharmony_ci    self->decoded_chars_used += n;
17597db96d56Sopenharmony_ci    return chars;
17607db96d56Sopenharmony_ci}
17617db96d56Sopenharmony_ci
17627db96d56Sopenharmony_ci/* Read and decode the next chunk of data from the BufferedReader.
17637db96d56Sopenharmony_ci */
17647db96d56Sopenharmony_cistatic int
17657db96d56Sopenharmony_citextiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
17667db96d56Sopenharmony_ci{
17677db96d56Sopenharmony_ci    PyObject *dec_buffer = NULL;
17687db96d56Sopenharmony_ci    PyObject *dec_flags = NULL;
17697db96d56Sopenharmony_ci    PyObject *input_chunk = NULL;
17707db96d56Sopenharmony_ci    Py_buffer input_chunk_buf;
17717db96d56Sopenharmony_ci    PyObject *decoded_chars, *chunk_size;
17727db96d56Sopenharmony_ci    Py_ssize_t nbytes, nchars;
17737db96d56Sopenharmony_ci    int eof;
17747db96d56Sopenharmony_ci
17757db96d56Sopenharmony_ci    /* The return value is True unless EOF was reached.  The decoded string is
17767db96d56Sopenharmony_ci     * placed in self._decoded_chars (replacing its previous value).  The
17777db96d56Sopenharmony_ci     * entire input chunk is sent to the decoder, though some of it may remain
17787db96d56Sopenharmony_ci     * buffered in the decoder, yet to be converted.
17797db96d56Sopenharmony_ci     */
17807db96d56Sopenharmony_ci
17817db96d56Sopenharmony_ci    if (self->decoder == NULL) {
17827db96d56Sopenharmony_ci        _unsupported("not readable");
17837db96d56Sopenharmony_ci        return -1;
17847db96d56Sopenharmony_ci    }
17857db96d56Sopenharmony_ci
17867db96d56Sopenharmony_ci    if (self->telling) {
17877db96d56Sopenharmony_ci        /* To prepare for tell(), we need to snapshot a point in the file
17887db96d56Sopenharmony_ci         * where the decoder's input buffer is empty.
17897db96d56Sopenharmony_ci         */
17907db96d56Sopenharmony_ci        PyObject *state = PyObject_CallMethodNoArgs(self->decoder,
17917db96d56Sopenharmony_ci                                                     &_Py_ID(getstate));
17927db96d56Sopenharmony_ci        if (state == NULL)
17937db96d56Sopenharmony_ci            return -1;
17947db96d56Sopenharmony_ci        /* Given this, we know there was a valid snapshot point
17957db96d56Sopenharmony_ci         * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
17967db96d56Sopenharmony_ci         */
17977db96d56Sopenharmony_ci        if (!PyTuple_Check(state)) {
17987db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError,
17997db96d56Sopenharmony_ci                            "illegal decoder state");
18007db96d56Sopenharmony_ci            Py_DECREF(state);
18017db96d56Sopenharmony_ci            return -1;
18027db96d56Sopenharmony_ci        }
18037db96d56Sopenharmony_ci        if (!PyArg_ParseTuple(state,
18047db96d56Sopenharmony_ci                              "OO;illegal decoder state", &dec_buffer, &dec_flags))
18057db96d56Sopenharmony_ci        {
18067db96d56Sopenharmony_ci            Py_DECREF(state);
18077db96d56Sopenharmony_ci            return -1;
18087db96d56Sopenharmony_ci        }
18097db96d56Sopenharmony_ci
18107db96d56Sopenharmony_ci        if (!PyBytes_Check(dec_buffer)) {
18117db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
18127db96d56Sopenharmony_ci                         "illegal decoder state: the first item should be a "
18137db96d56Sopenharmony_ci                         "bytes object, not '%.200s'",
18147db96d56Sopenharmony_ci                         Py_TYPE(dec_buffer)->tp_name);
18157db96d56Sopenharmony_ci            Py_DECREF(state);
18167db96d56Sopenharmony_ci            return -1;
18177db96d56Sopenharmony_ci        }
18187db96d56Sopenharmony_ci        Py_INCREF(dec_buffer);
18197db96d56Sopenharmony_ci        Py_INCREF(dec_flags);
18207db96d56Sopenharmony_ci        Py_DECREF(state);
18217db96d56Sopenharmony_ci    }
18227db96d56Sopenharmony_ci
18237db96d56Sopenharmony_ci    /* Read a chunk, decode it, and put the result in self._decoded_chars. */
18247db96d56Sopenharmony_ci    if (size_hint > 0) {
18257db96d56Sopenharmony_ci        size_hint = (Py_ssize_t)(Py_MAX(self->b2cratio, 1.0) * size_hint);
18267db96d56Sopenharmony_ci    }
18277db96d56Sopenharmony_ci    chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint));
18287db96d56Sopenharmony_ci    if (chunk_size == NULL)
18297db96d56Sopenharmony_ci        goto fail;
18307db96d56Sopenharmony_ci
18317db96d56Sopenharmony_ci    input_chunk = PyObject_CallMethodOneArg(self->buffer,
18327db96d56Sopenharmony_ci        (self->has_read1 ? &_Py_ID(read1): &_Py_ID(read)),
18337db96d56Sopenharmony_ci        chunk_size);
18347db96d56Sopenharmony_ci    Py_DECREF(chunk_size);
18357db96d56Sopenharmony_ci    if (input_chunk == NULL)
18367db96d56Sopenharmony_ci        goto fail;
18377db96d56Sopenharmony_ci
18387db96d56Sopenharmony_ci    if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) {
18397db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
18407db96d56Sopenharmony_ci                     "underlying %s() should have returned a bytes-like object, "
18417db96d56Sopenharmony_ci                     "not '%.200s'", (self->has_read1 ? "read1": "read"),
18427db96d56Sopenharmony_ci                     Py_TYPE(input_chunk)->tp_name);
18437db96d56Sopenharmony_ci        goto fail;
18447db96d56Sopenharmony_ci    }
18457db96d56Sopenharmony_ci
18467db96d56Sopenharmony_ci    nbytes = input_chunk_buf.len;
18477db96d56Sopenharmony_ci    eof = (nbytes == 0);
18487db96d56Sopenharmony_ci
18497db96d56Sopenharmony_ci    decoded_chars = _textiowrapper_decode(self->decoder, input_chunk, eof);
18507db96d56Sopenharmony_ci    PyBuffer_Release(&input_chunk_buf);
18517db96d56Sopenharmony_ci    if (decoded_chars == NULL)
18527db96d56Sopenharmony_ci        goto fail;
18537db96d56Sopenharmony_ci
18547db96d56Sopenharmony_ci    textiowrapper_set_decoded_chars(self, decoded_chars);
18557db96d56Sopenharmony_ci    nchars = PyUnicode_GET_LENGTH(decoded_chars);
18567db96d56Sopenharmony_ci    if (nchars > 0)
18577db96d56Sopenharmony_ci        self->b2cratio = (double) nbytes / nchars;
18587db96d56Sopenharmony_ci    else
18597db96d56Sopenharmony_ci        self->b2cratio = 0.0;
18607db96d56Sopenharmony_ci    if (nchars > 0)
18617db96d56Sopenharmony_ci        eof = 0;
18627db96d56Sopenharmony_ci
18637db96d56Sopenharmony_ci    if (self->telling) {
18647db96d56Sopenharmony_ci        /* At the snapshot point, len(dec_buffer) bytes before the read, the
18657db96d56Sopenharmony_ci         * next input to be decoded is dec_buffer + input_chunk.
18667db96d56Sopenharmony_ci         */
18677db96d56Sopenharmony_ci        PyObject *next_input = dec_buffer;
18687db96d56Sopenharmony_ci        PyBytes_Concat(&next_input, input_chunk);
18697db96d56Sopenharmony_ci        dec_buffer = NULL; /* Reference lost to PyBytes_Concat */
18707db96d56Sopenharmony_ci        if (next_input == NULL) {
18717db96d56Sopenharmony_ci            goto fail;
18727db96d56Sopenharmony_ci        }
18737db96d56Sopenharmony_ci        PyObject *snapshot = Py_BuildValue("NN", dec_flags, next_input);
18747db96d56Sopenharmony_ci        if (snapshot == NULL) {
18757db96d56Sopenharmony_ci            dec_flags = NULL;
18767db96d56Sopenharmony_ci            goto fail;
18777db96d56Sopenharmony_ci        }
18787db96d56Sopenharmony_ci        Py_XSETREF(self->snapshot, snapshot);
18797db96d56Sopenharmony_ci    }
18807db96d56Sopenharmony_ci    Py_DECREF(input_chunk);
18817db96d56Sopenharmony_ci
18827db96d56Sopenharmony_ci    return (eof == 0);
18837db96d56Sopenharmony_ci
18847db96d56Sopenharmony_ci  fail:
18857db96d56Sopenharmony_ci    Py_XDECREF(dec_buffer);
18867db96d56Sopenharmony_ci    Py_XDECREF(dec_flags);
18877db96d56Sopenharmony_ci    Py_XDECREF(input_chunk);
18887db96d56Sopenharmony_ci    return -1;
18897db96d56Sopenharmony_ci}
18907db96d56Sopenharmony_ci
18917db96d56Sopenharmony_ci/*[clinic input]
18927db96d56Sopenharmony_ci_io.TextIOWrapper.read
18937db96d56Sopenharmony_ci    size as n: Py_ssize_t(accept={int, NoneType}) = -1
18947db96d56Sopenharmony_ci    /
18957db96d56Sopenharmony_ci[clinic start generated code]*/
18967db96d56Sopenharmony_ci
18977db96d56Sopenharmony_cistatic PyObject *
18987db96d56Sopenharmony_ci_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
18997db96d56Sopenharmony_ci/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/
19007db96d56Sopenharmony_ci{
19017db96d56Sopenharmony_ci    PyObject *result = NULL, *chunks = NULL;
19027db96d56Sopenharmony_ci
19037db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
19047db96d56Sopenharmony_ci    CHECK_CLOSED(self);
19057db96d56Sopenharmony_ci
19067db96d56Sopenharmony_ci    if (self->decoder == NULL)
19077db96d56Sopenharmony_ci        return _unsupported("not readable");
19087db96d56Sopenharmony_ci
19097db96d56Sopenharmony_ci    if (_textiowrapper_writeflush(self) < 0)
19107db96d56Sopenharmony_ci        return NULL;
19117db96d56Sopenharmony_ci
19127db96d56Sopenharmony_ci    if (n < 0) {
19137db96d56Sopenharmony_ci        /* Read everything */
19147db96d56Sopenharmony_ci        PyObject *bytes = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(read));
19157db96d56Sopenharmony_ci        PyObject *decoded;
19167db96d56Sopenharmony_ci        if (bytes == NULL)
19177db96d56Sopenharmony_ci            goto fail;
19187db96d56Sopenharmony_ci
19197db96d56Sopenharmony_ci        if (Py_IS_TYPE(self->decoder, &PyIncrementalNewlineDecoder_Type))
19207db96d56Sopenharmony_ci            decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
19217db96d56Sopenharmony_ci                                                          bytes, 1);
19227db96d56Sopenharmony_ci        else
19237db96d56Sopenharmony_ci            decoded = PyObject_CallMethodObjArgs(
19247db96d56Sopenharmony_ci                self->decoder, &_Py_ID(decode), bytes, Py_True, NULL);
19257db96d56Sopenharmony_ci        Py_DECREF(bytes);
19267db96d56Sopenharmony_ci        if (check_decoded(decoded) < 0)
19277db96d56Sopenharmony_ci            goto fail;
19287db96d56Sopenharmony_ci
19297db96d56Sopenharmony_ci        result = textiowrapper_get_decoded_chars(self, -1);
19307db96d56Sopenharmony_ci
19317db96d56Sopenharmony_ci        if (result == NULL) {
19327db96d56Sopenharmony_ci            Py_DECREF(decoded);
19337db96d56Sopenharmony_ci            return NULL;
19347db96d56Sopenharmony_ci        }
19357db96d56Sopenharmony_ci
19367db96d56Sopenharmony_ci        PyUnicode_AppendAndDel(&result, decoded);
19377db96d56Sopenharmony_ci        if (result == NULL)
19387db96d56Sopenharmony_ci            goto fail;
19397db96d56Sopenharmony_ci
19407db96d56Sopenharmony_ci        textiowrapper_set_decoded_chars(self, NULL);
19417db96d56Sopenharmony_ci        Py_CLEAR(self->snapshot);
19427db96d56Sopenharmony_ci        return result;
19437db96d56Sopenharmony_ci    }
19447db96d56Sopenharmony_ci    else {
19457db96d56Sopenharmony_ci        int res = 1;
19467db96d56Sopenharmony_ci        Py_ssize_t remaining = n;
19477db96d56Sopenharmony_ci
19487db96d56Sopenharmony_ci        result = textiowrapper_get_decoded_chars(self, n);
19497db96d56Sopenharmony_ci        if (result == NULL)
19507db96d56Sopenharmony_ci            goto fail;
19517db96d56Sopenharmony_ci        if (PyUnicode_READY(result) == -1)
19527db96d56Sopenharmony_ci            goto fail;
19537db96d56Sopenharmony_ci        remaining -= PyUnicode_GET_LENGTH(result);
19547db96d56Sopenharmony_ci
19557db96d56Sopenharmony_ci        /* Keep reading chunks until we have n characters to return */
19567db96d56Sopenharmony_ci        while (remaining > 0) {
19577db96d56Sopenharmony_ci            res = textiowrapper_read_chunk(self, remaining);
19587db96d56Sopenharmony_ci            if (res < 0) {
19597db96d56Sopenharmony_ci                /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
19607db96d56Sopenharmony_ci                   when EINTR occurs so we needn't do it ourselves. */
19617db96d56Sopenharmony_ci                if (_PyIO_trap_eintr()) {
19627db96d56Sopenharmony_ci                    continue;
19637db96d56Sopenharmony_ci                }
19647db96d56Sopenharmony_ci                goto fail;
19657db96d56Sopenharmony_ci            }
19667db96d56Sopenharmony_ci            if (res == 0)  /* EOF */
19677db96d56Sopenharmony_ci                break;
19687db96d56Sopenharmony_ci            if (chunks == NULL) {
19697db96d56Sopenharmony_ci                chunks = PyList_New(0);
19707db96d56Sopenharmony_ci                if (chunks == NULL)
19717db96d56Sopenharmony_ci                    goto fail;
19727db96d56Sopenharmony_ci            }
19737db96d56Sopenharmony_ci            if (PyUnicode_GET_LENGTH(result) > 0 &&
19747db96d56Sopenharmony_ci                PyList_Append(chunks, result) < 0)
19757db96d56Sopenharmony_ci                goto fail;
19767db96d56Sopenharmony_ci            Py_DECREF(result);
19777db96d56Sopenharmony_ci            result = textiowrapper_get_decoded_chars(self, remaining);
19787db96d56Sopenharmony_ci            if (result == NULL)
19797db96d56Sopenharmony_ci                goto fail;
19807db96d56Sopenharmony_ci            remaining -= PyUnicode_GET_LENGTH(result);
19817db96d56Sopenharmony_ci        }
19827db96d56Sopenharmony_ci        if (chunks != NULL) {
19837db96d56Sopenharmony_ci            if (result != NULL && PyList_Append(chunks, result) < 0)
19847db96d56Sopenharmony_ci                goto fail;
19857db96d56Sopenharmony_ci            _Py_DECLARE_STR(empty, "");
19867db96d56Sopenharmony_ci            Py_XSETREF(result, PyUnicode_Join(&_Py_STR(empty), chunks));
19877db96d56Sopenharmony_ci            if (result == NULL)
19887db96d56Sopenharmony_ci                goto fail;
19897db96d56Sopenharmony_ci            Py_CLEAR(chunks);
19907db96d56Sopenharmony_ci        }
19917db96d56Sopenharmony_ci        return result;
19927db96d56Sopenharmony_ci    }
19937db96d56Sopenharmony_ci  fail:
19947db96d56Sopenharmony_ci    Py_XDECREF(result);
19957db96d56Sopenharmony_ci    Py_XDECREF(chunks);
19967db96d56Sopenharmony_ci    return NULL;
19977db96d56Sopenharmony_ci}
19987db96d56Sopenharmony_ci
19997db96d56Sopenharmony_ci
20007db96d56Sopenharmony_ci/* NOTE: `end` must point to the real end of the Py_UCS4 storage,
20017db96d56Sopenharmony_ci   that is to the NUL character. Otherwise the function will produce
20027db96d56Sopenharmony_ci   incorrect results. */
20037db96d56Sopenharmony_cistatic const char *
20047db96d56Sopenharmony_cifind_control_char(int kind, const char *s, const char *end, Py_UCS4 ch)
20057db96d56Sopenharmony_ci{
20067db96d56Sopenharmony_ci    if (kind == PyUnicode_1BYTE_KIND) {
20077db96d56Sopenharmony_ci        assert(ch < 256);
20087db96d56Sopenharmony_ci        return (char *) memchr((const void *) s, (char) ch, end - s);
20097db96d56Sopenharmony_ci    }
20107db96d56Sopenharmony_ci    for (;;) {
20117db96d56Sopenharmony_ci        while (PyUnicode_READ(kind, s, 0) > ch)
20127db96d56Sopenharmony_ci            s += kind;
20137db96d56Sopenharmony_ci        if (PyUnicode_READ(kind, s, 0) == ch)
20147db96d56Sopenharmony_ci            return s;
20157db96d56Sopenharmony_ci        if (s == end)
20167db96d56Sopenharmony_ci            return NULL;
20177db96d56Sopenharmony_ci        s += kind;
20187db96d56Sopenharmony_ci    }
20197db96d56Sopenharmony_ci}
20207db96d56Sopenharmony_ci
20217db96d56Sopenharmony_ciPy_ssize_t
20227db96d56Sopenharmony_ci_PyIO_find_line_ending(
20237db96d56Sopenharmony_ci    int translated, int universal, PyObject *readnl,
20247db96d56Sopenharmony_ci    int kind, const char *start, const char *end, Py_ssize_t *consumed)
20257db96d56Sopenharmony_ci{
20267db96d56Sopenharmony_ci    Py_ssize_t len = (end - start)/kind;
20277db96d56Sopenharmony_ci
20287db96d56Sopenharmony_ci    if (translated) {
20297db96d56Sopenharmony_ci        /* Newlines are already translated, only search for \n */
20307db96d56Sopenharmony_ci        const char *pos = find_control_char(kind, start, end, '\n');
20317db96d56Sopenharmony_ci        if (pos != NULL)
20327db96d56Sopenharmony_ci            return (pos - start)/kind + 1;
20337db96d56Sopenharmony_ci        else {
20347db96d56Sopenharmony_ci            *consumed = len;
20357db96d56Sopenharmony_ci            return -1;
20367db96d56Sopenharmony_ci        }
20377db96d56Sopenharmony_ci    }
20387db96d56Sopenharmony_ci    else if (universal) {
20397db96d56Sopenharmony_ci        /* Universal newline search. Find any of \r, \r\n, \n
20407db96d56Sopenharmony_ci         * The decoder ensures that \r\n are not split in two pieces
20417db96d56Sopenharmony_ci         */
20427db96d56Sopenharmony_ci        const char *s = start;
20437db96d56Sopenharmony_ci        for (;;) {
20447db96d56Sopenharmony_ci            Py_UCS4 ch;
20457db96d56Sopenharmony_ci            /* Fast path for non-control chars. The loop always ends
20467db96d56Sopenharmony_ci               since the Unicode string is NUL-terminated. */
20477db96d56Sopenharmony_ci            while (PyUnicode_READ(kind, s, 0) > '\r')
20487db96d56Sopenharmony_ci                s += kind;
20497db96d56Sopenharmony_ci            if (s >= end) {
20507db96d56Sopenharmony_ci                *consumed = len;
20517db96d56Sopenharmony_ci                return -1;
20527db96d56Sopenharmony_ci            }
20537db96d56Sopenharmony_ci            ch = PyUnicode_READ(kind, s, 0);
20547db96d56Sopenharmony_ci            s += kind;
20557db96d56Sopenharmony_ci            if (ch == '\n')
20567db96d56Sopenharmony_ci                return (s - start)/kind;
20577db96d56Sopenharmony_ci            if (ch == '\r') {
20587db96d56Sopenharmony_ci                if (PyUnicode_READ(kind, s, 0) == '\n')
20597db96d56Sopenharmony_ci                    return (s - start)/kind + 1;
20607db96d56Sopenharmony_ci                else
20617db96d56Sopenharmony_ci                    return (s - start)/kind;
20627db96d56Sopenharmony_ci            }
20637db96d56Sopenharmony_ci        }
20647db96d56Sopenharmony_ci    }
20657db96d56Sopenharmony_ci    else {
20667db96d56Sopenharmony_ci        /* Non-universal mode. */
20677db96d56Sopenharmony_ci        Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl);
20687db96d56Sopenharmony_ci        const Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl);
20697db96d56Sopenharmony_ci        /* Assume that readnl is an ASCII character. */
20707db96d56Sopenharmony_ci        assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND);
20717db96d56Sopenharmony_ci        if (readnl_len == 1) {
20727db96d56Sopenharmony_ci            const char *pos = find_control_char(kind, start, end, nl[0]);
20737db96d56Sopenharmony_ci            if (pos != NULL)
20747db96d56Sopenharmony_ci                return (pos - start)/kind + 1;
20757db96d56Sopenharmony_ci            *consumed = len;
20767db96d56Sopenharmony_ci            return -1;
20777db96d56Sopenharmony_ci        }
20787db96d56Sopenharmony_ci        else {
20797db96d56Sopenharmony_ci            const char *s = start;
20807db96d56Sopenharmony_ci            const char *e = end - (readnl_len - 1)*kind;
20817db96d56Sopenharmony_ci            const char *pos;
20827db96d56Sopenharmony_ci            if (e < s)
20837db96d56Sopenharmony_ci                e = s;
20847db96d56Sopenharmony_ci            while (s < e) {
20857db96d56Sopenharmony_ci                Py_ssize_t i;
20867db96d56Sopenharmony_ci                const char *pos = find_control_char(kind, s, end, nl[0]);
20877db96d56Sopenharmony_ci                if (pos == NULL || pos >= e)
20887db96d56Sopenharmony_ci                    break;
20897db96d56Sopenharmony_ci                for (i = 1; i < readnl_len; i++) {
20907db96d56Sopenharmony_ci                    if (PyUnicode_READ(kind, pos, i) != nl[i])
20917db96d56Sopenharmony_ci                        break;
20927db96d56Sopenharmony_ci                }
20937db96d56Sopenharmony_ci                if (i == readnl_len)
20947db96d56Sopenharmony_ci                    return (pos - start)/kind + readnl_len;
20957db96d56Sopenharmony_ci                s = pos + kind;
20967db96d56Sopenharmony_ci            }
20977db96d56Sopenharmony_ci            pos = find_control_char(kind, e, end, nl[0]);
20987db96d56Sopenharmony_ci            if (pos == NULL)
20997db96d56Sopenharmony_ci                *consumed = len;
21007db96d56Sopenharmony_ci            else
21017db96d56Sopenharmony_ci                *consumed = (pos - start)/kind;
21027db96d56Sopenharmony_ci            return -1;
21037db96d56Sopenharmony_ci        }
21047db96d56Sopenharmony_ci    }
21057db96d56Sopenharmony_ci}
21067db96d56Sopenharmony_ci
21077db96d56Sopenharmony_cistatic PyObject *
21087db96d56Sopenharmony_ci_textiowrapper_readline(textio *self, Py_ssize_t limit)
21097db96d56Sopenharmony_ci{
21107db96d56Sopenharmony_ci    PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
21117db96d56Sopenharmony_ci    Py_ssize_t start, endpos, chunked, offset_to_buffer;
21127db96d56Sopenharmony_ci    int res;
21137db96d56Sopenharmony_ci
21147db96d56Sopenharmony_ci    CHECK_CLOSED(self);
21157db96d56Sopenharmony_ci
21167db96d56Sopenharmony_ci    if (_textiowrapper_writeflush(self) < 0)
21177db96d56Sopenharmony_ci        return NULL;
21187db96d56Sopenharmony_ci
21197db96d56Sopenharmony_ci    chunked = 0;
21207db96d56Sopenharmony_ci
21217db96d56Sopenharmony_ci    while (1) {
21227db96d56Sopenharmony_ci        const char *ptr;
21237db96d56Sopenharmony_ci        Py_ssize_t line_len;
21247db96d56Sopenharmony_ci        int kind;
21257db96d56Sopenharmony_ci        Py_ssize_t consumed = 0;
21267db96d56Sopenharmony_ci
21277db96d56Sopenharmony_ci        /* First, get some data if necessary */
21287db96d56Sopenharmony_ci        res = 1;
21297db96d56Sopenharmony_ci        while (!self->decoded_chars ||
21307db96d56Sopenharmony_ci               !PyUnicode_GET_LENGTH(self->decoded_chars)) {
21317db96d56Sopenharmony_ci            res = textiowrapper_read_chunk(self, 0);
21327db96d56Sopenharmony_ci            if (res < 0) {
21337db96d56Sopenharmony_ci                /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
21347db96d56Sopenharmony_ci                   when EINTR occurs so we needn't do it ourselves. */
21357db96d56Sopenharmony_ci                if (_PyIO_trap_eintr()) {
21367db96d56Sopenharmony_ci                    continue;
21377db96d56Sopenharmony_ci                }
21387db96d56Sopenharmony_ci                goto error;
21397db96d56Sopenharmony_ci            }
21407db96d56Sopenharmony_ci            if (res == 0)
21417db96d56Sopenharmony_ci                break;
21427db96d56Sopenharmony_ci        }
21437db96d56Sopenharmony_ci        if (res == 0) {
21447db96d56Sopenharmony_ci            /* end of file */
21457db96d56Sopenharmony_ci            textiowrapper_set_decoded_chars(self, NULL);
21467db96d56Sopenharmony_ci            Py_CLEAR(self->snapshot);
21477db96d56Sopenharmony_ci            start = endpos = offset_to_buffer = 0;
21487db96d56Sopenharmony_ci            break;
21497db96d56Sopenharmony_ci        }
21507db96d56Sopenharmony_ci
21517db96d56Sopenharmony_ci        if (remaining == NULL) {
21527db96d56Sopenharmony_ci            line = self->decoded_chars;
21537db96d56Sopenharmony_ci            start = self->decoded_chars_used;
21547db96d56Sopenharmony_ci            offset_to_buffer = 0;
21557db96d56Sopenharmony_ci            Py_INCREF(line);
21567db96d56Sopenharmony_ci        }
21577db96d56Sopenharmony_ci        else {
21587db96d56Sopenharmony_ci            assert(self->decoded_chars_used == 0);
21597db96d56Sopenharmony_ci            line = PyUnicode_Concat(remaining, self->decoded_chars);
21607db96d56Sopenharmony_ci            start = 0;
21617db96d56Sopenharmony_ci            offset_to_buffer = PyUnicode_GET_LENGTH(remaining);
21627db96d56Sopenharmony_ci            Py_CLEAR(remaining);
21637db96d56Sopenharmony_ci            if (line == NULL)
21647db96d56Sopenharmony_ci                goto error;
21657db96d56Sopenharmony_ci            if (PyUnicode_READY(line) == -1)
21667db96d56Sopenharmony_ci                goto error;
21677db96d56Sopenharmony_ci        }
21687db96d56Sopenharmony_ci
21697db96d56Sopenharmony_ci        ptr = PyUnicode_DATA(line);
21707db96d56Sopenharmony_ci        line_len = PyUnicode_GET_LENGTH(line);
21717db96d56Sopenharmony_ci        kind = PyUnicode_KIND(line);
21727db96d56Sopenharmony_ci
21737db96d56Sopenharmony_ci        endpos = _PyIO_find_line_ending(
21747db96d56Sopenharmony_ci            self->readtranslate, self->readuniversal, self->readnl,
21757db96d56Sopenharmony_ci            kind,
21767db96d56Sopenharmony_ci            ptr + kind * start,
21777db96d56Sopenharmony_ci            ptr + kind * line_len,
21787db96d56Sopenharmony_ci            &consumed);
21797db96d56Sopenharmony_ci        if (endpos >= 0) {
21807db96d56Sopenharmony_ci            endpos += start;
21817db96d56Sopenharmony_ci            if (limit >= 0 && (endpos - start) + chunked >= limit)
21827db96d56Sopenharmony_ci                endpos = start + limit - chunked;
21837db96d56Sopenharmony_ci            break;
21847db96d56Sopenharmony_ci        }
21857db96d56Sopenharmony_ci
21867db96d56Sopenharmony_ci        /* We can put aside up to `endpos` */
21877db96d56Sopenharmony_ci        endpos = consumed + start;
21887db96d56Sopenharmony_ci        if (limit >= 0 && (endpos - start) + chunked >= limit) {
21897db96d56Sopenharmony_ci            /* Didn't find line ending, but reached length limit */
21907db96d56Sopenharmony_ci            endpos = start + limit - chunked;
21917db96d56Sopenharmony_ci            break;
21927db96d56Sopenharmony_ci        }
21937db96d56Sopenharmony_ci
21947db96d56Sopenharmony_ci        if (endpos > start) {
21957db96d56Sopenharmony_ci            /* No line ending seen yet - put aside current data */
21967db96d56Sopenharmony_ci            PyObject *s;
21977db96d56Sopenharmony_ci            if (chunks == NULL) {
21987db96d56Sopenharmony_ci                chunks = PyList_New(0);
21997db96d56Sopenharmony_ci                if (chunks == NULL)
22007db96d56Sopenharmony_ci                    goto error;
22017db96d56Sopenharmony_ci            }
22027db96d56Sopenharmony_ci            s = PyUnicode_Substring(line, start, endpos);
22037db96d56Sopenharmony_ci            if (s == NULL)
22047db96d56Sopenharmony_ci                goto error;
22057db96d56Sopenharmony_ci            if (PyList_Append(chunks, s) < 0) {
22067db96d56Sopenharmony_ci                Py_DECREF(s);
22077db96d56Sopenharmony_ci                goto error;
22087db96d56Sopenharmony_ci            }
22097db96d56Sopenharmony_ci            chunked += PyUnicode_GET_LENGTH(s);
22107db96d56Sopenharmony_ci            Py_DECREF(s);
22117db96d56Sopenharmony_ci        }
22127db96d56Sopenharmony_ci        /* There may be some remaining bytes we'll have to prepend to the
22137db96d56Sopenharmony_ci           next chunk of data */
22147db96d56Sopenharmony_ci        if (endpos < line_len) {
22157db96d56Sopenharmony_ci            remaining = PyUnicode_Substring(line, endpos, line_len);
22167db96d56Sopenharmony_ci            if (remaining == NULL)
22177db96d56Sopenharmony_ci                goto error;
22187db96d56Sopenharmony_ci        }
22197db96d56Sopenharmony_ci        Py_CLEAR(line);
22207db96d56Sopenharmony_ci        /* We have consumed the buffer */
22217db96d56Sopenharmony_ci        textiowrapper_set_decoded_chars(self, NULL);
22227db96d56Sopenharmony_ci    }
22237db96d56Sopenharmony_ci
22247db96d56Sopenharmony_ci    if (line != NULL) {
22257db96d56Sopenharmony_ci        /* Our line ends in the current buffer */
22267db96d56Sopenharmony_ci        self->decoded_chars_used = endpos - offset_to_buffer;
22277db96d56Sopenharmony_ci        if (start > 0 || endpos < PyUnicode_GET_LENGTH(line)) {
22287db96d56Sopenharmony_ci            PyObject *s = PyUnicode_Substring(line, start, endpos);
22297db96d56Sopenharmony_ci            Py_CLEAR(line);
22307db96d56Sopenharmony_ci            if (s == NULL)
22317db96d56Sopenharmony_ci                goto error;
22327db96d56Sopenharmony_ci            line = s;
22337db96d56Sopenharmony_ci        }
22347db96d56Sopenharmony_ci    }
22357db96d56Sopenharmony_ci    if (remaining != NULL) {
22367db96d56Sopenharmony_ci        if (chunks == NULL) {
22377db96d56Sopenharmony_ci            chunks = PyList_New(0);
22387db96d56Sopenharmony_ci            if (chunks == NULL)
22397db96d56Sopenharmony_ci                goto error;
22407db96d56Sopenharmony_ci        }
22417db96d56Sopenharmony_ci        if (PyList_Append(chunks, remaining) < 0)
22427db96d56Sopenharmony_ci            goto error;
22437db96d56Sopenharmony_ci        Py_CLEAR(remaining);
22447db96d56Sopenharmony_ci    }
22457db96d56Sopenharmony_ci    if (chunks != NULL) {
22467db96d56Sopenharmony_ci        if (line != NULL) {
22477db96d56Sopenharmony_ci            if (PyList_Append(chunks, line) < 0)
22487db96d56Sopenharmony_ci                goto error;
22497db96d56Sopenharmony_ci            Py_DECREF(line);
22507db96d56Sopenharmony_ci        }
22517db96d56Sopenharmony_ci        line = PyUnicode_Join(&_Py_STR(empty), chunks);
22527db96d56Sopenharmony_ci        if (line == NULL)
22537db96d56Sopenharmony_ci            goto error;
22547db96d56Sopenharmony_ci        Py_CLEAR(chunks);
22557db96d56Sopenharmony_ci    }
22567db96d56Sopenharmony_ci    if (line == NULL) {
22577db96d56Sopenharmony_ci        line = Py_NewRef(&_Py_STR(empty));
22587db96d56Sopenharmony_ci    }
22597db96d56Sopenharmony_ci
22607db96d56Sopenharmony_ci    return line;
22617db96d56Sopenharmony_ci
22627db96d56Sopenharmony_ci  error:
22637db96d56Sopenharmony_ci    Py_XDECREF(chunks);
22647db96d56Sopenharmony_ci    Py_XDECREF(remaining);
22657db96d56Sopenharmony_ci    Py_XDECREF(line);
22667db96d56Sopenharmony_ci    return NULL;
22677db96d56Sopenharmony_ci}
22687db96d56Sopenharmony_ci
22697db96d56Sopenharmony_ci/*[clinic input]
22707db96d56Sopenharmony_ci_io.TextIOWrapper.readline
22717db96d56Sopenharmony_ci    size: Py_ssize_t = -1
22727db96d56Sopenharmony_ci    /
22737db96d56Sopenharmony_ci[clinic start generated code]*/
22747db96d56Sopenharmony_ci
22757db96d56Sopenharmony_cistatic PyObject *
22767db96d56Sopenharmony_ci_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size)
22777db96d56Sopenharmony_ci/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/
22787db96d56Sopenharmony_ci{
22797db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
22807db96d56Sopenharmony_ci    return _textiowrapper_readline(self, size);
22817db96d56Sopenharmony_ci}
22827db96d56Sopenharmony_ci
22837db96d56Sopenharmony_ci/* Seek and Tell */
22847db96d56Sopenharmony_ci
22857db96d56Sopenharmony_citypedef struct {
22867db96d56Sopenharmony_ci    Py_off_t start_pos;
22877db96d56Sopenharmony_ci    int dec_flags;
22887db96d56Sopenharmony_ci    int bytes_to_feed;
22897db96d56Sopenharmony_ci    int chars_to_skip;
22907db96d56Sopenharmony_ci    char need_eof;
22917db96d56Sopenharmony_ci} cookie_type;
22927db96d56Sopenharmony_ci
22937db96d56Sopenharmony_ci/*
22947db96d56Sopenharmony_ci   To speed up cookie packing/unpacking, we store the fields in a temporary
22957db96d56Sopenharmony_ci   string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
22967db96d56Sopenharmony_ci   The following macros define at which offsets in the intermediary byte
22977db96d56Sopenharmony_ci   string the various CookieStruct fields will be stored.
22987db96d56Sopenharmony_ci */
22997db96d56Sopenharmony_ci
23007db96d56Sopenharmony_ci#define COOKIE_BUF_LEN      (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
23017db96d56Sopenharmony_ci
23027db96d56Sopenharmony_ci#if PY_BIG_ENDIAN
23037db96d56Sopenharmony_ci/* We want the least significant byte of start_pos to also be the least
23047db96d56Sopenharmony_ci   significant byte of the cookie, which means that in big-endian mode we
23057db96d56Sopenharmony_ci   must copy the fields in reverse order. */
23067db96d56Sopenharmony_ci
23077db96d56Sopenharmony_ci# define OFF_START_POS      (sizeof(char) + 3 * sizeof(int))
23087db96d56Sopenharmony_ci# define OFF_DEC_FLAGS      (sizeof(char) + 2 * sizeof(int))
23097db96d56Sopenharmony_ci# define OFF_BYTES_TO_FEED  (sizeof(char) + sizeof(int))
23107db96d56Sopenharmony_ci# define OFF_CHARS_TO_SKIP  (sizeof(char))
23117db96d56Sopenharmony_ci# define OFF_NEED_EOF       0
23127db96d56Sopenharmony_ci
23137db96d56Sopenharmony_ci#else
23147db96d56Sopenharmony_ci/* Little-endian mode: the least significant byte of start_pos will
23157db96d56Sopenharmony_ci   naturally end up the least significant byte of the cookie. */
23167db96d56Sopenharmony_ci
23177db96d56Sopenharmony_ci# define OFF_START_POS      0
23187db96d56Sopenharmony_ci# define OFF_DEC_FLAGS      (sizeof(Py_off_t))
23197db96d56Sopenharmony_ci# define OFF_BYTES_TO_FEED  (sizeof(Py_off_t) + sizeof(int))
23207db96d56Sopenharmony_ci# define OFF_CHARS_TO_SKIP  (sizeof(Py_off_t) + 2 * sizeof(int))
23217db96d56Sopenharmony_ci# define OFF_NEED_EOF       (sizeof(Py_off_t) + 3 * sizeof(int))
23227db96d56Sopenharmony_ci
23237db96d56Sopenharmony_ci#endif
23247db96d56Sopenharmony_ci
23257db96d56Sopenharmony_cistatic int
23267db96d56Sopenharmony_citextiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
23277db96d56Sopenharmony_ci{
23287db96d56Sopenharmony_ci    unsigned char buffer[COOKIE_BUF_LEN];
23297db96d56Sopenharmony_ci    PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
23307db96d56Sopenharmony_ci    if (cookieLong == NULL)
23317db96d56Sopenharmony_ci        return -1;
23327db96d56Sopenharmony_ci
23337db96d56Sopenharmony_ci    if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
23347db96d56Sopenharmony_ci                            PY_LITTLE_ENDIAN, 0) < 0) {
23357db96d56Sopenharmony_ci        Py_DECREF(cookieLong);
23367db96d56Sopenharmony_ci        return -1;
23377db96d56Sopenharmony_ci    }
23387db96d56Sopenharmony_ci    Py_DECREF(cookieLong);
23397db96d56Sopenharmony_ci
23407db96d56Sopenharmony_ci    memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
23417db96d56Sopenharmony_ci    memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
23427db96d56Sopenharmony_ci    memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
23437db96d56Sopenharmony_ci    memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
23447db96d56Sopenharmony_ci    memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
23457db96d56Sopenharmony_ci
23467db96d56Sopenharmony_ci    return 0;
23477db96d56Sopenharmony_ci}
23487db96d56Sopenharmony_ci
23497db96d56Sopenharmony_cistatic PyObject *
23507db96d56Sopenharmony_citextiowrapper_build_cookie(cookie_type *cookie)
23517db96d56Sopenharmony_ci{
23527db96d56Sopenharmony_ci    unsigned char buffer[COOKIE_BUF_LEN];
23537db96d56Sopenharmony_ci
23547db96d56Sopenharmony_ci    memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
23557db96d56Sopenharmony_ci    memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
23567db96d56Sopenharmony_ci    memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
23577db96d56Sopenharmony_ci    memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
23587db96d56Sopenharmony_ci    memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
23597db96d56Sopenharmony_ci
23607db96d56Sopenharmony_ci    return _PyLong_FromByteArray(buffer, sizeof(buffer),
23617db96d56Sopenharmony_ci                                 PY_LITTLE_ENDIAN, 0);
23627db96d56Sopenharmony_ci}
23637db96d56Sopenharmony_ci
23647db96d56Sopenharmony_cistatic int
23657db96d56Sopenharmony_ci_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
23667db96d56Sopenharmony_ci{
23677db96d56Sopenharmony_ci    PyObject *res;
23687db96d56Sopenharmony_ci    /* When seeking to the start of the stream, we call decoder.reset()
23697db96d56Sopenharmony_ci       rather than decoder.getstate().
23707db96d56Sopenharmony_ci       This is for a few decoders such as utf-16 for which the state value
23717db96d56Sopenharmony_ci       at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
23727db96d56Sopenharmony_ci       utf-16, that we are expecting a BOM).
23737db96d56Sopenharmony_ci    */
23747db96d56Sopenharmony_ci    if (cookie->start_pos == 0 && cookie->dec_flags == 0) {
23757db96d56Sopenharmony_ci        res = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
23767db96d56Sopenharmony_ci    }
23777db96d56Sopenharmony_ci    else {
23787db96d56Sopenharmony_ci        res = _PyObject_CallMethod(self->decoder, &_Py_ID(setstate),
23797db96d56Sopenharmony_ci                                   "((yi))", "", cookie->dec_flags);
23807db96d56Sopenharmony_ci    }
23817db96d56Sopenharmony_ci    if (res == NULL) {
23827db96d56Sopenharmony_ci        return -1;
23837db96d56Sopenharmony_ci    }
23847db96d56Sopenharmony_ci    Py_DECREF(res);
23857db96d56Sopenharmony_ci    return 0;
23867db96d56Sopenharmony_ci}
23877db96d56Sopenharmony_ci
23887db96d56Sopenharmony_cistatic int
23897db96d56Sopenharmony_ci_textiowrapper_encoder_reset(textio *self, int start_of_stream)
23907db96d56Sopenharmony_ci{
23917db96d56Sopenharmony_ci    PyObject *res;
23927db96d56Sopenharmony_ci    if (start_of_stream) {
23937db96d56Sopenharmony_ci        res = PyObject_CallMethodNoArgs(self->encoder, &_Py_ID(reset));
23947db96d56Sopenharmony_ci        self->encoding_start_of_stream = 1;
23957db96d56Sopenharmony_ci    }
23967db96d56Sopenharmony_ci    else {
23977db96d56Sopenharmony_ci        res = PyObject_CallMethodOneArg(self->encoder, &_Py_ID(setstate),
23987db96d56Sopenharmony_ci                                        _PyLong_GetZero());
23997db96d56Sopenharmony_ci        self->encoding_start_of_stream = 0;
24007db96d56Sopenharmony_ci    }
24017db96d56Sopenharmony_ci    if (res == NULL)
24027db96d56Sopenharmony_ci        return -1;
24037db96d56Sopenharmony_ci    Py_DECREF(res);
24047db96d56Sopenharmony_ci    return 0;
24057db96d56Sopenharmony_ci}
24067db96d56Sopenharmony_ci
24077db96d56Sopenharmony_cistatic int
24087db96d56Sopenharmony_ci_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
24097db96d56Sopenharmony_ci{
24107db96d56Sopenharmony_ci    /* Same as _textiowrapper_decoder_setstate() above. */
24117db96d56Sopenharmony_ci    return _textiowrapper_encoder_reset(
24127db96d56Sopenharmony_ci        self, cookie->start_pos == 0 && cookie->dec_flags == 0);
24137db96d56Sopenharmony_ci}
24147db96d56Sopenharmony_ci
24157db96d56Sopenharmony_ci/*[clinic input]
24167db96d56Sopenharmony_ci_io.TextIOWrapper.seek
24177db96d56Sopenharmony_ci    cookie as cookieObj: object
24187db96d56Sopenharmony_ci    whence: int = 0
24197db96d56Sopenharmony_ci    /
24207db96d56Sopenharmony_ci[clinic start generated code]*/
24217db96d56Sopenharmony_ci
24227db96d56Sopenharmony_cistatic PyObject *
24237db96d56Sopenharmony_ci_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence)
24247db96d56Sopenharmony_ci/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/
24257db96d56Sopenharmony_ci{
24267db96d56Sopenharmony_ci    PyObject *posobj;
24277db96d56Sopenharmony_ci    cookie_type cookie;
24287db96d56Sopenharmony_ci    PyObject *res;
24297db96d56Sopenharmony_ci    int cmp;
24307db96d56Sopenharmony_ci    PyObject *snapshot;
24317db96d56Sopenharmony_ci
24327db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
24337db96d56Sopenharmony_ci    CHECK_CLOSED(self);
24347db96d56Sopenharmony_ci
24357db96d56Sopenharmony_ci    Py_INCREF(cookieObj);
24367db96d56Sopenharmony_ci
24377db96d56Sopenharmony_ci    if (!self->seekable) {
24387db96d56Sopenharmony_ci        _unsupported("underlying stream is not seekable");
24397db96d56Sopenharmony_ci        goto fail;
24407db96d56Sopenharmony_ci    }
24417db96d56Sopenharmony_ci
24427db96d56Sopenharmony_ci    PyObject *zero = _PyLong_GetZero();  // borrowed reference
24437db96d56Sopenharmony_ci
24447db96d56Sopenharmony_ci    switch (whence) {
24457db96d56Sopenharmony_ci    case SEEK_CUR:
24467db96d56Sopenharmony_ci        /* seek relative to current position */
24477db96d56Sopenharmony_ci        cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ);
24487db96d56Sopenharmony_ci        if (cmp < 0)
24497db96d56Sopenharmony_ci            goto fail;
24507db96d56Sopenharmony_ci
24517db96d56Sopenharmony_ci        if (cmp == 0) {
24527db96d56Sopenharmony_ci            _unsupported("can't do nonzero cur-relative seeks");
24537db96d56Sopenharmony_ci            goto fail;
24547db96d56Sopenharmony_ci        }
24557db96d56Sopenharmony_ci
24567db96d56Sopenharmony_ci        /* Seeking to the current position should attempt to
24577db96d56Sopenharmony_ci         * sync the underlying buffer with the current position.
24587db96d56Sopenharmony_ci         */
24597db96d56Sopenharmony_ci        Py_DECREF(cookieObj);
24607db96d56Sopenharmony_ci        cookieObj = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(tell));
24617db96d56Sopenharmony_ci        if (cookieObj == NULL)
24627db96d56Sopenharmony_ci            goto fail;
24637db96d56Sopenharmony_ci        break;
24647db96d56Sopenharmony_ci
24657db96d56Sopenharmony_ci    case SEEK_END:
24667db96d56Sopenharmony_ci        /* seek relative to end of file */
24677db96d56Sopenharmony_ci        cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ);
24687db96d56Sopenharmony_ci        if (cmp < 0)
24697db96d56Sopenharmony_ci            goto fail;
24707db96d56Sopenharmony_ci
24717db96d56Sopenharmony_ci        if (cmp == 0) {
24727db96d56Sopenharmony_ci            _unsupported("can't do nonzero end-relative seeks");
24737db96d56Sopenharmony_ci            goto fail;
24747db96d56Sopenharmony_ci        }
24757db96d56Sopenharmony_ci
24767db96d56Sopenharmony_ci        res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
24777db96d56Sopenharmony_ci        if (res == NULL)
24787db96d56Sopenharmony_ci            goto fail;
24797db96d56Sopenharmony_ci        Py_DECREF(res);
24807db96d56Sopenharmony_ci
24817db96d56Sopenharmony_ci        textiowrapper_set_decoded_chars(self, NULL);
24827db96d56Sopenharmony_ci        Py_CLEAR(self->snapshot);
24837db96d56Sopenharmony_ci        if (self->decoder) {
24847db96d56Sopenharmony_ci            res = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
24857db96d56Sopenharmony_ci            if (res == NULL)
24867db96d56Sopenharmony_ci                goto fail;
24877db96d56Sopenharmony_ci            Py_DECREF(res);
24887db96d56Sopenharmony_ci        }
24897db96d56Sopenharmony_ci
24907db96d56Sopenharmony_ci        res = _PyObject_CallMethod(self->buffer, &_Py_ID(seek), "ii", 0, 2);
24917db96d56Sopenharmony_ci        Py_CLEAR(cookieObj);
24927db96d56Sopenharmony_ci        if (res == NULL)
24937db96d56Sopenharmony_ci            goto fail;
24947db96d56Sopenharmony_ci        if (self->encoder) {
24957db96d56Sopenharmony_ci            /* If seek() == 0, we are at the start of stream, otherwise not */
24967db96d56Sopenharmony_ci            cmp = PyObject_RichCompareBool(res, zero, Py_EQ);
24977db96d56Sopenharmony_ci            if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) {
24987db96d56Sopenharmony_ci                Py_DECREF(res);
24997db96d56Sopenharmony_ci                goto fail;
25007db96d56Sopenharmony_ci            }
25017db96d56Sopenharmony_ci        }
25027db96d56Sopenharmony_ci        return res;
25037db96d56Sopenharmony_ci
25047db96d56Sopenharmony_ci    case SEEK_SET:
25057db96d56Sopenharmony_ci        break;
25067db96d56Sopenharmony_ci
25077db96d56Sopenharmony_ci    default:
25087db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
25097db96d56Sopenharmony_ci                     "invalid whence (%d, should be %d, %d or %d)", whence,
25107db96d56Sopenharmony_ci                     SEEK_SET, SEEK_CUR, SEEK_END);
25117db96d56Sopenharmony_ci        goto fail;
25127db96d56Sopenharmony_ci    }
25137db96d56Sopenharmony_ci
25147db96d56Sopenharmony_ci    cmp = PyObject_RichCompareBool(cookieObj, zero, Py_LT);
25157db96d56Sopenharmony_ci    if (cmp < 0)
25167db96d56Sopenharmony_ci        goto fail;
25177db96d56Sopenharmony_ci
25187db96d56Sopenharmony_ci    if (cmp == 1) {
25197db96d56Sopenharmony_ci        PyErr_Format(PyExc_ValueError,
25207db96d56Sopenharmony_ci                     "negative seek position %R", cookieObj);
25217db96d56Sopenharmony_ci        goto fail;
25227db96d56Sopenharmony_ci    }
25237db96d56Sopenharmony_ci
25247db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
25257db96d56Sopenharmony_ci    if (res == NULL)
25267db96d56Sopenharmony_ci        goto fail;
25277db96d56Sopenharmony_ci    Py_DECREF(res);
25287db96d56Sopenharmony_ci
25297db96d56Sopenharmony_ci    /* The strategy of seek() is to go back to the safe start point
25307db96d56Sopenharmony_ci     * and replay the effect of read(chars_to_skip) from there.
25317db96d56Sopenharmony_ci     */
25327db96d56Sopenharmony_ci    if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
25337db96d56Sopenharmony_ci        goto fail;
25347db96d56Sopenharmony_ci
25357db96d56Sopenharmony_ci    /* Seek back to the safe start point. */
25367db96d56Sopenharmony_ci    posobj = PyLong_FromOff_t(cookie.start_pos);
25377db96d56Sopenharmony_ci    if (posobj == NULL)
25387db96d56Sopenharmony_ci        goto fail;
25397db96d56Sopenharmony_ci    res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(seek), posobj);
25407db96d56Sopenharmony_ci    Py_DECREF(posobj);
25417db96d56Sopenharmony_ci    if (res == NULL)
25427db96d56Sopenharmony_ci        goto fail;
25437db96d56Sopenharmony_ci    Py_DECREF(res);
25447db96d56Sopenharmony_ci
25457db96d56Sopenharmony_ci    textiowrapper_set_decoded_chars(self, NULL);
25467db96d56Sopenharmony_ci    Py_CLEAR(self->snapshot);
25477db96d56Sopenharmony_ci
25487db96d56Sopenharmony_ci    /* Restore the decoder to its state from the safe start point. */
25497db96d56Sopenharmony_ci    if (self->decoder) {
25507db96d56Sopenharmony_ci        if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
25517db96d56Sopenharmony_ci            goto fail;
25527db96d56Sopenharmony_ci    }
25537db96d56Sopenharmony_ci
25547db96d56Sopenharmony_ci    if (cookie.chars_to_skip) {
25557db96d56Sopenharmony_ci        /* Just like _read_chunk, feed the decoder and save a snapshot. */
25567db96d56Sopenharmony_ci        PyObject *input_chunk = _PyObject_CallMethod(self->buffer, &_Py_ID(read),
25577db96d56Sopenharmony_ci                                                     "i", cookie.bytes_to_feed);
25587db96d56Sopenharmony_ci        PyObject *decoded;
25597db96d56Sopenharmony_ci
25607db96d56Sopenharmony_ci        if (input_chunk == NULL)
25617db96d56Sopenharmony_ci            goto fail;
25627db96d56Sopenharmony_ci
25637db96d56Sopenharmony_ci        if (!PyBytes_Check(input_chunk)) {
25647db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError,
25657db96d56Sopenharmony_ci                         "underlying read() should have returned a bytes "
25667db96d56Sopenharmony_ci                         "object, not '%.200s'",
25677db96d56Sopenharmony_ci                         Py_TYPE(input_chunk)->tp_name);
25687db96d56Sopenharmony_ci            Py_DECREF(input_chunk);
25697db96d56Sopenharmony_ci            goto fail;
25707db96d56Sopenharmony_ci        }
25717db96d56Sopenharmony_ci
25727db96d56Sopenharmony_ci        snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
25737db96d56Sopenharmony_ci        if (snapshot == NULL) {
25747db96d56Sopenharmony_ci            goto fail;
25757db96d56Sopenharmony_ci        }
25767db96d56Sopenharmony_ci        Py_XSETREF(self->snapshot, snapshot);
25777db96d56Sopenharmony_ci
25787db96d56Sopenharmony_ci        decoded = PyObject_CallMethodObjArgs(self->decoder, &_Py_ID(decode),
25797db96d56Sopenharmony_ci            input_chunk, cookie.need_eof ? Py_True : Py_False, NULL);
25807db96d56Sopenharmony_ci
25817db96d56Sopenharmony_ci        if (check_decoded(decoded) < 0)
25827db96d56Sopenharmony_ci            goto fail;
25837db96d56Sopenharmony_ci
25847db96d56Sopenharmony_ci        textiowrapper_set_decoded_chars(self, decoded);
25857db96d56Sopenharmony_ci
25867db96d56Sopenharmony_ci        /* Skip chars_to_skip of the decoded characters. */
25877db96d56Sopenharmony_ci        if (PyUnicode_GetLength(self->decoded_chars) < cookie.chars_to_skip) {
25887db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OSError, "can't restore logical file position");
25897db96d56Sopenharmony_ci            goto fail;
25907db96d56Sopenharmony_ci        }
25917db96d56Sopenharmony_ci        self->decoded_chars_used = cookie.chars_to_skip;
25927db96d56Sopenharmony_ci    }
25937db96d56Sopenharmony_ci    else {
25947db96d56Sopenharmony_ci        snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
25957db96d56Sopenharmony_ci        if (snapshot == NULL)
25967db96d56Sopenharmony_ci            goto fail;
25977db96d56Sopenharmony_ci        Py_XSETREF(self->snapshot, snapshot);
25987db96d56Sopenharmony_ci    }
25997db96d56Sopenharmony_ci
26007db96d56Sopenharmony_ci    /* Finally, reset the encoder (merely useful for proper BOM handling) */
26017db96d56Sopenharmony_ci    if (self->encoder) {
26027db96d56Sopenharmony_ci        if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
26037db96d56Sopenharmony_ci            goto fail;
26047db96d56Sopenharmony_ci    }
26057db96d56Sopenharmony_ci    return cookieObj;
26067db96d56Sopenharmony_ci  fail:
26077db96d56Sopenharmony_ci    Py_XDECREF(cookieObj);
26087db96d56Sopenharmony_ci    return NULL;
26097db96d56Sopenharmony_ci
26107db96d56Sopenharmony_ci}
26117db96d56Sopenharmony_ci
26127db96d56Sopenharmony_ci/*[clinic input]
26137db96d56Sopenharmony_ci_io.TextIOWrapper.tell
26147db96d56Sopenharmony_ci[clinic start generated code]*/
26157db96d56Sopenharmony_ci
26167db96d56Sopenharmony_cistatic PyObject *
26177db96d56Sopenharmony_ci_io_TextIOWrapper_tell_impl(textio *self)
26187db96d56Sopenharmony_ci/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/
26197db96d56Sopenharmony_ci{
26207db96d56Sopenharmony_ci    PyObject *res;
26217db96d56Sopenharmony_ci    PyObject *posobj = NULL;
26227db96d56Sopenharmony_ci    cookie_type cookie = {0,0,0,0,0};
26237db96d56Sopenharmony_ci    PyObject *next_input;
26247db96d56Sopenharmony_ci    Py_ssize_t chars_to_skip, chars_decoded;
26257db96d56Sopenharmony_ci    Py_ssize_t skip_bytes, skip_back;
26267db96d56Sopenharmony_ci    PyObject *saved_state = NULL;
26277db96d56Sopenharmony_ci    const char *input, *input_end;
26287db96d56Sopenharmony_ci    Py_ssize_t dec_buffer_len;
26297db96d56Sopenharmony_ci    int dec_flags;
26307db96d56Sopenharmony_ci
26317db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
26327db96d56Sopenharmony_ci    CHECK_CLOSED(self);
26337db96d56Sopenharmony_ci
26347db96d56Sopenharmony_ci    if (!self->seekable) {
26357db96d56Sopenharmony_ci        _unsupported("underlying stream is not seekable");
26367db96d56Sopenharmony_ci        goto fail;
26377db96d56Sopenharmony_ci    }
26387db96d56Sopenharmony_ci    if (!self->telling) {
26397db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OSError,
26407db96d56Sopenharmony_ci                        "telling position disabled by next() call");
26417db96d56Sopenharmony_ci        goto fail;
26427db96d56Sopenharmony_ci    }
26437db96d56Sopenharmony_ci
26447db96d56Sopenharmony_ci    if (_textiowrapper_writeflush(self) < 0)
26457db96d56Sopenharmony_ci        return NULL;
26467db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
26477db96d56Sopenharmony_ci    if (res == NULL)
26487db96d56Sopenharmony_ci        goto fail;
26497db96d56Sopenharmony_ci    Py_DECREF(res);
26507db96d56Sopenharmony_ci
26517db96d56Sopenharmony_ci    posobj = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(tell));
26527db96d56Sopenharmony_ci    if (posobj == NULL)
26537db96d56Sopenharmony_ci        goto fail;
26547db96d56Sopenharmony_ci
26557db96d56Sopenharmony_ci    if (self->decoder == NULL || self->snapshot == NULL) {
26567db96d56Sopenharmony_ci        assert (self->decoded_chars == NULL || PyUnicode_GetLength(self->decoded_chars) == 0);
26577db96d56Sopenharmony_ci        return posobj;
26587db96d56Sopenharmony_ci    }
26597db96d56Sopenharmony_ci
26607db96d56Sopenharmony_ci#if defined(HAVE_LARGEFILE_SUPPORT)
26617db96d56Sopenharmony_ci    cookie.start_pos = PyLong_AsLongLong(posobj);
26627db96d56Sopenharmony_ci#else
26637db96d56Sopenharmony_ci    cookie.start_pos = PyLong_AsLong(posobj);
26647db96d56Sopenharmony_ci#endif
26657db96d56Sopenharmony_ci    Py_DECREF(posobj);
26667db96d56Sopenharmony_ci    if (PyErr_Occurred())
26677db96d56Sopenharmony_ci        goto fail;
26687db96d56Sopenharmony_ci
26697db96d56Sopenharmony_ci    /* Skip backward to the snapshot point (see _read_chunk). */
26707db96d56Sopenharmony_ci    assert(PyTuple_Check(self->snapshot));
26717db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input))
26727db96d56Sopenharmony_ci        goto fail;
26737db96d56Sopenharmony_ci
26747db96d56Sopenharmony_ci    assert (PyBytes_Check(next_input));
26757db96d56Sopenharmony_ci
26767db96d56Sopenharmony_ci    cookie.start_pos -= PyBytes_GET_SIZE(next_input);
26777db96d56Sopenharmony_ci
26787db96d56Sopenharmony_ci    /* How many decoded characters have been used up since the snapshot? */
26797db96d56Sopenharmony_ci    if (self->decoded_chars_used == 0)  {
26807db96d56Sopenharmony_ci        /* We haven't moved from the snapshot point. */
26817db96d56Sopenharmony_ci        return textiowrapper_build_cookie(&cookie);
26827db96d56Sopenharmony_ci    }
26837db96d56Sopenharmony_ci
26847db96d56Sopenharmony_ci    chars_to_skip = self->decoded_chars_used;
26857db96d56Sopenharmony_ci
26867db96d56Sopenharmony_ci    /* Decoder state will be restored at the end */
26877db96d56Sopenharmony_ci    saved_state = PyObject_CallMethodNoArgs(self->decoder,
26887db96d56Sopenharmony_ci                                             &_Py_ID(getstate));
26897db96d56Sopenharmony_ci    if (saved_state == NULL)
26907db96d56Sopenharmony_ci        goto fail;
26917db96d56Sopenharmony_ci
26927db96d56Sopenharmony_ci#define DECODER_GETSTATE() do { \
26937db96d56Sopenharmony_ci        PyObject *dec_buffer; \
26947db96d56Sopenharmony_ci        PyObject *_state = PyObject_CallMethodNoArgs(self->decoder, \
26957db96d56Sopenharmony_ci            &_Py_ID(getstate)); \
26967db96d56Sopenharmony_ci        if (_state == NULL) \
26977db96d56Sopenharmony_ci            goto fail; \
26987db96d56Sopenharmony_ci        if (!PyTuple_Check(_state)) { \
26997db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError, \
27007db96d56Sopenharmony_ci                            "illegal decoder state"); \
27017db96d56Sopenharmony_ci            Py_DECREF(_state); \
27027db96d56Sopenharmony_ci            goto fail; \
27037db96d56Sopenharmony_ci        } \
27047db96d56Sopenharmony_ci        if (!PyArg_ParseTuple(_state, "Oi;illegal decoder state", \
27057db96d56Sopenharmony_ci                              &dec_buffer, &dec_flags)) \
27067db96d56Sopenharmony_ci        { \
27077db96d56Sopenharmony_ci            Py_DECREF(_state); \
27087db96d56Sopenharmony_ci            goto fail; \
27097db96d56Sopenharmony_ci        } \
27107db96d56Sopenharmony_ci        if (!PyBytes_Check(dec_buffer)) { \
27117db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError, \
27127db96d56Sopenharmony_ci                         "illegal decoder state: the first item should be a " \
27137db96d56Sopenharmony_ci                         "bytes object, not '%.200s'", \
27147db96d56Sopenharmony_ci                         Py_TYPE(dec_buffer)->tp_name); \
27157db96d56Sopenharmony_ci            Py_DECREF(_state); \
27167db96d56Sopenharmony_ci            goto fail; \
27177db96d56Sopenharmony_ci        } \
27187db96d56Sopenharmony_ci        dec_buffer_len = PyBytes_GET_SIZE(dec_buffer); \
27197db96d56Sopenharmony_ci        Py_DECREF(_state); \
27207db96d56Sopenharmony_ci    } while (0)
27217db96d56Sopenharmony_ci
27227db96d56Sopenharmony_ci#define DECODER_DECODE(start, len, res) do { \
27237db96d56Sopenharmony_ci        PyObject *_decoded = _PyObject_CallMethod( \
27247db96d56Sopenharmony_ci            self->decoder, &_Py_ID(decode), "y#", start, len); \
27257db96d56Sopenharmony_ci        if (check_decoded(_decoded) < 0) \
27267db96d56Sopenharmony_ci            goto fail; \
27277db96d56Sopenharmony_ci        res = PyUnicode_GET_LENGTH(_decoded); \
27287db96d56Sopenharmony_ci        Py_DECREF(_decoded); \
27297db96d56Sopenharmony_ci    } while (0)
27307db96d56Sopenharmony_ci
27317db96d56Sopenharmony_ci    /* Fast search for an acceptable start point, close to our
27327db96d56Sopenharmony_ci       current pos */
27337db96d56Sopenharmony_ci    skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip);
27347db96d56Sopenharmony_ci    skip_back = 1;
27357db96d56Sopenharmony_ci    assert(skip_back <= PyBytes_GET_SIZE(next_input));
27367db96d56Sopenharmony_ci    input = PyBytes_AS_STRING(next_input);
27377db96d56Sopenharmony_ci    while (skip_bytes > 0) {
27387db96d56Sopenharmony_ci        /* Decode up to temptative start point */
27397db96d56Sopenharmony_ci        if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
27407db96d56Sopenharmony_ci            goto fail;
27417db96d56Sopenharmony_ci        DECODER_DECODE(input, skip_bytes, chars_decoded);
27427db96d56Sopenharmony_ci        if (chars_decoded <= chars_to_skip) {
27437db96d56Sopenharmony_ci            DECODER_GETSTATE();
27447db96d56Sopenharmony_ci            if (dec_buffer_len == 0) {
27457db96d56Sopenharmony_ci                /* Before pos and no bytes buffered in decoder => OK */
27467db96d56Sopenharmony_ci                cookie.dec_flags = dec_flags;
27477db96d56Sopenharmony_ci                chars_to_skip -= chars_decoded;
27487db96d56Sopenharmony_ci                break;
27497db96d56Sopenharmony_ci            }
27507db96d56Sopenharmony_ci            /* Skip back by buffered amount and reset heuristic */
27517db96d56Sopenharmony_ci            skip_bytes -= dec_buffer_len;
27527db96d56Sopenharmony_ci            skip_back = 1;
27537db96d56Sopenharmony_ci        }
27547db96d56Sopenharmony_ci        else {
27557db96d56Sopenharmony_ci            /* We're too far ahead, skip back a bit */
27567db96d56Sopenharmony_ci            skip_bytes -= skip_back;
27577db96d56Sopenharmony_ci            skip_back *= 2;
27587db96d56Sopenharmony_ci        }
27597db96d56Sopenharmony_ci    }
27607db96d56Sopenharmony_ci    if (skip_bytes <= 0) {
27617db96d56Sopenharmony_ci        skip_bytes = 0;
27627db96d56Sopenharmony_ci        if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
27637db96d56Sopenharmony_ci            goto fail;
27647db96d56Sopenharmony_ci    }
27657db96d56Sopenharmony_ci
27667db96d56Sopenharmony_ci    /* Note our initial start point. */
27677db96d56Sopenharmony_ci    cookie.start_pos += skip_bytes;
27687db96d56Sopenharmony_ci    cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
27697db96d56Sopenharmony_ci    if (chars_to_skip == 0)
27707db96d56Sopenharmony_ci        goto finally;
27717db96d56Sopenharmony_ci
27727db96d56Sopenharmony_ci    /* We should be close to the desired position.  Now feed the decoder one
27737db96d56Sopenharmony_ci     * byte at a time until we reach the `chars_to_skip` target.
27747db96d56Sopenharmony_ci     * As we go, note the nearest "safe start point" before the current
27757db96d56Sopenharmony_ci     * location (a point where the decoder has nothing buffered, so seek()
27767db96d56Sopenharmony_ci     * can safely start from there and advance to this location).
27777db96d56Sopenharmony_ci     */
27787db96d56Sopenharmony_ci    chars_decoded = 0;
27797db96d56Sopenharmony_ci    input = PyBytes_AS_STRING(next_input);
27807db96d56Sopenharmony_ci    input_end = input + PyBytes_GET_SIZE(next_input);
27817db96d56Sopenharmony_ci    input += skip_bytes;
27827db96d56Sopenharmony_ci    while (input < input_end) {
27837db96d56Sopenharmony_ci        Py_ssize_t n;
27847db96d56Sopenharmony_ci
27857db96d56Sopenharmony_ci        DECODER_DECODE(input, (Py_ssize_t)1, n);
27867db96d56Sopenharmony_ci        /* We got n chars for 1 byte */
27877db96d56Sopenharmony_ci        chars_decoded += n;
27887db96d56Sopenharmony_ci        cookie.bytes_to_feed += 1;
27897db96d56Sopenharmony_ci        DECODER_GETSTATE();
27907db96d56Sopenharmony_ci
27917db96d56Sopenharmony_ci        if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
27927db96d56Sopenharmony_ci            /* Decoder buffer is empty, so this is a safe start point. */
27937db96d56Sopenharmony_ci            cookie.start_pos += cookie.bytes_to_feed;
27947db96d56Sopenharmony_ci            chars_to_skip -= chars_decoded;
27957db96d56Sopenharmony_ci            cookie.dec_flags = dec_flags;
27967db96d56Sopenharmony_ci            cookie.bytes_to_feed = 0;
27977db96d56Sopenharmony_ci            chars_decoded = 0;
27987db96d56Sopenharmony_ci        }
27997db96d56Sopenharmony_ci        if (chars_decoded >= chars_to_skip)
28007db96d56Sopenharmony_ci            break;
28017db96d56Sopenharmony_ci        input++;
28027db96d56Sopenharmony_ci    }
28037db96d56Sopenharmony_ci    if (input == input_end) {
28047db96d56Sopenharmony_ci        /* We didn't get enough decoded data; signal EOF to get more. */
28057db96d56Sopenharmony_ci        PyObject *decoded = _PyObject_CallMethod(
28067db96d56Sopenharmony_ci            self->decoder, &_Py_ID(decode), "yO", "", /* final = */ Py_True);
28077db96d56Sopenharmony_ci        if (check_decoded(decoded) < 0)
28087db96d56Sopenharmony_ci            goto fail;
28097db96d56Sopenharmony_ci        chars_decoded += PyUnicode_GET_LENGTH(decoded);
28107db96d56Sopenharmony_ci        Py_DECREF(decoded);
28117db96d56Sopenharmony_ci        cookie.need_eof = 1;
28127db96d56Sopenharmony_ci
28137db96d56Sopenharmony_ci        if (chars_decoded < chars_to_skip) {
28147db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OSError,
28157db96d56Sopenharmony_ci                            "can't reconstruct logical file position");
28167db96d56Sopenharmony_ci            goto fail;
28177db96d56Sopenharmony_ci        }
28187db96d56Sopenharmony_ci    }
28197db96d56Sopenharmony_ci
28207db96d56Sopenharmony_cifinally:
28217db96d56Sopenharmony_ci    res = PyObject_CallMethodOneArg(
28227db96d56Sopenharmony_ci            self->decoder, &_Py_ID(setstate), saved_state);
28237db96d56Sopenharmony_ci    Py_DECREF(saved_state);
28247db96d56Sopenharmony_ci    if (res == NULL)
28257db96d56Sopenharmony_ci        return NULL;
28267db96d56Sopenharmony_ci    Py_DECREF(res);
28277db96d56Sopenharmony_ci
28287db96d56Sopenharmony_ci    /* The returned cookie corresponds to the last safe start point. */
28297db96d56Sopenharmony_ci    cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
28307db96d56Sopenharmony_ci    return textiowrapper_build_cookie(&cookie);
28317db96d56Sopenharmony_ci
28327db96d56Sopenharmony_cifail:
28337db96d56Sopenharmony_ci    if (saved_state) {
28347db96d56Sopenharmony_ci        PyObject *type, *value, *traceback;
28357db96d56Sopenharmony_ci        PyErr_Fetch(&type, &value, &traceback);
28367db96d56Sopenharmony_ci        res = PyObject_CallMethodOneArg(
28377db96d56Sopenharmony_ci                self->decoder, &_Py_ID(setstate), saved_state);
28387db96d56Sopenharmony_ci        _PyErr_ChainExceptions(type, value, traceback);
28397db96d56Sopenharmony_ci        Py_DECREF(saved_state);
28407db96d56Sopenharmony_ci        Py_XDECREF(res);
28417db96d56Sopenharmony_ci    }
28427db96d56Sopenharmony_ci    return NULL;
28437db96d56Sopenharmony_ci}
28447db96d56Sopenharmony_ci
28457db96d56Sopenharmony_ci/*[clinic input]
28467db96d56Sopenharmony_ci_io.TextIOWrapper.truncate
28477db96d56Sopenharmony_ci    pos: object = None
28487db96d56Sopenharmony_ci    /
28497db96d56Sopenharmony_ci[clinic start generated code]*/
28507db96d56Sopenharmony_ci
28517db96d56Sopenharmony_cistatic PyObject *
28527db96d56Sopenharmony_ci_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos)
28537db96d56Sopenharmony_ci/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/
28547db96d56Sopenharmony_ci{
28557db96d56Sopenharmony_ci    PyObject *res;
28567db96d56Sopenharmony_ci
28577db96d56Sopenharmony_ci    CHECK_ATTACHED(self)
28587db96d56Sopenharmony_ci
28597db96d56Sopenharmony_ci    res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
28607db96d56Sopenharmony_ci    if (res == NULL)
28617db96d56Sopenharmony_ci        return NULL;
28627db96d56Sopenharmony_ci    Py_DECREF(res);
28637db96d56Sopenharmony_ci
28647db96d56Sopenharmony_ci    return PyObject_CallMethodOneArg(self->buffer, &_Py_ID(truncate), pos);
28657db96d56Sopenharmony_ci}
28667db96d56Sopenharmony_ci
28677db96d56Sopenharmony_cistatic PyObject *
28687db96d56Sopenharmony_citextiowrapper_repr(textio *self)
28697db96d56Sopenharmony_ci{
28707db96d56Sopenharmony_ci    PyObject *nameobj, *modeobj, *res, *s;
28717db96d56Sopenharmony_ci    int status;
28727db96d56Sopenharmony_ci
28737db96d56Sopenharmony_ci    CHECK_INITIALIZED(self);
28747db96d56Sopenharmony_ci
28757db96d56Sopenharmony_ci    res = PyUnicode_FromString("<_io.TextIOWrapper");
28767db96d56Sopenharmony_ci    if (res == NULL)
28777db96d56Sopenharmony_ci        return NULL;
28787db96d56Sopenharmony_ci
28797db96d56Sopenharmony_ci    status = Py_ReprEnter((PyObject *)self);
28807db96d56Sopenharmony_ci    if (status != 0) {
28817db96d56Sopenharmony_ci        if (status > 0) {
28827db96d56Sopenharmony_ci            PyErr_Format(PyExc_RuntimeError,
28837db96d56Sopenharmony_ci                         "reentrant call inside %s.__repr__",
28847db96d56Sopenharmony_ci                         Py_TYPE(self)->tp_name);
28857db96d56Sopenharmony_ci        }
28867db96d56Sopenharmony_ci        goto error;
28877db96d56Sopenharmony_ci    }
28887db96d56Sopenharmony_ci    if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) {
28897db96d56Sopenharmony_ci        if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
28907db96d56Sopenharmony_ci            goto error;
28917db96d56Sopenharmony_ci        }
28927db96d56Sopenharmony_ci        /* Ignore ValueError raised if the underlying stream was detached */
28937db96d56Sopenharmony_ci        PyErr_Clear();
28947db96d56Sopenharmony_ci    }
28957db96d56Sopenharmony_ci    if (nameobj != NULL) {
28967db96d56Sopenharmony_ci        s = PyUnicode_FromFormat(" name=%R", nameobj);
28977db96d56Sopenharmony_ci        Py_DECREF(nameobj);
28987db96d56Sopenharmony_ci        if (s == NULL)
28997db96d56Sopenharmony_ci            goto error;
29007db96d56Sopenharmony_ci        PyUnicode_AppendAndDel(&res, s);
29017db96d56Sopenharmony_ci        if (res == NULL)
29027db96d56Sopenharmony_ci            goto error;
29037db96d56Sopenharmony_ci    }
29047db96d56Sopenharmony_ci    if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(mode), &modeobj) < 0) {
29057db96d56Sopenharmony_ci        goto error;
29067db96d56Sopenharmony_ci    }
29077db96d56Sopenharmony_ci    if (modeobj != NULL) {
29087db96d56Sopenharmony_ci        s = PyUnicode_FromFormat(" mode=%R", modeobj);
29097db96d56Sopenharmony_ci        Py_DECREF(modeobj);
29107db96d56Sopenharmony_ci        if (s == NULL)
29117db96d56Sopenharmony_ci            goto error;
29127db96d56Sopenharmony_ci        PyUnicode_AppendAndDel(&res, s);
29137db96d56Sopenharmony_ci        if (res == NULL)
29147db96d56Sopenharmony_ci            goto error;
29157db96d56Sopenharmony_ci    }
29167db96d56Sopenharmony_ci    s = PyUnicode_FromFormat("%U encoding=%R>",
29177db96d56Sopenharmony_ci                             res, self->encoding);
29187db96d56Sopenharmony_ci    Py_DECREF(res);
29197db96d56Sopenharmony_ci    if (status == 0) {
29207db96d56Sopenharmony_ci        Py_ReprLeave((PyObject *)self);
29217db96d56Sopenharmony_ci    }
29227db96d56Sopenharmony_ci    return s;
29237db96d56Sopenharmony_ci
29247db96d56Sopenharmony_ci  error:
29257db96d56Sopenharmony_ci    Py_XDECREF(res);
29267db96d56Sopenharmony_ci    if (status == 0) {
29277db96d56Sopenharmony_ci        Py_ReprLeave((PyObject *)self);
29287db96d56Sopenharmony_ci    }
29297db96d56Sopenharmony_ci    return NULL;
29307db96d56Sopenharmony_ci}
29317db96d56Sopenharmony_ci
29327db96d56Sopenharmony_ci
29337db96d56Sopenharmony_ci/* Inquiries */
29347db96d56Sopenharmony_ci
29357db96d56Sopenharmony_ci/*[clinic input]
29367db96d56Sopenharmony_ci_io.TextIOWrapper.fileno
29377db96d56Sopenharmony_ci[clinic start generated code]*/
29387db96d56Sopenharmony_ci
29397db96d56Sopenharmony_cistatic PyObject *
29407db96d56Sopenharmony_ci_io_TextIOWrapper_fileno_impl(textio *self)
29417db96d56Sopenharmony_ci/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/
29427db96d56Sopenharmony_ci{
29437db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
29447db96d56Sopenharmony_ci    return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(fileno));
29457db96d56Sopenharmony_ci}
29467db96d56Sopenharmony_ci
29477db96d56Sopenharmony_ci/*[clinic input]
29487db96d56Sopenharmony_ci_io.TextIOWrapper.seekable
29497db96d56Sopenharmony_ci[clinic start generated code]*/
29507db96d56Sopenharmony_ci
29517db96d56Sopenharmony_cistatic PyObject *
29527db96d56Sopenharmony_ci_io_TextIOWrapper_seekable_impl(textio *self)
29537db96d56Sopenharmony_ci/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/
29547db96d56Sopenharmony_ci{
29557db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
29567db96d56Sopenharmony_ci    return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(seekable));
29577db96d56Sopenharmony_ci}
29587db96d56Sopenharmony_ci
29597db96d56Sopenharmony_ci/*[clinic input]
29607db96d56Sopenharmony_ci_io.TextIOWrapper.readable
29617db96d56Sopenharmony_ci[clinic start generated code]*/
29627db96d56Sopenharmony_ci
29637db96d56Sopenharmony_cistatic PyObject *
29647db96d56Sopenharmony_ci_io_TextIOWrapper_readable_impl(textio *self)
29657db96d56Sopenharmony_ci/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/
29667db96d56Sopenharmony_ci{
29677db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
29687db96d56Sopenharmony_ci    return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(readable));
29697db96d56Sopenharmony_ci}
29707db96d56Sopenharmony_ci
29717db96d56Sopenharmony_ci/*[clinic input]
29727db96d56Sopenharmony_ci_io.TextIOWrapper.writable
29737db96d56Sopenharmony_ci[clinic start generated code]*/
29747db96d56Sopenharmony_ci
29757db96d56Sopenharmony_cistatic PyObject *
29767db96d56Sopenharmony_ci_io_TextIOWrapper_writable_impl(textio *self)
29777db96d56Sopenharmony_ci/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/
29787db96d56Sopenharmony_ci{
29797db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
29807db96d56Sopenharmony_ci    return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(writable));
29817db96d56Sopenharmony_ci}
29827db96d56Sopenharmony_ci
29837db96d56Sopenharmony_ci/*[clinic input]
29847db96d56Sopenharmony_ci_io.TextIOWrapper.isatty
29857db96d56Sopenharmony_ci[clinic start generated code]*/
29867db96d56Sopenharmony_ci
29877db96d56Sopenharmony_cistatic PyObject *
29887db96d56Sopenharmony_ci_io_TextIOWrapper_isatty_impl(textio *self)
29897db96d56Sopenharmony_ci/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/
29907db96d56Sopenharmony_ci{
29917db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
29927db96d56Sopenharmony_ci    return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(isatty));
29937db96d56Sopenharmony_ci}
29947db96d56Sopenharmony_ci
29957db96d56Sopenharmony_ci/*[clinic input]
29967db96d56Sopenharmony_ci_io.TextIOWrapper.flush
29977db96d56Sopenharmony_ci[clinic start generated code]*/
29987db96d56Sopenharmony_ci
29997db96d56Sopenharmony_cistatic PyObject *
30007db96d56Sopenharmony_ci_io_TextIOWrapper_flush_impl(textio *self)
30017db96d56Sopenharmony_ci/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/
30027db96d56Sopenharmony_ci{
30037db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
30047db96d56Sopenharmony_ci    CHECK_CLOSED(self);
30057db96d56Sopenharmony_ci    self->telling = self->seekable;
30067db96d56Sopenharmony_ci    if (_textiowrapper_writeflush(self) < 0)
30077db96d56Sopenharmony_ci        return NULL;
30087db96d56Sopenharmony_ci    return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(flush));
30097db96d56Sopenharmony_ci}
30107db96d56Sopenharmony_ci
30117db96d56Sopenharmony_ci/*[clinic input]
30127db96d56Sopenharmony_ci_io.TextIOWrapper.close
30137db96d56Sopenharmony_ci[clinic start generated code]*/
30147db96d56Sopenharmony_ci
30157db96d56Sopenharmony_cistatic PyObject *
30167db96d56Sopenharmony_ci_io_TextIOWrapper_close_impl(textio *self)
30177db96d56Sopenharmony_ci/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/
30187db96d56Sopenharmony_ci{
30197db96d56Sopenharmony_ci    PyObject *res;
30207db96d56Sopenharmony_ci    int r;
30217db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
30227db96d56Sopenharmony_ci
30237db96d56Sopenharmony_ci    res = textiowrapper_closed_get(self, NULL);
30247db96d56Sopenharmony_ci    if (res == NULL)
30257db96d56Sopenharmony_ci        return NULL;
30267db96d56Sopenharmony_ci    r = PyObject_IsTrue(res);
30277db96d56Sopenharmony_ci    Py_DECREF(res);
30287db96d56Sopenharmony_ci    if (r < 0)
30297db96d56Sopenharmony_ci        return NULL;
30307db96d56Sopenharmony_ci
30317db96d56Sopenharmony_ci    if (r > 0) {
30327db96d56Sopenharmony_ci        Py_RETURN_NONE; /* stream already closed */
30337db96d56Sopenharmony_ci    }
30347db96d56Sopenharmony_ci    else {
30357db96d56Sopenharmony_ci        PyObject *exc = NULL, *val, *tb;
30367db96d56Sopenharmony_ci        if (self->finalizing) {
30377db96d56Sopenharmony_ci            res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(_dealloc_warn),
30387db96d56Sopenharmony_ci                                            (PyObject *)self);
30397db96d56Sopenharmony_ci            if (res)
30407db96d56Sopenharmony_ci                Py_DECREF(res);
30417db96d56Sopenharmony_ci            else
30427db96d56Sopenharmony_ci                PyErr_Clear();
30437db96d56Sopenharmony_ci        }
30447db96d56Sopenharmony_ci        res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
30457db96d56Sopenharmony_ci        if (res == NULL)
30467db96d56Sopenharmony_ci            PyErr_Fetch(&exc, &val, &tb);
30477db96d56Sopenharmony_ci        else
30487db96d56Sopenharmony_ci            Py_DECREF(res);
30497db96d56Sopenharmony_ci
30507db96d56Sopenharmony_ci        res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(close));
30517db96d56Sopenharmony_ci        if (exc != NULL) {
30527db96d56Sopenharmony_ci            _PyErr_ChainExceptions(exc, val, tb);
30537db96d56Sopenharmony_ci            Py_CLEAR(res);
30547db96d56Sopenharmony_ci        }
30557db96d56Sopenharmony_ci        return res;
30567db96d56Sopenharmony_ci    }
30577db96d56Sopenharmony_ci}
30587db96d56Sopenharmony_ci
30597db96d56Sopenharmony_cistatic PyObject *
30607db96d56Sopenharmony_citextiowrapper_iternext(textio *self)
30617db96d56Sopenharmony_ci{
30627db96d56Sopenharmony_ci    PyObject *line;
30637db96d56Sopenharmony_ci
30647db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
30657db96d56Sopenharmony_ci
30667db96d56Sopenharmony_ci    self->telling = 0;
30677db96d56Sopenharmony_ci    if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) {
30687db96d56Sopenharmony_ci        /* Skip method call overhead for speed */
30697db96d56Sopenharmony_ci        line = _textiowrapper_readline(self, -1);
30707db96d56Sopenharmony_ci    }
30717db96d56Sopenharmony_ci    else {
30727db96d56Sopenharmony_ci        line = PyObject_CallMethodNoArgs((PyObject *)self,
30737db96d56Sopenharmony_ci                                          &_Py_ID(readline));
30747db96d56Sopenharmony_ci        if (line && !PyUnicode_Check(line)) {
30757db96d56Sopenharmony_ci            PyErr_Format(PyExc_OSError,
30767db96d56Sopenharmony_ci                         "readline() should have returned a str object, "
30777db96d56Sopenharmony_ci                         "not '%.200s'", Py_TYPE(line)->tp_name);
30787db96d56Sopenharmony_ci            Py_DECREF(line);
30797db96d56Sopenharmony_ci            return NULL;
30807db96d56Sopenharmony_ci        }
30817db96d56Sopenharmony_ci    }
30827db96d56Sopenharmony_ci
30837db96d56Sopenharmony_ci    if (line == NULL || PyUnicode_READY(line) == -1)
30847db96d56Sopenharmony_ci        return NULL;
30857db96d56Sopenharmony_ci
30867db96d56Sopenharmony_ci    if (PyUnicode_GET_LENGTH(line) == 0) {
30877db96d56Sopenharmony_ci        /* Reached EOF or would have blocked */
30887db96d56Sopenharmony_ci        Py_DECREF(line);
30897db96d56Sopenharmony_ci        Py_CLEAR(self->snapshot);
30907db96d56Sopenharmony_ci        self->telling = self->seekable;
30917db96d56Sopenharmony_ci        return NULL;
30927db96d56Sopenharmony_ci    }
30937db96d56Sopenharmony_ci
30947db96d56Sopenharmony_ci    return line;
30957db96d56Sopenharmony_ci}
30967db96d56Sopenharmony_ci
30977db96d56Sopenharmony_cistatic PyObject *
30987db96d56Sopenharmony_citextiowrapper_name_get(textio *self, void *context)
30997db96d56Sopenharmony_ci{
31007db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
31017db96d56Sopenharmony_ci    return PyObject_GetAttr(self->buffer, &_Py_ID(name));
31027db96d56Sopenharmony_ci}
31037db96d56Sopenharmony_ci
31047db96d56Sopenharmony_cistatic PyObject *
31057db96d56Sopenharmony_citextiowrapper_closed_get(textio *self, void *context)
31067db96d56Sopenharmony_ci{
31077db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
31087db96d56Sopenharmony_ci    return PyObject_GetAttr(self->buffer, &_Py_ID(closed));
31097db96d56Sopenharmony_ci}
31107db96d56Sopenharmony_ci
31117db96d56Sopenharmony_cistatic PyObject *
31127db96d56Sopenharmony_citextiowrapper_newlines_get(textio *self, void *context)
31137db96d56Sopenharmony_ci{
31147db96d56Sopenharmony_ci    PyObject *res;
31157db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
31167db96d56Sopenharmony_ci    if (self->decoder == NULL ||
31177db96d56Sopenharmony_ci        _PyObject_LookupAttr(self->decoder, &_Py_ID(newlines), &res) == 0)
31187db96d56Sopenharmony_ci    {
31197db96d56Sopenharmony_ci        Py_RETURN_NONE;
31207db96d56Sopenharmony_ci    }
31217db96d56Sopenharmony_ci    return res;
31227db96d56Sopenharmony_ci}
31237db96d56Sopenharmony_ci
31247db96d56Sopenharmony_cistatic PyObject *
31257db96d56Sopenharmony_citextiowrapper_errors_get(textio *self, void *context)
31267db96d56Sopenharmony_ci{
31277db96d56Sopenharmony_ci    CHECK_INITIALIZED(self);
31287db96d56Sopenharmony_ci    Py_INCREF(self->errors);
31297db96d56Sopenharmony_ci    return self->errors;
31307db96d56Sopenharmony_ci}
31317db96d56Sopenharmony_ci
31327db96d56Sopenharmony_cistatic PyObject *
31337db96d56Sopenharmony_citextiowrapper_chunk_size_get(textio *self, void *context)
31347db96d56Sopenharmony_ci{
31357db96d56Sopenharmony_ci    CHECK_ATTACHED(self);
31367db96d56Sopenharmony_ci    return PyLong_FromSsize_t(self->chunk_size);
31377db96d56Sopenharmony_ci}
31387db96d56Sopenharmony_ci
31397db96d56Sopenharmony_cistatic int
31407db96d56Sopenharmony_citextiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
31417db96d56Sopenharmony_ci{
31427db96d56Sopenharmony_ci    Py_ssize_t n;
31437db96d56Sopenharmony_ci    CHECK_ATTACHED_INT(self);
31447db96d56Sopenharmony_ci    if (arg == NULL) {
31457db96d56Sopenharmony_ci        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
31467db96d56Sopenharmony_ci        return -1;
31477db96d56Sopenharmony_ci    }
31487db96d56Sopenharmony_ci    n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
31497db96d56Sopenharmony_ci    if (n == -1 && PyErr_Occurred())
31507db96d56Sopenharmony_ci        return -1;
31517db96d56Sopenharmony_ci    if (n <= 0) {
31527db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
31537db96d56Sopenharmony_ci                        "a strictly positive integer is required");
31547db96d56Sopenharmony_ci        return -1;
31557db96d56Sopenharmony_ci    }
31567db96d56Sopenharmony_ci    self->chunk_size = n;
31577db96d56Sopenharmony_ci    return 0;
31587db96d56Sopenharmony_ci}
31597db96d56Sopenharmony_ci
31607db96d56Sopenharmony_ci#include "clinic/textio.c.h"
31617db96d56Sopenharmony_ci
31627db96d56Sopenharmony_cistatic PyMethodDef incrementalnewlinedecoder_methods[] = {
31637db96d56Sopenharmony_ci    _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF
31647db96d56Sopenharmony_ci    _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF
31657db96d56Sopenharmony_ci    _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF
31667db96d56Sopenharmony_ci    _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF
31677db96d56Sopenharmony_ci    {NULL}
31687db96d56Sopenharmony_ci};
31697db96d56Sopenharmony_ci
31707db96d56Sopenharmony_cistatic PyGetSetDef incrementalnewlinedecoder_getset[] = {
31717db96d56Sopenharmony_ci    {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL},
31727db96d56Sopenharmony_ci    {NULL}
31737db96d56Sopenharmony_ci};
31747db96d56Sopenharmony_ci
31757db96d56Sopenharmony_ciPyTypeObject PyIncrementalNewlineDecoder_Type = {
31767db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
31777db96d56Sopenharmony_ci    "_io.IncrementalNewlineDecoder", /*tp_name*/
31787db96d56Sopenharmony_ci    sizeof(nldecoder_object), /*tp_basicsize*/
31797db96d56Sopenharmony_ci    0,                          /*tp_itemsize*/
31807db96d56Sopenharmony_ci    (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/
31817db96d56Sopenharmony_ci    0,                          /*tp_vectorcall_offset*/
31827db96d56Sopenharmony_ci    0,                          /*tp_getattr*/
31837db96d56Sopenharmony_ci    0,                          /*tp_setattr*/
31847db96d56Sopenharmony_ci    0,                          /*tp_as_async*/
31857db96d56Sopenharmony_ci    0,                          /*tp_repr*/
31867db96d56Sopenharmony_ci    0,                          /*tp_as_number*/
31877db96d56Sopenharmony_ci    0,                          /*tp_as_sequence*/
31887db96d56Sopenharmony_ci    0,                          /*tp_as_mapping*/
31897db96d56Sopenharmony_ci    0,                          /*tp_hash */
31907db96d56Sopenharmony_ci    0,                          /*tp_call*/
31917db96d56Sopenharmony_ci    0,                          /*tp_str*/
31927db96d56Sopenharmony_ci    0,                          /*tp_getattro*/
31937db96d56Sopenharmony_ci    0,                          /*tp_setattro*/
31947db96d56Sopenharmony_ci    0,                          /*tp_as_buffer*/
31957db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
31967db96d56Sopenharmony_ci    _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */
31977db96d56Sopenharmony_ci    0,                          /* tp_traverse */
31987db96d56Sopenharmony_ci    0,                          /* tp_clear */
31997db96d56Sopenharmony_ci    0,                          /* tp_richcompare */
32007db96d56Sopenharmony_ci    0,                          /*tp_weaklistoffset*/
32017db96d56Sopenharmony_ci    0,                          /* tp_iter */
32027db96d56Sopenharmony_ci    0,                          /* tp_iternext */
32037db96d56Sopenharmony_ci    incrementalnewlinedecoder_methods, /* tp_methods */
32047db96d56Sopenharmony_ci    0,                          /* tp_members */
32057db96d56Sopenharmony_ci    incrementalnewlinedecoder_getset, /* tp_getset */
32067db96d56Sopenharmony_ci    0,                          /* tp_base */
32077db96d56Sopenharmony_ci    0,                          /* tp_dict */
32087db96d56Sopenharmony_ci    0,                          /* tp_descr_get */
32097db96d56Sopenharmony_ci    0,                          /* tp_descr_set */
32107db96d56Sopenharmony_ci    0,                          /* tp_dictoffset */
32117db96d56Sopenharmony_ci    _io_IncrementalNewlineDecoder___init__, /* tp_init */
32127db96d56Sopenharmony_ci    0,                          /* tp_alloc */
32137db96d56Sopenharmony_ci    PyType_GenericNew,          /* tp_new */
32147db96d56Sopenharmony_ci};
32157db96d56Sopenharmony_ci
32167db96d56Sopenharmony_ci
32177db96d56Sopenharmony_cistatic PyMethodDef textiowrapper_methods[] = {
32187db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_DETACH_METHODDEF
32197db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF
32207db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_WRITE_METHODDEF
32217db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_READ_METHODDEF
32227db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_READLINE_METHODDEF
32237db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_FLUSH_METHODDEF
32247db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_CLOSE_METHODDEF
32257db96d56Sopenharmony_ci
32267db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_FILENO_METHODDEF
32277db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF
32287db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_READABLE_METHODDEF
32297db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF
32307db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_ISATTY_METHODDEF
32317db96d56Sopenharmony_ci
32327db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_SEEK_METHODDEF
32337db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_TELL_METHODDEF
32347db96d56Sopenharmony_ci    _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF
32357db96d56Sopenharmony_ci    {NULL, NULL}
32367db96d56Sopenharmony_ci};
32377db96d56Sopenharmony_ci
32387db96d56Sopenharmony_cistatic PyMemberDef textiowrapper_members[] = {
32397db96d56Sopenharmony_ci    {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
32407db96d56Sopenharmony_ci    {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
32417db96d56Sopenharmony_ci    {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
32427db96d56Sopenharmony_ci    {"write_through", T_BOOL, offsetof(textio, write_through), READONLY},
32437db96d56Sopenharmony_ci    {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0},
32447db96d56Sopenharmony_ci    {NULL}
32457db96d56Sopenharmony_ci};
32467db96d56Sopenharmony_ci
32477db96d56Sopenharmony_cistatic PyGetSetDef textiowrapper_getset[] = {
32487db96d56Sopenharmony_ci    {"name", (getter)textiowrapper_name_get, NULL, NULL},
32497db96d56Sopenharmony_ci    {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
32507db96d56Sopenharmony_ci/*    {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
32517db96d56Sopenharmony_ci*/
32527db96d56Sopenharmony_ci    {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
32537db96d56Sopenharmony_ci    {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
32547db96d56Sopenharmony_ci    {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
32557db96d56Sopenharmony_ci                    (setter)textiowrapper_chunk_size_set, NULL},
32567db96d56Sopenharmony_ci    {NULL}
32577db96d56Sopenharmony_ci};
32587db96d56Sopenharmony_ci
32597db96d56Sopenharmony_ciPyTypeObject PyTextIOWrapper_Type = {
32607db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
32617db96d56Sopenharmony_ci    "_io.TextIOWrapper",        /*tp_name*/
32627db96d56Sopenharmony_ci    sizeof(textio), /*tp_basicsize*/
32637db96d56Sopenharmony_ci    0,                          /*tp_itemsize*/
32647db96d56Sopenharmony_ci    (destructor)textiowrapper_dealloc, /*tp_dealloc*/
32657db96d56Sopenharmony_ci    0,                          /*tp_vectorcall_offset*/
32667db96d56Sopenharmony_ci    0,                          /*tp_getattr*/
32677db96d56Sopenharmony_ci    0,                          /*tps_etattr*/
32687db96d56Sopenharmony_ci    0,                          /*tp_as_async*/
32697db96d56Sopenharmony_ci    (reprfunc)textiowrapper_repr,/*tp_repr*/
32707db96d56Sopenharmony_ci    0,                          /*tp_as_number*/
32717db96d56Sopenharmony_ci    0,                          /*tp_as_sequence*/
32727db96d56Sopenharmony_ci    0,                          /*tp_as_mapping*/
32737db96d56Sopenharmony_ci    0,                          /*tp_hash */
32747db96d56Sopenharmony_ci    0,                          /*tp_call*/
32757db96d56Sopenharmony_ci    0,                          /*tp_str*/
32767db96d56Sopenharmony_ci    0,                          /*tp_getattro*/
32777db96d56Sopenharmony_ci    0,                          /*tp_setattro*/
32787db96d56Sopenharmony_ci    0,                          /*tp_as_buffer*/
32797db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
32807db96d56Sopenharmony_ci        | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
32817db96d56Sopenharmony_ci    _io_TextIOWrapper___init____doc__, /* tp_doc */
32827db96d56Sopenharmony_ci    (traverseproc)textiowrapper_traverse, /* tp_traverse */
32837db96d56Sopenharmony_ci    (inquiry)textiowrapper_clear, /* tp_clear */
32847db96d56Sopenharmony_ci    0,                          /* tp_richcompare */
32857db96d56Sopenharmony_ci    offsetof(textio, weakreflist), /*tp_weaklistoffset*/
32867db96d56Sopenharmony_ci    0,                          /* tp_iter */
32877db96d56Sopenharmony_ci    (iternextfunc)textiowrapper_iternext, /* tp_iternext */
32887db96d56Sopenharmony_ci    textiowrapper_methods,      /* tp_methods */
32897db96d56Sopenharmony_ci    textiowrapper_members,      /* tp_members */
32907db96d56Sopenharmony_ci    textiowrapper_getset,       /* tp_getset */
32917db96d56Sopenharmony_ci    0,                          /* tp_base */
32927db96d56Sopenharmony_ci    0,                          /* tp_dict */
32937db96d56Sopenharmony_ci    0,                          /* tp_descr_get */
32947db96d56Sopenharmony_ci    0,                          /* tp_descr_set */
32957db96d56Sopenharmony_ci    offsetof(textio, dict), /*tp_dictoffset*/
32967db96d56Sopenharmony_ci    _io_TextIOWrapper___init__, /* tp_init */
32977db96d56Sopenharmony_ci    0,                          /* tp_alloc */
32987db96d56Sopenharmony_ci    PyType_GenericNew,          /* tp_new */
32997db96d56Sopenharmony_ci    0,                          /* tp_free */
33007db96d56Sopenharmony_ci    0,                          /* tp_is_gc */
33017db96d56Sopenharmony_ci    0,                          /* tp_bases */
33027db96d56Sopenharmony_ci    0,                          /* tp_mro */
33037db96d56Sopenharmony_ci    0,                          /* tp_cache */
33047db96d56Sopenharmony_ci    0,                          /* tp_subclasses */
33057db96d56Sopenharmony_ci    0,                          /* tp_weaklist */
33067db96d56Sopenharmony_ci    0,                          /* tp_del */
33077db96d56Sopenharmony_ci    0,                          /* tp_version_tag */
33087db96d56Sopenharmony_ci    0,                          /* tp_finalize */
33097db96d56Sopenharmony_ci};
3310