14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm An implementation of Text I/O as defined by PEP 3116 - "New I/O" 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper. 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Written by Amaury Forgeot d'Arc and Antoine Pitrou 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/ 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define PY_SSIZE_T_CLEAN 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h" 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "structmember.h" 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "_iomodule.h" 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* TextIOBase */ 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_doc, 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Base class for text I/O.\n" 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "This class provides a character and line based interface to stream\n" 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "I/O. There is no readinto method because Python's character strings\n" 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "are immutable. There is no public constructor.\n" 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_unsupported(const char *message) 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(_PyIO_unsupported_operation, message); 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_detach_doc, 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Separate the underlying buffer from the TextIOBase and return it.\n" 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "After the underlying buffer has been detached, the TextIO is in an\n" 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "unusable state.\n" 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_detach(PyObject *self) 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _unsupported("detach"); 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_read_doc, 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Read at most n characters from stream.\n" 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Read from underlying buffer until we have n characters or we hit EOF.\n" 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "If n is negative or omitted, read until EOF.\n" 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_read(PyObject *self, PyObject *args) 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _unsupported("read"); 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_readline_doc, 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Read until newline or EOF.\n" 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Returns an empty string if EOF is hit immediately.\n" 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_readline(PyObject *self, PyObject *args) 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _unsupported("readline"); 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_write_doc, 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Write string to stream.\n" 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Returns the number of characters written (which is always equal to\n" 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "the length of the string).\n" 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_write(PyObject *self, PyObject *args) 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _unsupported("write"); 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_encoding_doc, 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Encoding of the text stream.\n" 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Subclasses should override.\n" 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_encoding_get(PyObject *self, void *context) 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_newlines_doc, 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Line endings translated so far.\n" 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Only line endings translated during reading are considered.\n" 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Subclasses should override.\n" 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_newlines_get(PyObject *self, void *context) 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiobase_errors_doc, 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "The error setting of the decoder or encoder.\n" 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Subclasses should override.\n" 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiobase_errors_get(PyObject *self, void *context) 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef textiobase_methods[] = { 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"detach", (PyCFunction)textiobase_detach, METH_NOARGS, textiobase_detach_doc}, 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"read", textiobase_read, METH_VARARGS, textiobase_read_doc}, 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc}, 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"write", textiobase_write, METH_VARARGS, textiobase_write_doc}, 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL} 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyGetSetDef textiobase_getset[] = { 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc}, 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc}, 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc}, 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL} 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyTypeObject PyTextIOBase_Type = { 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "_io._TextIOBase", /*tp_name*/ 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_basicsize*/ 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_itemsize*/ 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_dealloc*/ 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_print*/ 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_getattr*/ 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_setattr*/ 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_compare */ 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_repr*/ 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_number*/ 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_sequence*/ 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_mapping*/ 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_hash */ 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_call*/ 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_str*/ 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_getattro*/ 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_setattro*/ 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_buffer*/ 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiobase_doc, /* tp_doc */ 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_traverse */ 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_weaklistoffset */ 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iternext */ 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiobase_methods, /* tp_methods */ 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_members */ 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiobase_getset, /* tp_getset */ 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &PyIOBase_Type, /* tp_base */ 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dictoffset */ 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_init */ 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_new */ 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* IncrementalNewlineDecoder */ 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(incrementalnewlinedecoder_doc, 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Codec used when reading a file in universal newlines mode. It wraps\n" 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "another incremental decoder, translating \\r\\n and \\r into \\n. It also\n" 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "records the types of newlines encountered. When used with\n" 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "translate=False, it ensures that the newline sequence is returned in\n" 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "one piece. When used with decoder=None, it expects unicode strings as\n" 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "decode input and translates newlines without first invoking an external\n" 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "decoder.\n" 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct { 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_HEAD 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoder; 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errors; 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm signed int pendingcr: 1; 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm signed int translate: 1; 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned int seennl: 3; 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} nldecoder_object; 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_init(nldecoder_object *self, 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, PyObject *kwds) 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoder; 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int translate; 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errors = NULL; 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *kwlist[] = {"decoder", "translate", "errors", NULL}; 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|O:IncrementalNewlineDecoder", 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kwlist, &decoder, &translate, &errors)) 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoder = decoder; 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(decoder); 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == NULL) { 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = PyUnicode_FromString("strict"); 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == NULL) 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(errors); 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = errors; 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->translate = translate; 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->seennl = 0; 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingcr = 0; 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_dealloc(nldecoder_object *self) 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoder); 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->errors); 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(self)->tp_free((PyObject *)self); 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SEEN_CR 1 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SEEN_LF 2 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SEEN_CRLF 4 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF) 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject * 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyIncrementalNewlineDecoder_decode(PyObject *_self, 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *input, int final) 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *output; 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t output_len; 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nldecoder_object *self = (nldecoder_object *) _self; 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder == NULL) { 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "IncrementalNewlineDecoder.__init__ not called"); 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* decode input (with the eventual \r from a previous pass) */ 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder != Py_None) { 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = PyObject_CallMethodObjArgs(self->decoder, 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_decode, input, final ? Py_True : Py_False, NULL); 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = input; 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(output); 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (output == NULL) 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyUnicode_Check(output)) { 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "decoder should return a string result"); 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output_len = PyUnicode_GET_SIZE(output); 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pendingcr && (final || output_len > 0)) { 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *out; 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *modified = PyUnicode_FromUnicode(NULL, output_len + 1); 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (modified == NULL) 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out = PyUnicode_AS_UNICODE(modified); 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out[0] = '\r'; 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(out + 1, PyUnicode_AS_UNICODE(output), 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output_len * sizeof(Py_UNICODE)); 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(output); 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = modified; 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingcr = 0; 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output_len++; 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* retain last \r even when not translating data: 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * then readline() is sure to get \r\n in one pass 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!final) { 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (output_len > 0 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm && PyUnicode_AS_UNICODE(output)[output_len - 1] == '\r') { 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (Py_REFCNT(output) == 1) { 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&output, output_len - 1) < 0) 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *modified = PyUnicode_FromUnicode( 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(output), 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output_len - 1); 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (modified == NULL) 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(output); 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = modified; 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingcr = 1; 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Record which newlines are read and do newline translation if desired, 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm all in one pass. */ 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm { 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *in_str; 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t len; 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int seennl = self->seennl; 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int only_lf = 0; 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in_str = PyUnicode_AS_UNICODE(output); 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm len = PyUnicode_GET_SIZE(output); 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (len == 0) 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return output; 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* If, up to now, newlines are consistently \n, do a quick check 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for the \r *byte* with the libc's optimized memchr. 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (seennl == SEEN_LF || seennl == 0) { 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm only_lf = (memchr(in_str, '\r', len * sizeof(Py_UNICODE)) == NULL); 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (only_lf) { 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* If not already seen, quick scan for a possible "\n" character. 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (there's nothing else to be done, even when in translation mode) 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (seennl == 0 && 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memchr(in_str, '\n', len * sizeof(Py_UNICODE)) != NULL) { 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *s, *end; 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = in_str; 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm end = in_str + len; 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE c; 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Fast loop for non-control characters */ 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (*s > '\n') 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c = *s++; 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (c == '\n') { 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_LF; 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (s > end) 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Finished: we have scanned for newlines, and none of them 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm need translating */ 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (!self->translate) { 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *s, *end; 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We have already seen all newline types, no need to scan again */ 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (seennl == SEEN_ALL) 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto endscan; 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = in_str; 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm end = in_str + len; 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE c; 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Fast loop for non-control characters */ 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (*s > '\r') 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c = *s++; 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (c == '\n') 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_LF; 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (c == '\r') { 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (*s == '\n') { 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_CRLF; 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_CR; 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (s > end) 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (seennl == SEEN_ALL) 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endscan: 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ; 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *translated = NULL; 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *out_str; 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *in, *out, *end; 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (Py_REFCNT(output) != 1) { 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We could try to optimize this so that we only do a copy 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm when there is something to translate. On the other hand, 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm most decoders should only output non-shared strings, i.e. 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm translation is done in place. */ 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm translated = PyUnicode_FromUnicode(NULL, len); 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (translated == NULL) 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(Py_REFCNT(translated) == 1); 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(PyUnicode_AS_UNICODE(translated), 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(output), 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm len * sizeof(Py_UNICODE)); 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm translated = output; 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out_str = PyUnicode_AS_UNICODE(translated); 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in = in_str; 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm out = out_str; 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm end = in_str + len; 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE c; 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Fast loop for non-control characters */ 4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while ((c = *in++) > '\r') 4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *out++ = c; 4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (c == '\n') { 4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *out++ = c; 4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_LF; 4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm continue; 4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (c == '\r') { 4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (*in == '\n') { 4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in++; 4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_CRLF; 4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm seennl |= SEEN_CR; 4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *out++ = '\n'; 4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm continue; 4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (in > end) 4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *out++ = c; 4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (translated != output) { 4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(output); 4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm output = translated; 4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (out - out_str != len) { 4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&output, out - out_str) < 0) 4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->seennl |= seennl; 4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return output; 4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm error: 4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(output); 4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_decode(nldecoder_object *self, 4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, PyObject *kwds) 4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *kwlist[] = {"input", "final", NULL}; 4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *input; 4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int final = 0; 4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder", 4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kwlist, &input, &final)) 4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); 4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_getstate(nldecoder_object *self, PyObject *args) 4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *buffer; 4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned PY_LONG_LONG flag; 4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder != Py_None) { 4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *state = PyObject_CallMethodObjArgs(self->decoder, 4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_getstate, NULL); 4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (state == NULL) 4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) { 4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(state); 4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(buffer); 4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(state); 4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buffer = PyBytes_FromString(""); 4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flag = 0; 4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flag <<= 1; 4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pendingcr) 5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flag |= 1; 5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Py_BuildValue("NK", buffer, flag); 5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state) 5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *buffer; 5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned PY_LONG_LONG flag; 5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) 5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingcr = (int) flag & 1; 5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm flag >>= 1; 5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder != Py_None) 5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->decoder, 5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "setstate", "((OK))", buffer, flag); 5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_reset(nldecoder_object *self, PyObject *args) 5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->seennl = 0; 5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingcr = 0; 5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder != Py_None) 5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); 5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmincrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) 5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm switch (self->seennl) { 5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_CR: 5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_FromString("\r"); 5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_LF: 5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_FromString("\n"); 5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_CRLF: 5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_FromString("\r\n"); 5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_CR | SEEN_LF: 5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Py_BuildValue("ss", "\r", "\n"); 5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_CR | SEEN_CRLF: 5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Py_BuildValue("ss", "\r", "\r\n"); 5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_LF | SEEN_CRLF: 5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Py_BuildValue("ss", "\n", "\r\n"); 5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case SEEN_CR | SEEN_LF | SEEN_CRLF: 5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Py_BuildValue("sss", "\r", "\n", "\r\n"); 5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default: 5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef incrementalnewlinedecoder_methods[] = { 5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"decode", (PyCFunction)incrementalnewlinedecoder_decode, METH_VARARGS|METH_KEYWORDS}, 5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"getstate", (PyCFunction)incrementalnewlinedecoder_getstate, METH_NOARGS}, 5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"setstate", (PyCFunction)incrementalnewlinedecoder_setstate, METH_O}, 5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"reset", (PyCFunction)incrementalnewlinedecoder_reset, METH_NOARGS}, 5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL} 5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyGetSetDef incrementalnewlinedecoder_getset[] = { 5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL}, 5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL} 5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyTypeObject PyIncrementalNewlineDecoder_Type = { 5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "_io.IncrementalNewlineDecoder", /*tp_name*/ 5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(nldecoder_object), /*tp_basicsize*/ 5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_itemsize*/ 5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/ 5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_print*/ 5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_getattr*/ 5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_setattr*/ 5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_compare */ 5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_repr*/ 5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_number*/ 5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_sequence*/ 5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_mapping*/ 5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_hash */ 5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_call*/ 5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_str*/ 5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_getattro*/ 5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_setattro*/ 5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_buffer*/ 5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incrementalnewlinedecoder_doc, /* tp_doc */ 5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_traverse */ 5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_weaklistoffset*/ 5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iternext */ 6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incrementalnewlinedecoder_methods, /* tp_methods */ 6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_members */ 6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incrementalnewlinedecoder_getset, /* tp_getset */ 6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_base */ 6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dictoffset */ 6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (initproc)incrementalnewlinedecoder_init, /* tp_init */ 6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyType_GenericNew, /* tp_new */ 6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* TextIOWrapper */ 6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(textiowrapper_doc, 6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Character and line based layer over a BufferedIOBase object, buffer.\n" 6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "encoding gives the name of the encoding that the stream will be\n" 6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "decoded or encoded with. It defaults to locale.getpreferredencoding.\n" 6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "errors determines the strictness of encoding and decoding (see the\n" 6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "codecs.register) and defaults to \"strict\".\n" 6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "newline can be None, '', '\\n', '\\r', or '\\r\\n'. It controls the\n" 6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "handling of line endings. If it is None, universal newlines is\n" 6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "enabled. With this enabled, on input, the lines endings '\\n', '\\r',\n" 6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "or '\\r\\n' are translated to '\\n' before being returned to the\n" 6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "caller. Conversely, on output, '\\n' is translated to the system\n" 6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "default line seperator, os.linesep. If newline is any other of its\n" 6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "legal values, that newline becomes the newline when the file is read\n" 6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "and it is returned untranslated. On output, '\\n' is converted to the\n" 6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "newline.\n" 6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "\n" 6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "If line_buffering is True, a call to flush is implied when a call to\n" 6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "write contains a newline character." 6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ); 6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef PyObject * 6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (*encodefunc_t)(PyObject *, PyObject *); 6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct 6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_HEAD 6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int ok; /* initialized? */ 6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int detached; 6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t chunk_size; 6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *buffer; 6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *encoding; 6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *encoder; 6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoder; 6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *readnl; 6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errors; 6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *writenl; /* utf-8 encoded, NULL stands for \n */ 6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char line_buffering; 6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char readuniversal; 6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char readtranslate; 6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char writetranslate; 6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char seekable; 6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char telling; 6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Specialized encoding func (see below) */ 6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encodefunc_t encodefunc; 6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Whether or not it's the start of the stream */ 6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char encoding_start_of_stream; 6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Reads and writes are internally buffered in order to speed things up. 6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm However, any read will first flush the write buffer if itsn't empty. 6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Please also note that text to be written is first encoded before being 6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buffered. This is necessary so that encoding errors are immediately 6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reported to the caller, but it unfortunately means that the 6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm IncrementalEncoder (whose encode() method is always written in Python) 6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm becomes a bottleneck for small writes. 6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoded_chars; /* buffer for text returned from decoder */ 6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */ 6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *pending_bytes; /* list of bytes objects waiting to be 6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm written, or NULL */ 6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t pending_bytes_count; 6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *snapshot; 6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* snapshot is either None, or a tuple (dec_flags, next_input) where 6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * dec_flags is the second (integer) item of the decoder state and 6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * next_input is the chunk of input bytes that comes next after the 6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * snapshot point. We use this to reconstruct decoder states in tell(). 6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Cache raw object if it's a FileIO object */ 6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *raw; 6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *weakreflist; 6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *dict; 6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} textio; 6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* A couple of specialized cases in order to bypass the slow incremental 6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding methods for the most popular encodings. */ 6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmascii_encode(textio *self, PyObject *text) 7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(text), 7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors)); 7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf16be_encode(textio *self, PyObject *text) 7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), 7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors), 1); 7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf16le_encode(textio *self, PyObject *text) 7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), 7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors), -1); 7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf16_encode(textio *self, PyObject *text) 7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!self->encoding_start_of_stream) { 7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Skip the BOM and use native byte ordering */ 7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(WORDS_BIGENDIAN) 7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return utf16be_encode(self, text); 7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else 7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return utf16le_encode(self, text); 7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), 7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors), 0); 7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf32be_encode(textio *self, PyObject *text) 7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text), 7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors), 1); 7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf32le_encode(textio *self, PyObject *text) 7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text), 7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors), -1); 7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf32_encode(textio *self, PyObject *text) 7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!self->encoding_start_of_stream) { 7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Skip the BOM and use native byte ordering */ 7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(WORDS_BIGENDIAN) 7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return utf32be_encode(self, text); 7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else 7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return utf32le_encode(self, text); 7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text), 7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors), 0); 7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmutf8_encode(textio *self, PyObject *text) 7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(text), 7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors)); 7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmlatin1_encode(textio *self, PyObject *text) 7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(text), 7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), 7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBytes_AS_STRING(self->errors)); 7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Map normalized encoding names onto the specialized encoding funcs */ 7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct { 7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *name; 7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encodefunc_t encodefunc; 7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} encodefuncentry; 7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic encodefuncentry encodefuncs[] = { 7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"ascii", (encodefunc_t) ascii_encode}, 7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"iso8859-1", (encodefunc_t) latin1_encode}, 7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-8", (encodefunc_t) utf8_encode}, 7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-16-be", (encodefunc_t) utf16be_encode}, 7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-16-le", (encodefunc_t) utf16le_encode}, 7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-16", (encodefunc_t) utf16_encode}, 8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-32-be", (encodefunc_t) utf32be_encode}, 8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-32-le", (encodefunc_t) utf32le_encode}, 8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"utf-32", (encodefunc_t) utf32_encode}, 8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL} 8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_init(textio *self, PyObject *args, PyObject *kwds) 8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *kwlist[] = {"buffer", "encoding", "errors", 8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "newline", "line_buffering", 8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NULL}; 8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *buffer, *raw; 8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *encoding = NULL; 8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *errors = NULL; 8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *newline = NULL; 8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int line_buffering = 0; 8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int r; 8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->ok = 0; 8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->detached = 0; 8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio", 8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm kwlist, &buffer, &encoding, &errors, 8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &newline, &line_buffering)) 8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newline && newline[0] != '\0' 8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm && !(newline[0] == '\n' && newline[1] == '\0') 8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm && !(newline[0] == '\r' && newline[1] == '\0') 8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { 8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_ValueError, 8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "illegal newline value: %s", newline); 8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->buffer); 8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->encoding); 8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->encoder); 8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoder); 8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->readnl); 8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoded_chars); 8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->pending_bytes); 8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->errors); 8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->raw); 8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoded_chars_used = 0; 8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pending_bytes_count = 0; 8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encodefunc = NULL; 8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->writenl = NULL; 8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (encoding == NULL && self->encoding == NULL) { 8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_PyIO_locale_module == NULL) { 8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_locale_module = PyImport_ImportModule("locale"); 8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_PyIO_locale_module == NULL) 8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto catch_ImportError; 8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto use_locale; 8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm use_locale: 8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding = PyObject_CallMethod( 8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_locale_module, "getpreferredencoding", NULL); 8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encoding == NULL) { 8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm catch_ImportError: 8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* 8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Importing locale can raise a ImportError because of 8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _functools, and locale.getpreferredencoding can raise a 8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ImportError if _locale is not available. These will happen 8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm during module building. 8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_ExceptionMatches(PyExc_ImportError)) { 8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding = PyString_FromString("ascii"); 8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (!PyString_Check(self->encoding)) 8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->encoding); 8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encoding != NULL) 8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding = PyString_AsString(self->encoding); 8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (encoding != NULL) { 8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding = PyString_FromString(encoding); 8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encoding == NULL) 8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "could not determine default encoding"); 8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == NULL) 8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm errors = "strict"; 8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = PyBytes_FromString(errors); 8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == NULL) 9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->chunk_size = 8192; 9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->readuniversal = (newline == NULL || newline[0] == '\0'); 9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->line_buffering = line_buffering; 9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->readtranslate = (newline == NULL); 9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newline) { 9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->readnl = PyString_FromString(newline); 9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->readnl == NULL) 9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->writetranslate = (newline == NULL || newline[0] != '\0'); 9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!self->readuniversal && self->writetranslate) { 9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->writenl = PyString_AsString(self->readnl); 9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!strcmp(self->writenl, "\n")) 9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->writenl = NULL; 9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_WINDOWS 9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->writenl = "\r\n"; 9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Build the decoder object */ 9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(buffer, "readable", NULL); 9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = PyObject_IsTrue(res); 9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == -1) 9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == 1) { 9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoder = PyCodec_IncrementalDecoder( 9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding, errors); 9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder == NULL) 9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->readuniversal) { 9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *incrementalDecoder = PyObject_CallFunction( 9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (PyObject *)&PyIncrementalNewlineDecoder_Type, 9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Oi", self->decoder, (int)self->readtranslate); 9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (incrementalDecoder == NULL) 9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoder); 9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoder = incrementalDecoder; 9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Build the encoder object */ 9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(buffer, "writable", NULL); 9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = PyObject_IsTrue(res); 9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == -1) 9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == 1) { 9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *ci; 9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoder = PyCodec_IncrementalEncoder( 9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding, errors); 9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encoder == NULL) 9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Get the normalized named of the codec */ 9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ci = _PyCodec_Lookup(encoding); 9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ci == NULL) 9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_GetAttrString(ci, "name"); 9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(ci); 9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) { 9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_ExceptionMatches(PyExc_AttributeError)) 9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (PyString_Check(res)) { 9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encodefuncentry *e = encodefuncs; 9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (e->name != NULL) { 9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!strcmp(PyString_AS_STRING(res), e->name)) { 9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encodefunc = e->encodefunc; 9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm e++; 9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(res); 9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->buffer = buffer; 9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(buffer); 9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (Py_TYPE(buffer) == &PyBufferedReader_Type || 9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(buffer) == &PyBufferedWriter_Type || 9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(buffer) == &PyBufferedRandom_Type) { 9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raw = PyObject_GetAttrString(buffer, "raw"); 9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Cache the raw FileIO object to speed up 'closed' checks */ 9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (raw == NULL) { 9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_ExceptionMatches(PyExc_AttributeError)) 9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (Py_TYPE(raw) == &PyFileIO_Type) 10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->raw = raw; 10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(raw); 10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(buffer, "seekable", NULL); 10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->seekable = self->telling = PyObject_IsTrue(res); 10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding_start_of_stream = 0; 10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->seekable && self->encoder) { 10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *cookieObj; 10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int cmp; 10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding_start_of_stream = 1; 10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookieObj = PyObject_CallMethodObjArgs(buffer, _PyIO_str_tell, NULL); 10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cookieObj == NULL) 10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ); 10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cookieObj); 10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp < 0) { 10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp == 0) { 10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding_start_of_stream = 0; 10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate, 10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_zero, NULL); 10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->ok = 1; 10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm error: 10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_textiowrapper_clear(textio *self) 10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) 10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->ok = 0; 10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->buffer); 10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->encoding); 10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->encoder); 10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoder); 10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->readnl); 10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoded_chars); 10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->pending_bytes); 10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->errors); 10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->raw); 10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_dealloc(textio *self) 10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_clear(self) < 0) 10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return; 10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyObject_GC_UNTRACK(self); 10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->weakreflist != NULL) 10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_ClearWeakRefs((PyObject *)self); 10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->dict); 10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(self)->tp_free((PyObject *)self); 10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_traverse(textio *self, visitproc visit, void *arg) 10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->buffer); 10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->encoding); 10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->encoder); 10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->decoder); 10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->readnl); 10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->decoded_chars); 10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->pending_bytes); 10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->snapshot); 10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->errors); 10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->raw); 10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->dict); 10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_clear(textio *self) 10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_clear(self) < 0) 10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->dict); 11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_closed_get(textio *self, void *context); 11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* This macro takes some shortcuts to make the common case faster. */ 11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define CHECK_CLOSED(self) \ 11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm do { \ 11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int r; \ 11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *_res; \ 11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \ 11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->raw != NULL) \ 11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = _PyFileIO_closed(self->raw); \ 11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { \ 11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _res = textiowrapper_closed_get(self, NULL); \ 11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_res == NULL) \ 11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; \ 11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = PyObject_IsTrue(_res); \ 11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(_res); \ 11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r < 0) \ 11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; \ 11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } \ 11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r > 0) { \ 11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, \ 11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "I/O operation on closed file."); \ 11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; \ 11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } \ 11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } \ 11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \ 11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; \ 11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } while (0) 11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define CHECK_INITIALIZED(self) \ 11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->ok <= 0) { \ 11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->detached) { \ 11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, \ 11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "underlying buffer has been detached"); \ 11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } else { \ 11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, \ 11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "I/O operation on uninitialized object"); \ 11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } \ 11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; \ 11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define CHECK_INITIALIZED_INT(self) \ 11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->ok <= 0) { \ 11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->detached) { \ 11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, \ 11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "underlying buffer has been detached"); \ 11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } else { \ 11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, \ 11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "I/O operation on uninitialized object"); \ 11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } \ 11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; \ 11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_detach(textio *self) 11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *buffer, *res; 11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); 11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buffer = self->buffer; 11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->buffer = NULL; 11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->detached = 1; 11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->ok = 0; 11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return buffer; 11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPy_LOCAL_INLINE(const Py_UNICODE *) 11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfindchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch) 11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* like wcschr, but doesn't stop at NULL characters */ 11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (size-- > 0) { 11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (*s == ch) 11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return s; 11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Flush the internal write buffer. This doesn't explicitly flush the 11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm underlying buffered object, though. */ 11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_textiowrapper_writeflush(textio *self) 11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *pending, *b, *ret; 11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pending_bytes == NULL) 11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pending = self->pending_bytes; 11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(pending); 11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pending_bytes_count = 0; 12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->pending_bytes); 12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm b = _PyBytes_Join(_PyIO_empty_bytes, pending); 12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(pending); 12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (b == NULL) 12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ret = PyObject_CallMethodObjArgs(self->buffer, 12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_write, b, NULL); 12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(b); 12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ret == NULL) 12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(ret); 12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_write(textio *self, PyObject *args) 12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *ret; 12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *text; /* owned reference */ 12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *b; 12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t textlen; 12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int haslf = 0; 12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int needflush = 0; 12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTuple(args, "U:write", &text)) { 12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_CLOSED(self); 12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encoder == NULL) { 12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, "not writable"); 12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(text); 12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textlen = PyUnicode_GetSize(text); 12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((self->writetranslate && self->writenl != NULL) || self->line_buffering) 12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (findchar(PyUnicode_AS_UNICODE(text), 12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), '\n')) 12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm haslf = 1; 12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (haslf && self->writetranslate && self->writenl != NULL) { 12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *newtext = PyObject_CallMethod( 12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm text, "replace", "ss", "\n", self->writenl); 12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(text); 12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newtext == NULL) 12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm text = newtext; 12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->line_buffering && 12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (haslf || 12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm findchar(PyUnicode_AS_UNICODE(text), 12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(text), '\r'))) 12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm needflush = 1; 12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* XXX What if we were just reading? */ 12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encodefunc != NULL) { 12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm b = (*self->encodefunc)((PyObject *) self, text); 12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding_start_of_stream = 0; 12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm b = PyObject_CallMethodObjArgs(self->encoder, 12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_encode, text, NULL); 12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(text); 12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (b == NULL) 12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pending_bytes == NULL) { 12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pending_bytes = PyList_New(0); 12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pending_bytes == NULL) { 12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(b); 12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pending_bytes_count = 0; 12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyList_Append(self->pending_bytes, b) < 0) { 12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(b); 12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pending_bytes_count += PyBytes_GET_SIZE(b); 12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(b); 12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pending_bytes_count > self->chunk_size || needflush) { 12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_writeflush(self) < 0) 12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (needflush) { 12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL); 12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ret == NULL) 12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(ret); 12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder) { 13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ret = PyObject_CallMethod(self->decoder, "reset", NULL); 13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ret == NULL) 13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(ret); 13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyLong_FromSsize_t(textlen); 13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Steal a reference to chars and store it in the decoded_char buffer; 13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_set_decoded_chars(textio *self, PyObject *chars) 13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->decoded_chars); 13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoded_chars = chars; 13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoded_chars_used = 0; 13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_get_decoded_chars(textio *self, Py_ssize_t n) 13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *chars; 13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t avail; 13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoded_chars == NULL) 13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_FromStringAndSize(NULL, 0); 13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm avail = (PyUnicode_GET_SIZE(self->decoded_chars) 13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm - self->decoded_chars_used); 13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(avail >= 0); 13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (n < 0 || n > avail) 13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = avail; 13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoded_chars_used > 0 || n < avail) { 13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars = PyUnicode_FromUnicode( 13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(self->decoded_chars) 13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm + self->decoded_chars_used, n); 13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chars == NULL) 13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars = self->decoded_chars; 13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(chars); 13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoded_chars_used += n; 13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return chars; 13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Read and decode the next chunk of data from the BufferedReader. 13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_read_chunk(textio *self) 13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *dec_buffer = NULL; 13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *dec_flags = NULL; 13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *input_chunk = NULL; 13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoded_chars, *chunk_size; 13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int eof; 13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* The return value is True unless EOF was reached. The decoded string is 13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * placed in self._decoded_chars (replacing its previous value). The 13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * entire input chunk is sent to the decoder, though some of it may remain 13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * buffered in the decoder, yet to be converted. 13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder == NULL) { 13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, "not readable"); 13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->telling) { 13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* To prepare for tell(), we need to snapshot a point in the file 13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * where the decoder's input buffer is empty. 13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *state = PyObject_CallMethodObjArgs(self->decoder, 13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_getstate, NULL); 13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (state == NULL) 13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Given this, we know there was a valid snapshot point 13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * len(dec_buffer) bytes ago with decoder state (b'', dec_flags). 13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) { 13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(state); 13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 13924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(dec_buffer); 13944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(dec_flags); 13954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(state); 13964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Read a chunk, decode it, and put the result in self._decoded_chars. */ 13994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunk_size = PyLong_FromSsize_t(self->chunk_size); 14004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunk_size == NULL) 14014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm input_chunk = PyObject_CallMethodObjArgs(self->buffer, 14034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_read1, chunk_size, NULL); 14044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(chunk_size); 14054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (input_chunk == NULL) 14064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(PyBytes_Check(input_chunk)); 14084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm eof = (PyBytes_Size(input_chunk) == 0); 14104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) { 14124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm decoded_chars = _PyIncrementalNewlineDecoder_decode( 14134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoder, input_chunk, eof); 14144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 14164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm decoded_chars = PyObject_CallMethodObjArgs(self->decoder, 14174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL); 14184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* TODO sanity check: isinstance(decoded_chars, unicode) */ 14214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoded_chars == NULL) 14224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_set_decoded_chars(self, decoded_chars); 14244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_GET_SIZE(decoded_chars) > 0) 14254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm eof = 0; 14264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->telling) { 14284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* At the snapshot point, len(dec_buffer) bytes before the read, the 14294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * next input to be decoded is dec_buffer + input_chunk. 14304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 14314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk); 14324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (next_input == NULL) 14334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert (PyBytes_Check(next_input)); 14354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(dec_buffer); 14364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 14374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->snapshot = Py_BuildValue("NN", dec_flags, next_input); 14384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(input_chunk); 14404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (eof == 0); 14424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fail: 14444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(dec_buffer); 14454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(dec_flags); 14464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(input_chunk); 14474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 14484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 14494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 14514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_read(textio *self, PyObject *args) 14524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 14534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t n = -1; 14544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *result = NULL, *chunks = NULL; 14554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 14574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) 14594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_CLOSED(self); 14624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder == NULL) { 14644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, "not readable"); 14654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_writeflush(self) < 0) 14694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (n < 0) { 14724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Read everything */ 14734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL); 14744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoded, *final; 14754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (bytes == NULL) 14764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode, 14784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bytes, Py_True, NULL); 14794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(bytes); 14804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoded == NULL) 14814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = textiowrapper_get_decoded_chars(self, -1); 14844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (result == NULL) { 14864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(decoded); 14874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm final = PyUnicode_Concat(result, decoded); 14914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(result); 14924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(decoded); 14934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (final == NULL) 14944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 14954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 14974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return final; 14984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 15004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int res = 1; 15014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t remaining = n; 15024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = textiowrapper_get_decoded_chars(self, n); 15044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (result == NULL) 15054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm remaining -= PyUnicode_GET_SIZE(result); 15074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Keep reading chunks until we have n characters to return */ 15094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (remaining > 0) { 15104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = textiowrapper_read_chunk(self); 15114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res < 0) 15124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == 0) /* EOF */ 15144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 15154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks == NULL) { 15164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunks = PyList_New(0); 15174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks == NULL) 15184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyList_Append(chunks, result) < 0) 15214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(result); 15234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = textiowrapper_get_decoded_chars(self, remaining); 15244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (result == NULL) 15254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm remaining -= PyUnicode_GET_SIZE(result); 15274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks != NULL) { 15294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (result != NULL && PyList_Append(chunks, result) < 0) 15304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(result); 15324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = PyUnicode_Join(_PyIO_empty_str, chunks); 15334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (result == NULL) 15344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 15354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(chunks); 15364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return result; 15384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fail: 15404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(result); 15414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(chunks); 15424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 15434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 15444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* NOTE: `end` must point to the real end of the Py_UNICODE storage, 15474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm that is to the NUL character. Otherwise the function will produce 15484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incorrect results. */ 15494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic Py_UNICODE * 15504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfind_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch) 15514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 15524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *s = start; 15534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 15544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (*s > ch) 15554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 15564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (*s == ch) 15574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return s; 15584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (s == end) 15594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 15604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 15614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 15634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPy_ssize_t 15654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyIO_find_line_ending( 15664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int translated, int universal, PyObject *readnl, 15674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed) 15684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 15694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t len = end - start; 15704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (translated) { 15724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Newlines are already translated, only search for \n */ 15734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *pos = find_control_char(start, end, '\n'); 15744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (pos != NULL) 15754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return pos - start + 1; 15764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 15774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *consumed = len; 15784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 15794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (universal) { 15824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Universal newline search. Find any of \r, \r\n, \n 15834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * The decoder ensures that \r\n are not split in two pieces 15844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 15854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *s = start; 15864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 15874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE ch; 15884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Fast path for non-control chars. The loop always ends 15894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm since the Py_UNICODE storage is NUL-terminated. */ 15904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (*s > '\r') 15914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s++; 15924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (s >= end) { 15934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *consumed = len; 15944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 15954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ch = *s++; 15974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ch == '\n') 15984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return s - start; 15994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ch == '\r') { 16004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (*s == '\n') 16014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return s - start + 1; 16024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 16034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return s - start; 16044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 16084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Non-universal mode. */ 16094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t readnl_len = PyString_GET_SIZE(readnl); 16104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned char *nl = (unsigned char *) PyString_AS_STRING(readnl); 16114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (readnl_len == 1) { 16124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *pos = find_control_char(start, end, nl[0]); 16134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (pos != NULL) 16144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return pos - start + 1; 16154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *consumed = len; 16164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 16174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 16194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *s = start; 16204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *e = end - readnl_len + 1; 16214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *pos; 16224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (e < s) 16234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm e = s; 16244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (s < e) { 16254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t i; 16264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *pos = find_control_char(s, end, nl[0]); 16274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (pos == NULL || pos >= e) 16284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 16294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (i = 1; i < readnl_len; i++) { 16304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (pos[i] != nl[i]) 16314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 16324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (i == readnl_len) 16344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return pos - start + readnl_len; 16354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = pos + 1; 16364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pos = find_control_char(e, end, nl[0]); 16384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (pos == NULL) 16394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *consumed = len; 16404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 16414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *consumed = pos - start; 16424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 16434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 16464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 16484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_textiowrapper_readline(textio *self, Py_ssize_t limit) 16494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 16504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *line = NULL, *chunks = NULL, *remaining = NULL; 16514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t start, endpos, chunked, offset_to_buffer; 16524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int res; 16534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_CLOSED(self); 16554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_writeflush(self) < 0) 16574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunked = 0; 16604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (1) { 16624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *ptr; 16634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t line_len; 16644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t consumed = 0; 16654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* First, get some data if necessary */ 16674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = 1; 16684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (!self->decoded_chars || 16694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm !PyUnicode_GET_SIZE(self->decoded_chars)) { 16704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = textiowrapper_read_chunk(self); 16714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res < 0) 16724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 16734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == 0) 16744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 16754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == 0) { 16774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* end of file */ 16784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_set_decoded_chars(self, NULL); 16794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 16804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start = endpos = offset_to_buffer = 0; 16814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 16824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (remaining == NULL) { 16854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = self->decoded_chars; 16864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start = self->decoded_chars_used; 16874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm offset_to_buffer = 0; 16884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(line); 16894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 16914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(self->decoded_chars_used == 0); 16924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = PyUnicode_Concat(remaining, self->decoded_chars); 16934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start = 0; 16944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm offset_to_buffer = PyUnicode_GET_SIZE(remaining); 16954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(remaining); 16964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line == NULL) 16974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 16984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ptr = PyUnicode_AS_UNICODE(line); 17014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line_len = PyUnicode_GET_SIZE(line); 17024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endpos = _PyIO_find_line_ending( 17044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->readtranslate, self->readuniversal, self->readnl, 17054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ptr + start, ptr + line_len, &consumed); 17064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (endpos >= 0) { 17074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endpos += start; 17084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (limit >= 0 && (endpos - start) + chunked >= limit) 17094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endpos = start + limit - chunked; 17104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 17114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We can put aside up to `endpos` */ 17144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endpos = consumed + start; 17154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (limit >= 0 && (endpos - start) + chunked >= limit) { 17164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Didn't find line ending, but reached length limit */ 17174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endpos = start + limit - chunked; 17184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 17194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (endpos > start) { 17224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* No line ending seen yet - put aside current data */ 17234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *s; 17244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks == NULL) { 17254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunks = PyList_New(0); 17264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks == NULL) 17274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = PyUnicode_FromUnicode(ptr + start, endpos - start); 17304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (s == NULL) 17314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyList_Append(chunks, s) < 0) { 17334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(s); 17344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunked += PyUnicode_GET_SIZE(s); 17374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(s); 17384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* There may be some remaining bytes we'll have to prepend to the 17404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm next chunk of data */ 17414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (endpos < line_len) { 17424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm remaining = PyUnicode_FromUnicode( 17434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ptr + endpos, line_len - endpos); 17444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (remaining == NULL) 17454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(line); 17484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We have consumed the buffer */ 17494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_set_decoded_chars(self, NULL); 17504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line != NULL) { 17534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Our line ends in the current buffer */ 17544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoded_chars_used = endpos - offset_to_buffer; 17554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) { 17564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (start == 0 && Py_REFCNT(line) == 1) { 17574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&line, endpos) < 0) 17584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 17614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *s = PyUnicode_FromUnicode( 17624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(line) + start, endpos - start); 17634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(line); 17644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (s == NULL) 17654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = s; 17674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (remaining != NULL) { 17714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks == NULL) { 17724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunks = PyList_New(0); 17734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks == NULL) 17744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyList_Append(chunks, remaining) < 0) 17774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(remaining); 17794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chunks != NULL) { 17814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line != NULL && PyList_Append(chunks, line) < 0) 17824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(line); 17844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = PyUnicode_Join(_PyIO_empty_str, chunks); 17854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line == NULL) 17864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 17874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(chunks); 17884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line == NULL) 17904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = PyUnicode_FromStringAndSize(NULL, 0); 17914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return line; 17934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm error: 17954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(chunks); 17964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(remaining); 17974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(line); 17984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 17994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 18004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 18024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_readline(textio *self, PyObject *args) 18034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 18044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *limitobj = NULL; 18054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t limit = -1; 18064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 18084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTuple(args, "|O:readline", &limitobj)) { 18094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 18104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 18114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (limitobj) { 18124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyNumber_Check(limitobj)) { 18134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_TypeError, 18144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "integer argument expected, got '%.200s'", 18154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(limitobj)->tp_name); 18164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 18174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 18184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm limit = PyNumber_AsSsize_t(limitobj, PyExc_OverflowError); 18194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (limit == -1 && PyErr_Occurred()) 18204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 18214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 18224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _textiowrapper_readline(self, limit); 18234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 18244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Seek and Tell */ 18264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct { 18284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_off_t start_pos; 18294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int dec_flags; 18304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int bytes_to_feed; 18314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int chars_to_skip; 18324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char need_eof; 18334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} cookie_type; 18344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* 18364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm To speed up cookie packing/unpacking, we store the fields in a temporary 18374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.). 18384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The following macros define at which offsets in the intermediary byte 18394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm string the various CookieStruct fields will be stored. 18404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 18414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char)) 18434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(WORDS_BIGENDIAN) 18454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define IS_LITTLE_ENDIAN 0 18474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* We want the least significant byte of start_pos to also be the least 18494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm significant byte of the cookie, which means that in big-endian mode we 18504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm must copy the fields in reverse order. */ 18514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_START_POS (sizeof(char) + 3 * sizeof(int)) 18534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int)) 18544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int)) 18554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_CHARS_TO_SKIP (sizeof(char)) 18564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_NEED_EOF 0 18574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else 18594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define IS_LITTLE_ENDIAN 1 18614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Little-endian mode: the least significant byte of start_pos will 18634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm naturally end up the least significant byte of the cookie. */ 18644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_START_POS 0 18664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_DEC_FLAGS (sizeof(Py_off_t)) 18674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int)) 18684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int)) 18694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int)) 18704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 18724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 18744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj) 18754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 18764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned char buffer[COOKIE_BUF_LEN]; 18774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj); 18784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cookieLong == NULL) 18794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 18804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer), 18824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm IS_LITTLE_ENDIAN, 0) < 0) { 18834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cookieLong); 18844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 18854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 18864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cookieLong); 18874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos)); 18894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags)); 18904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed)); 18914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip)); 18924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof)); 18934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 18954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 18964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 18984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_build_cookie(cookie_type *cookie) 18994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 19004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned char buffer[COOKIE_BUF_LEN]; 19014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos)); 19034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags)); 19044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed)); 19054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip)); 19064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof)); 19074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0); 19094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 19104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef IS_LITTLE_ENDIAN 19114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 19134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) 19144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 19154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 19164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* When seeking to the start of the stream, we call decoder.reset() 19174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rather than decoder.getstate(). 19184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This is for a few decoders such as utf-16 for which the state value 19194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of 19204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm utf-16, that we are expecting a BOM). 19214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 19224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cookie->start_pos == 0 && cookie->dec_flags == 0) 19234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); 19244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 19254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(self->decoder, "setstate", 19264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "((si))", "", cookie->dec_flags); 19274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 19284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 19294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 19304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 19314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 19324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 19344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) 19354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 19364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 19374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Same as _textiowrapper_decoder_setstate() above. */ 19384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cookie->start_pos == 0 && cookie->dec_flags == 0) { 19394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL); 19404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding_start_of_stream = 1; 19414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 19424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 19434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate, 19444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_zero, NULL); 19454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->encoding_start_of_stream = 0; 19464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 19474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 19484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 19494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 19504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 19514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 19524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 19544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_seek(textio *self, PyObject *args) 19554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 19564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *cookieObj, *posobj; 19574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie_type cookie; 19584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int whence = 0; 19594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 19604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int cmp; 19614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 19634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence)) 19654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 19664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_CLOSED(self); 19674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(cookieObj); 19694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!self->seekable) { 19714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 19724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "underlying stream is not seekable"); 19734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 19744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 19754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (whence == 1) { 19774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* seek relative to current position */ 19784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ); 19794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp < 0) 19804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 19814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp == 0) { 19834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 19844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "can't do nonzero cur-relative seeks"); 19854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 19864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 19874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Seeking to the current position should attempt to 19894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * sync the underlying buffer with the current position. 19904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 19914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cookieObj); 19924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL); 19934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cookieObj == NULL) 19944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 19954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 19964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (whence == 2) { 19974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* seek relative to end of file */ 19984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 19994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ); 20004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp < 0) 20014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp == 0) { 20044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 20054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "can't do nonzero end-relative seeks"); 20064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod((PyObject *)self, "flush", NULL); 20104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 20114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 20134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_set_decoded_chars(self, NULL); 20154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 20164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder) { 20174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(self->decoder, "reset", NULL); 20184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 20194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 20214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2); 20244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(cookieObj); 20254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return res; 20264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (whence != 0) { 20284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_ValueError, 20294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "invalid whence (%d, should be 0, 1 or 2)", whence); 20304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_LT); 20344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp < 0) 20354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cmp == 1) { 20384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *repr = PyObject_Repr(cookieObj); 20394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (repr != NULL) { 20404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_ValueError, 20414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "negative seek position %s", 20424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(repr)); 20434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(repr); 20444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); 20494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 20504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 20524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* The strategy of seek() is to go back to the safe start point 20544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * and replay the effect of read(chars_to_skip) from there. 20554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 20564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0) 20574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Seek back to the safe start point. */ 20604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm posobj = PyLong_FromOff_t(cookie.start_pos); 20614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (posobj == NULL) 20624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs(self->buffer, 20644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_seek, posobj, NULL); 20654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(posobj); 20664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 20674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 20694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_set_decoded_chars(self, NULL); 20714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 20724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Restore the decoder to its state from the safe start point. */ 20744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder) { 20754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_decoder_setstate(self, &cookie) < 0) 20764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cookie.chars_to_skip) { 20804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Just like _read_chunk, feed the decoder and save a snapshot. */ 20814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *input_chunk = PyObject_CallMethod( 20824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->buffer, "read", "i", cookie.bytes_to_feed); 20834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoded; 20844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (input_chunk == NULL) 20864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert (PyBytes_Check(input_chunk)); 20894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); 20914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->snapshot == NULL) { 20924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(input_chunk); 20934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 20944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 20954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm decoded = PyObject_CallMethod(self->decoder, "decode", 20974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Oi", input_chunk, (int)cookie.need_eof); 20984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 20994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoded == NULL) 21004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_set_decoded_chars(self, decoded); 21034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Skip chars_to_skip of the decoded characters. */ 21054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) { 21064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, "can't restore logical file position"); 21074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoded_chars_used = cookie.chars_to_skip; 21104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 21124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->snapshot = Py_BuildValue("is", cookie.dec_flags, ""); 21134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->snapshot == NULL) 21144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Finally, reset the encoder (merely useful for proper BOM handling) */ 21184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->encoder) { 21194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_encoder_setstate(self, &cookie) < 0) 21204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return cookieObj; 21234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fail: 21244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(cookieObj); 21254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 21264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 21284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 21304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_tell(textio *self, PyObject *args) 21314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 21324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 21334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *posobj = NULL; 21344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie_type cookie = {0,0,0,0,0}; 21354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *next_input; 21364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t chars_to_skip, chars_decoded; 21374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *saved_state = NULL; 21384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *input, *input_end; 21394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 21414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_CLOSED(self); 21424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!self->seekable) { 21444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 21454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "underlying stream is not seekable"); 21464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!self->telling) { 21494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 21504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "telling position disabled by next() call"); 21514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_writeflush(self) < 0) 21554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 21564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod((PyObject *)self, "flush", NULL); 21574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 21584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 21604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm posobj = PyObject_CallMethod(self->buffer, "tell", NULL); 21624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (posobj == NULL) 21634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder == NULL || self->snapshot == NULL) { 21664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0); 21674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return posobj; 21684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(HAVE_LARGEFILE_SUPPORT) 21714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.start_pos = PyLong_AsLongLong(posobj); 21724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else 21734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.start_pos = PyLong_AsLong(posobj); 21744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 21754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_Occurred()) 21764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Skip backward to the snapshot point (see _read_chunk). */ 21794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input)) 21804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 21814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert (PyBytes_Check(next_input)); 21834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.start_pos -= PyBytes_GET_SIZE(next_input); 21854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* How many decoded characters have been used up since the snapshot? */ 21874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoded_chars_used == 0) { 21884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We haven't moved from the snapshot point. */ 21894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(posobj); 21904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return textiowrapper_build_cookie(&cookie); 21914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 21924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars_to_skip = self->decoded_chars_used; 21944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 21954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Starting from the snapshot position, we will walk the decoder 21964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * forward until it gives us enough decoded characters. 21974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 21984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm saved_state = PyObject_CallMethodObjArgs(self->decoder, 21994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_getstate, NULL); 22004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (saved_state == NULL) 22014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Note our initial start point. */ 22044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_decoder_setstate(self, &cookie) < 0) 22054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Feed the decoder one byte at a time. As we go, note the 22084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * nearest "safe start point" before the current location 22094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * (a point where the decoder has nothing buffered, so seek() 22104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * can safely start from there and advance to this location). 22114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 22124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars_decoded = 0; 22134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm input = PyBytes_AS_STRING(next_input); 22144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm input_end = input + PyBytes_GET_SIZE(next_input); 22154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (input < input_end) { 22164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *state; 22174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *dec_buffer; 22184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t dec_buffer_len; 22194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int dec_flags; 22204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoded = PyObject_CallMethod( 22224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoder, "decode", "s#", input, 1); 22234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoded == NULL) 22244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert (PyUnicode_Check(decoded)); 22264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars_decoded += PyUnicode_GET_SIZE(decoded); 22274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(decoded); 22284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.bytes_to_feed += 1; 22304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = PyObject_CallMethodObjArgs(self->decoder, 22324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_getstate, NULL); 22334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (state == NULL) 22344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_Parse(state, "(s#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) { 22364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(state); 22374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 22394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(state); 22404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) { 22424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Decoder buffer is empty, so this is a safe start point. */ 22434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.start_pos += cookie.bytes_to_feed; 22444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars_to_skip -= chars_decoded; 22454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.dec_flags = dec_flags; 22464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.bytes_to_feed = 0; 22474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars_decoded = 0; 22484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 22494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chars_decoded >= chars_to_skip) 22504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 22514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm input++; 22524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 22534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (input == input_end) { 22544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We didn't get enough decoded data; signal EOF to get more. */ 22554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *decoded = PyObject_CallMethod( 22564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->decoder, "decode", "si", "", /* final = */ 1); 22574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoded == NULL) 22584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert (PyUnicode_Check(decoded)); 22604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chars_decoded += PyUnicode_GET_SIZE(decoded); 22614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(decoded); 22624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.need_eof = 1; 22634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (chars_decoded < chars_to_skip) { 22654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_IOError, 22664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "can't reconstruct logical file position"); 22674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto fail; 22684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 22694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 22704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* finally */ 22724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(posobj); 22734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); 22744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(saved_state); 22754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 22764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 22774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 22784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* The returned cookie corresponds to the last safe start point. */ 22804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); 22814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return textiowrapper_build_cookie(&cookie); 22824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fail: 22844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(posobj); 22854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (saved_state) { 22864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *type, *value, *traceback; 22874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Fetch(&type, &value, &traceback); 22884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); 22904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(saved_state); 22914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 22924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 22934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 22944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 22954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Restore(type, value, traceback); 22964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 22974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 22984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 22994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_truncate(textio *self, PyObject *args) 23024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *pos = Py_None; 23044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 23054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self) 23074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { 23084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 23094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 23104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); 23124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 23134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 23144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 23154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL); 23174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_repr(textio *self) 23214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *nameobj, *res; 23234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *namerepr = NULL, *encrepr = NULL; 23244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm nameobj = PyObject_GetAttrString((PyObject *) self, "name"); 23284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (nameobj == NULL) { 23294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_ExceptionMatches(PyExc_AttributeError)) 23304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 23314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 23324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto error; 23334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encrepr = PyObject_Repr(self->encoding); 23344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyString_FromFormat("<_io.TextIOWrapper encoding=%s>", 23354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(encrepr)); 23364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 23374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 23384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encrepr = PyObject_Repr(self->encoding); 23394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm namerepr = PyObject_Repr(nameobj); 23404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyString_FromFormat("<_io.TextIOWrapper name=%s encoding=%s>", 23414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(namerepr), 23424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(encrepr)); 23434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(nameobj); 23444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 23454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(namerepr); 23464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(encrepr); 23474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return res; 23484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerror: 23504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(namerepr); 23514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(encrepr); 23524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 23534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Inquiries */ 23574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_fileno(textio *self, PyObject *args) 23604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "fileno", NULL); 23634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_seekable(textio *self, PyObject *args) 23674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "seekable", NULL); 23704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_readable(textio *self, PyObject *args) 23744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "readable", NULL); 23774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_writable(textio *self, PyObject *args) 23814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "writable", NULL); 23844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_isatty(textio *self, PyObject *args) 23884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "isatty", NULL); 23914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 23924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 23934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 23944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_flush(textio *self, PyObject *args) 23954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 23964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 23974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_CLOSED(self); 23984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->telling = self->seekable; 23994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_textiowrapper_writeflush(self) < 0) 24004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "flush", NULL); 24024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 24034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 24054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_close(textio *self, PyObject *args) 24064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 24074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 24084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int r; 24094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 24104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = textiowrapper_closed_get(self, NULL); 24124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) 24134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = PyObject_IsTrue(res); 24154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 24164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r < 0) 24174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r > 0) { 24204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; /* stream already closed */ 24214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 24234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_CallMethod((PyObject *)self, "flush", NULL); 24244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) { 24254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 24284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(res); 24294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_CallMethod(self->buffer, "close", NULL); 24314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 24334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 24354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_iternext(textio *self) 24364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 24374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *line; 24384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 24404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->telling = 0; 24424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (Py_TYPE(self) == &PyTextIOWrapper_Type) { 24434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Skip method call overhead for speed */ 24444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = _textiowrapper_readline(self, -1); 24454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 24474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = PyObject_CallMethodObjArgs((PyObject *)self, 24484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _PyIO_str_readline, NULL); 24494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line && !PyUnicode_Check(line)) { 24504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_IOError, 24514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "readline() should have returned an str object, " 24524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "not '%.200s'", Py_TYPE(line)->tp_name); 24534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(line); 24544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (line == NULL) 24594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_GET_SIZE(line) == 0) { 24624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Reached EOF or would have blocked */ 24634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(line); 24644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_CLEAR(self->snapshot); 24654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->telling = self->seekable; 24664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 24674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return line; 24704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 24714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 24734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_name_get(textio *self, void *context) 24744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 24754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 24764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_GetAttrString(self->buffer, "name"); 24774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 24784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 24804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_closed_get(textio *self, void *context) 24814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 24824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 24834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyObject_GetAttr(self->buffer, _PyIO_str_closed); 24844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 24854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 24874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_newlines_get(textio *self, void *context) 24884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 24894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *res; 24904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 24914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->decoder == NULL) 24924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 24934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines); 24944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (res == NULL) { 24954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_ExceptionMatches(PyExc_AttributeError)) { 24964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 24974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 24984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 24994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 25004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 25014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 25024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 25034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return res; 25044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 25054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 25074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_errors_get(textio *self, void *context) 25084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 25094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 25104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(self->errors); 25114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self->errors; 25124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 25134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 25154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_chunk_size_get(textio *self, void *context) 25164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 25174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED(self); 25184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyLong_FromSsize_t(self->chunk_size); 25194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 25204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 25224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtextiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) 25234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 25244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t n; 25254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHECK_INITIALIZED_INT(self); 25264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = PyNumber_AsSsize_t(arg, PyExc_TypeError); 25274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (n == -1 && PyErr_Occurred()) 25284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 25294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (n <= 0) { 25304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, 25314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "a strictly positive integer is required"); 25324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 25334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 25344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->chunk_size = n; 25354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 25364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 25374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef textiowrapper_methods[] = { 25394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"detach", (PyCFunction)textiowrapper_detach, METH_NOARGS}, 25404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"write", (PyCFunction)textiowrapper_write, METH_VARARGS}, 25414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"read", (PyCFunction)textiowrapper_read, METH_VARARGS}, 25424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"readline", (PyCFunction)textiowrapper_readline, METH_VARARGS}, 25434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"flush", (PyCFunction)textiowrapper_flush, METH_NOARGS}, 25444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"close", (PyCFunction)textiowrapper_close, METH_NOARGS}, 25454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"fileno", (PyCFunction)textiowrapper_fileno, METH_NOARGS}, 25474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"seekable", (PyCFunction)textiowrapper_seekable, METH_NOARGS}, 25484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS}, 25494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS}, 25504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS}, 25514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS}, 25534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS}, 25544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"truncate", (PyCFunction)textiowrapper_truncate, METH_VARARGS}, 25554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL} 25564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 25574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMemberDef textiowrapper_members[] = { 25594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY}, 25604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY}, 25614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY}, 25624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL} 25634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 25644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyGetSetDef textiowrapper_getset[] = { 25664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"name", (getter)textiowrapper_name_get, NULL, NULL}, 25674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"closed", (getter)textiowrapper_closed_get, NULL, NULL}, 25684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL}, 25694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/ 25704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL}, 25714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"errors", (getter)textiowrapper_errors_get, NULL, NULL}, 25724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get, 25734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (setter)textiowrapper_chunk_size_set, NULL}, 25744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL} 25754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 25764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 25774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyTypeObject PyTextIOWrapper_Type = { 25784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 25794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "_io.TextIOWrapper", /*tp_name*/ 25804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(textio), /*tp_basicsize*/ 25814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_itemsize*/ 25824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)textiowrapper_dealloc, /*tp_dealloc*/ 25834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_print*/ 25844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_getattr*/ 25854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tps_etattr*/ 25864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_compare */ 25874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (reprfunc)textiowrapper_repr,/*tp_repr*/ 25884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_number*/ 25894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_sequence*/ 25904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_mapping*/ 25914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_hash */ 25924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_call*/ 25934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_str*/ 25944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_getattro*/ 25954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_setattro*/ 25964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /*tp_as_buffer*/ 25974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE 25984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 25994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_doc, /* tp_doc */ 26004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (traverseproc)textiowrapper_traverse, /* tp_traverse */ 26014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (inquiry)textiowrapper_clear, /* tp_clear */ 26024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 26034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm offsetof(textio, weakreflist), /*tp_weaklistoffset*/ 26044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 26054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (iternextfunc)textiowrapper_iternext, /* tp_iternext */ 26064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_methods, /* tp_methods */ 26074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_members, /* tp_members */ 26084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm textiowrapper_getset, /* tp_getset */ 26094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_base */ 26104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 26114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 26124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 26134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm offsetof(textio, dict), /*tp_dictoffset*/ 26144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (initproc)textiowrapper_init, /* tp_init */ 26154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 26164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyType_GenericNew, /* tp_new */ 26174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 2618