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