17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci An implementation of the I/O abstract base classes hierarchy 37db96d56Sopenharmony_ci as defined by PEP 3116 - "New I/O" 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci Classes defined here: IOBase, RawIOBase. 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci Written by Amaury Forgeot d'Arc and Antoine Pitrou 87db96d56Sopenharmony_ci*/ 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 127db96d56Sopenharmony_ci#include "Python.h" 137db96d56Sopenharmony_ci#include "pycore_long.h" // _PyLong_GetOne() 147db96d56Sopenharmony_ci#include "pycore_object.h" 157db96d56Sopenharmony_ci#include <stddef.h> // offsetof() 167db96d56Sopenharmony_ci#include "_iomodule.h" 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci/*[clinic input] 197db96d56Sopenharmony_cimodule _io 207db96d56Sopenharmony_ciclass _io._IOBase "PyObject *" "&PyIOBase_Type" 217db96d56Sopenharmony_ciclass _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" 227db96d56Sopenharmony_ci[clinic start generated code]*/ 237db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci/* 267db96d56Sopenharmony_ci * IOBase class, an abstract class 277db96d56Sopenharmony_ci */ 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_citypedef struct { 307db96d56Sopenharmony_ci PyObject_HEAD 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci PyObject *dict; 337db96d56Sopenharmony_ci PyObject *weakreflist; 347db96d56Sopenharmony_ci} iobase; 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ciPyDoc_STRVAR(iobase_doc, 377db96d56Sopenharmony_ci "The abstract base class for all I/O classes.\n" 387db96d56Sopenharmony_ci "\n" 397db96d56Sopenharmony_ci "This class provides dummy implementations for many methods that\n" 407db96d56Sopenharmony_ci "derived classes can override selectively; the default implementations\n" 417db96d56Sopenharmony_ci "represent a file that cannot be read, written or seeked.\n" 427db96d56Sopenharmony_ci "\n" 437db96d56Sopenharmony_ci "Even though IOBase does not declare read, readinto, or write because\n" 447db96d56Sopenharmony_ci "their signatures will vary, implementations and clients should\n" 457db96d56Sopenharmony_ci "consider those methods part of the interface. Also, implementations\n" 467db96d56Sopenharmony_ci "may raise UnsupportedOperation when operations they do not support are\n" 477db96d56Sopenharmony_ci "called.\n" 487db96d56Sopenharmony_ci "\n" 497db96d56Sopenharmony_ci "The basic type used for binary data read from or written to a file is\n" 507db96d56Sopenharmony_ci "bytes. Other bytes-like objects are accepted as method arguments too.\n" 517db96d56Sopenharmony_ci "In some cases (such as readinto), a writable object is required. Text\n" 527db96d56Sopenharmony_ci "I/O classes work with str data.\n" 537db96d56Sopenharmony_ci "\n" 547db96d56Sopenharmony_ci "Note that calling any method (except additional calls to close(),\n" 557db96d56Sopenharmony_ci "which are ignored) on a closed stream should raise a ValueError.\n" 567db96d56Sopenharmony_ci "\n" 577db96d56Sopenharmony_ci "IOBase (and its subclasses) support the iterator protocol, meaning\n" 587db96d56Sopenharmony_ci "that an IOBase object can be iterated over yielding the lines in a\n" 597db96d56Sopenharmony_ci "stream.\n" 607db96d56Sopenharmony_ci "\n" 617db96d56Sopenharmony_ci "IOBase also supports the :keyword:`with` statement. In this example,\n" 627db96d56Sopenharmony_ci "fp is closed after the suite of the with statement is complete:\n" 637db96d56Sopenharmony_ci "\n" 647db96d56Sopenharmony_ci "with open('spam.txt', 'r') as fp:\n" 657db96d56Sopenharmony_ci " fp.write('Spam and eggs!')\n"); 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci/* Use this macro whenever you want to check the internal `closed` status 687db96d56Sopenharmony_ci of the IOBase object rather than the virtual `closed` attribute as returned 697db96d56Sopenharmony_ci by whatever subclass. */ 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci/* Internal methods */ 737db96d56Sopenharmony_cistatic PyObject * 747db96d56Sopenharmony_ciiobase_unsupported(const char *message) 757db96d56Sopenharmony_ci{ 767db96d56Sopenharmony_ci _PyIO_State *state = IO_STATE(); 777db96d56Sopenharmony_ci if (state != NULL) 787db96d56Sopenharmony_ci PyErr_SetString(state->unsupported_operation, message); 797db96d56Sopenharmony_ci return NULL; 807db96d56Sopenharmony_ci} 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci/* Positioning */ 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ciPyDoc_STRVAR(iobase_seek_doc, 857db96d56Sopenharmony_ci "Change stream position.\n" 867db96d56Sopenharmony_ci "\n" 877db96d56Sopenharmony_ci "Change the stream position to the given byte offset. The offset is\n" 887db96d56Sopenharmony_ci "interpreted relative to the position indicated by whence. Values\n" 897db96d56Sopenharmony_ci "for whence are:\n" 907db96d56Sopenharmony_ci "\n" 917db96d56Sopenharmony_ci "* 0 -- start of stream (the default); offset should be zero or positive\n" 927db96d56Sopenharmony_ci "* 1 -- current stream position; offset may be negative\n" 937db96d56Sopenharmony_ci "* 2 -- end of stream; offset is usually negative\n" 947db96d56Sopenharmony_ci "\n" 957db96d56Sopenharmony_ci "Return the new absolute position."); 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_cistatic PyObject * 987db96d56Sopenharmony_ciiobase_seek(PyObject *self, PyObject *args) 997db96d56Sopenharmony_ci{ 1007db96d56Sopenharmony_ci return iobase_unsupported("seek"); 1017db96d56Sopenharmony_ci} 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci/*[clinic input] 1047db96d56Sopenharmony_ci_io._IOBase.tell 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ciReturn current stream position. 1077db96d56Sopenharmony_ci[clinic start generated code]*/ 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_cistatic PyObject * 1107db96d56Sopenharmony_ci_io__IOBase_tell_impl(PyObject *self) 1117db96d56Sopenharmony_ci/*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ 1127db96d56Sopenharmony_ci{ 1137db96d56Sopenharmony_ci return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1); 1147db96d56Sopenharmony_ci} 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ciPyDoc_STRVAR(iobase_truncate_doc, 1177db96d56Sopenharmony_ci "Truncate file to size bytes.\n" 1187db96d56Sopenharmony_ci "\n" 1197db96d56Sopenharmony_ci "File pointer is left unchanged. Size defaults to the current IO\n" 1207db96d56Sopenharmony_ci "position as reported by tell(). Returns the new size."); 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_cistatic PyObject * 1237db96d56Sopenharmony_ciiobase_truncate(PyObject *self, PyObject *args) 1247db96d56Sopenharmony_ci{ 1257db96d56Sopenharmony_ci return iobase_unsupported("truncate"); 1267db96d56Sopenharmony_ci} 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_cistatic int 1297db96d56Sopenharmony_ciiobase_is_closed(PyObject *self) 1307db96d56Sopenharmony_ci{ 1317db96d56Sopenharmony_ci PyObject *res; 1327db96d56Sopenharmony_ci int ret; 1337db96d56Sopenharmony_ci /* This gets the derived attribute, which is *not* __IOBase_closed 1347db96d56Sopenharmony_ci in most cases! */ 1357db96d56Sopenharmony_ci ret = _PyObject_LookupAttr(self, &_Py_ID(__IOBase_closed), &res); 1367db96d56Sopenharmony_ci Py_XDECREF(res); 1377db96d56Sopenharmony_ci return ret; 1387db96d56Sopenharmony_ci} 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci/* Flush and close methods */ 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci/*[clinic input] 1437db96d56Sopenharmony_ci_io._IOBase.flush 1447db96d56Sopenharmony_ci 1457db96d56Sopenharmony_ciFlush write buffers, if applicable. 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ciThis is not implemented for read-only and non-blocking streams. 1487db96d56Sopenharmony_ci[clinic start generated code]*/ 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_cistatic PyObject * 1517db96d56Sopenharmony_ci_io__IOBase_flush_impl(PyObject *self) 1527db96d56Sopenharmony_ci/*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/ 1537db96d56Sopenharmony_ci{ 1547db96d56Sopenharmony_ci /* XXX Should this return the number of bytes written??? */ 1557db96d56Sopenharmony_ci int closed = iobase_is_closed(self); 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci if (!closed) { 1587db96d56Sopenharmony_ci Py_RETURN_NONE; 1597db96d56Sopenharmony_ci } 1607db96d56Sopenharmony_ci if (closed > 0) { 1617db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); 1627db96d56Sopenharmony_ci } 1637db96d56Sopenharmony_ci return NULL; 1647db96d56Sopenharmony_ci} 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_cistatic PyObject * 1677db96d56Sopenharmony_ciiobase_closed_get(PyObject *self, void *context) 1687db96d56Sopenharmony_ci{ 1697db96d56Sopenharmony_ci int closed = iobase_is_closed(self); 1707db96d56Sopenharmony_ci if (closed < 0) { 1717db96d56Sopenharmony_ci return NULL; 1727db96d56Sopenharmony_ci } 1737db96d56Sopenharmony_ci return PyBool_FromLong(closed); 1747db96d56Sopenharmony_ci} 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_cistatic int 1777db96d56Sopenharmony_ciiobase_check_closed(PyObject *self) 1787db96d56Sopenharmony_ci{ 1797db96d56Sopenharmony_ci PyObject *res; 1807db96d56Sopenharmony_ci int closed; 1817db96d56Sopenharmony_ci /* This gets the derived attribute, which is *not* __IOBase_closed 1827db96d56Sopenharmony_ci in most cases! */ 1837db96d56Sopenharmony_ci closed = _PyObject_LookupAttr(self, &_Py_ID(closed), &res); 1847db96d56Sopenharmony_ci if (closed > 0) { 1857db96d56Sopenharmony_ci closed = PyObject_IsTrue(res); 1867db96d56Sopenharmony_ci Py_DECREF(res); 1877db96d56Sopenharmony_ci if (closed > 0) { 1887db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); 1897db96d56Sopenharmony_ci return -1; 1907db96d56Sopenharmony_ci } 1917db96d56Sopenharmony_ci } 1927db96d56Sopenharmony_ci return closed; 1937db96d56Sopenharmony_ci} 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ciPyObject * 1967db96d56Sopenharmony_ci_PyIOBase_check_closed(PyObject *self, PyObject *args) 1977db96d56Sopenharmony_ci{ 1987db96d56Sopenharmony_ci if (iobase_check_closed(self)) { 1997db96d56Sopenharmony_ci return NULL; 2007db96d56Sopenharmony_ci } 2017db96d56Sopenharmony_ci if (args == Py_True) { 2027db96d56Sopenharmony_ci return Py_None; 2037db96d56Sopenharmony_ci } 2047db96d56Sopenharmony_ci Py_RETURN_NONE; 2057db96d56Sopenharmony_ci} 2067db96d56Sopenharmony_ci 2077db96d56Sopenharmony_ci/* XXX: IOBase thinks it has to maintain its own internal state in 2087db96d56Sopenharmony_ci `__IOBase_closed` and call flush() by itself, but it is redundant with 2097db96d56Sopenharmony_ci whatever behaviour a non-trivial derived class will implement. */ 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci/*[clinic input] 2127db96d56Sopenharmony_ci_io._IOBase.close 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ciFlush and close the IO object. 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ciThis method has no effect if the file is already closed. 2177db96d56Sopenharmony_ci[clinic start generated code]*/ 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_cistatic PyObject * 2207db96d56Sopenharmony_ci_io__IOBase_close_impl(PyObject *self) 2217db96d56Sopenharmony_ci/*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ 2227db96d56Sopenharmony_ci{ 2237db96d56Sopenharmony_ci PyObject *res, *exc, *val, *tb; 2247db96d56Sopenharmony_ci int rc, closed = iobase_is_closed(self); 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci if (closed < 0) { 2277db96d56Sopenharmony_ci return NULL; 2287db96d56Sopenharmony_ci } 2297db96d56Sopenharmony_ci if (closed) { 2307db96d56Sopenharmony_ci Py_RETURN_NONE; 2317db96d56Sopenharmony_ci } 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush)); 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci PyErr_Fetch(&exc, &val, &tb); 2367db96d56Sopenharmony_ci rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True); 2377db96d56Sopenharmony_ci _PyErr_ChainExceptions(exc, val, tb); 2387db96d56Sopenharmony_ci if (rc < 0) { 2397db96d56Sopenharmony_ci Py_CLEAR(res); 2407db96d56Sopenharmony_ci } 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci if (res == NULL) 2437db96d56Sopenharmony_ci return NULL; 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci Py_DECREF(res); 2467db96d56Sopenharmony_ci Py_RETURN_NONE; 2477db96d56Sopenharmony_ci} 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci/* Finalization and garbage collection support */ 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_cistatic void 2527db96d56Sopenharmony_ciiobase_finalize(PyObject *self) 2537db96d56Sopenharmony_ci{ 2547db96d56Sopenharmony_ci PyObject *res; 2557db96d56Sopenharmony_ci PyObject *error_type, *error_value, *error_traceback; 2567db96d56Sopenharmony_ci int closed; 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ci /* Save the current exception, if any. */ 2597db96d56Sopenharmony_ci PyErr_Fetch(&error_type, &error_value, &error_traceback); 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci /* If `closed` doesn't exist or can't be evaluated as bool, then the 2627db96d56Sopenharmony_ci object is probably in an unusable state, so ignore. */ 2637db96d56Sopenharmony_ci if (_PyObject_LookupAttr(self, &_Py_ID(closed), &res) <= 0) { 2647db96d56Sopenharmony_ci PyErr_Clear(); 2657db96d56Sopenharmony_ci closed = -1; 2667db96d56Sopenharmony_ci } 2677db96d56Sopenharmony_ci else { 2687db96d56Sopenharmony_ci closed = PyObject_IsTrue(res); 2697db96d56Sopenharmony_ci Py_DECREF(res); 2707db96d56Sopenharmony_ci if (closed == -1) 2717db96d56Sopenharmony_ci PyErr_Clear(); 2727db96d56Sopenharmony_ci } 2737db96d56Sopenharmony_ci if (closed == 0) { 2747db96d56Sopenharmony_ci /* Signal close() that it was called as part of the object 2757db96d56Sopenharmony_ci finalization process. */ 2767db96d56Sopenharmony_ci if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True)) 2777db96d56Sopenharmony_ci PyErr_Clear(); 2787db96d56Sopenharmony_ci res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(close)); 2797db96d56Sopenharmony_ci /* Silencing I/O errors is bad, but printing spurious tracebacks is 2807db96d56Sopenharmony_ci equally as bad, and potentially more frequent (because of 2817db96d56Sopenharmony_ci shutdown issues). */ 2827db96d56Sopenharmony_ci if (res == NULL) { 2837db96d56Sopenharmony_ci#ifndef Py_DEBUG 2847db96d56Sopenharmony_ci if (_Py_GetConfig()->dev_mode) { 2857db96d56Sopenharmony_ci PyErr_WriteUnraisable(self); 2867db96d56Sopenharmony_ci } 2877db96d56Sopenharmony_ci else { 2887db96d56Sopenharmony_ci PyErr_Clear(); 2897db96d56Sopenharmony_ci } 2907db96d56Sopenharmony_ci#else 2917db96d56Sopenharmony_ci PyErr_WriteUnraisable(self); 2927db96d56Sopenharmony_ci#endif 2937db96d56Sopenharmony_ci } 2947db96d56Sopenharmony_ci else { 2957db96d56Sopenharmony_ci Py_DECREF(res); 2967db96d56Sopenharmony_ci } 2977db96d56Sopenharmony_ci } 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci /* Restore the saved exception. */ 3007db96d56Sopenharmony_ci PyErr_Restore(error_type, error_value, error_traceback); 3017db96d56Sopenharmony_ci} 3027db96d56Sopenharmony_ci 3037db96d56Sopenharmony_ciint 3047db96d56Sopenharmony_ci_PyIOBase_finalize(PyObject *self) 3057db96d56Sopenharmony_ci{ 3067db96d56Sopenharmony_ci int is_zombie; 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci /* If _PyIOBase_finalize() is called from a destructor, we need to 3097db96d56Sopenharmony_ci resurrect the object as calling close() can invoke arbitrary code. */ 3107db96d56Sopenharmony_ci is_zombie = (Py_REFCNT(self) == 0); 3117db96d56Sopenharmony_ci if (is_zombie) 3127db96d56Sopenharmony_ci return PyObject_CallFinalizerFromDealloc(self); 3137db96d56Sopenharmony_ci else { 3147db96d56Sopenharmony_ci PyObject_CallFinalizer(self); 3157db96d56Sopenharmony_ci return 0; 3167db96d56Sopenharmony_ci } 3177db96d56Sopenharmony_ci} 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_cistatic int 3207db96d56Sopenharmony_ciiobase_traverse(iobase *self, visitproc visit, void *arg) 3217db96d56Sopenharmony_ci{ 3227db96d56Sopenharmony_ci Py_VISIT(self->dict); 3237db96d56Sopenharmony_ci return 0; 3247db96d56Sopenharmony_ci} 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_cistatic int 3277db96d56Sopenharmony_ciiobase_clear(iobase *self) 3287db96d56Sopenharmony_ci{ 3297db96d56Sopenharmony_ci Py_CLEAR(self->dict); 3307db96d56Sopenharmony_ci return 0; 3317db96d56Sopenharmony_ci} 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci/* Destructor */ 3347db96d56Sopenharmony_ci 3357db96d56Sopenharmony_cistatic void 3367db96d56Sopenharmony_ciiobase_dealloc(iobase *self) 3377db96d56Sopenharmony_ci{ 3387db96d56Sopenharmony_ci /* NOTE: since IOBaseObject has its own dict, Python-defined attributes 3397db96d56Sopenharmony_ci are still available here for close() to use. 3407db96d56Sopenharmony_ci However, if the derived class declares a __slots__, those slots are 3417db96d56Sopenharmony_ci already gone. 3427db96d56Sopenharmony_ci */ 3437db96d56Sopenharmony_ci if (_PyIOBase_finalize((PyObject *) self) < 0) { 3447db96d56Sopenharmony_ci /* When called from a heap type's dealloc, the type will be 3457db96d56Sopenharmony_ci decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ 3467db96d56Sopenharmony_ci if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) { 3477db96d56Sopenharmony_ci Py_INCREF(Py_TYPE(self)); 3487db96d56Sopenharmony_ci } 3497db96d56Sopenharmony_ci return; 3507db96d56Sopenharmony_ci } 3517db96d56Sopenharmony_ci _PyObject_GC_UNTRACK(self); 3527db96d56Sopenharmony_ci if (self->weakreflist != NULL) 3537db96d56Sopenharmony_ci PyObject_ClearWeakRefs((PyObject *) self); 3547db96d56Sopenharmony_ci Py_CLEAR(self->dict); 3557db96d56Sopenharmony_ci Py_TYPE(self)->tp_free((PyObject *) self); 3567db96d56Sopenharmony_ci} 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci/* Inquiry methods */ 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci/*[clinic input] 3617db96d56Sopenharmony_ci_io._IOBase.seekable 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_ciReturn whether object supports random access. 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ciIf False, seek(), tell() and truncate() will raise OSError. 3667db96d56Sopenharmony_ciThis method may need to do a test seek(). 3677db96d56Sopenharmony_ci[clinic start generated code]*/ 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_cistatic PyObject * 3707db96d56Sopenharmony_ci_io__IOBase_seekable_impl(PyObject *self) 3717db96d56Sopenharmony_ci/*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/ 3727db96d56Sopenharmony_ci{ 3737db96d56Sopenharmony_ci Py_RETURN_FALSE; 3747db96d56Sopenharmony_ci} 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_ciPyObject * 3777db96d56Sopenharmony_ci_PyIOBase_check_seekable(PyObject *self, PyObject *args) 3787db96d56Sopenharmony_ci{ 3797db96d56Sopenharmony_ci PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable)); 3807db96d56Sopenharmony_ci if (res == NULL) 3817db96d56Sopenharmony_ci return NULL; 3827db96d56Sopenharmony_ci if (res != Py_True) { 3837db96d56Sopenharmony_ci Py_CLEAR(res); 3847db96d56Sopenharmony_ci iobase_unsupported("File or stream is not seekable."); 3857db96d56Sopenharmony_ci return NULL; 3867db96d56Sopenharmony_ci } 3877db96d56Sopenharmony_ci if (args == Py_True) { 3887db96d56Sopenharmony_ci Py_DECREF(res); 3897db96d56Sopenharmony_ci } 3907db96d56Sopenharmony_ci return res; 3917db96d56Sopenharmony_ci} 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ci/*[clinic input] 3947db96d56Sopenharmony_ci_io._IOBase.readable 3957db96d56Sopenharmony_ci 3967db96d56Sopenharmony_ciReturn whether object was opened for reading. 3977db96d56Sopenharmony_ci 3987db96d56Sopenharmony_ciIf False, read() will raise OSError. 3997db96d56Sopenharmony_ci[clinic start generated code]*/ 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_cistatic PyObject * 4027db96d56Sopenharmony_ci_io__IOBase_readable_impl(PyObject *self) 4037db96d56Sopenharmony_ci/*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/ 4047db96d56Sopenharmony_ci{ 4057db96d56Sopenharmony_ci Py_RETURN_FALSE; 4067db96d56Sopenharmony_ci} 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci/* May be called with any object */ 4097db96d56Sopenharmony_ciPyObject * 4107db96d56Sopenharmony_ci_PyIOBase_check_readable(PyObject *self, PyObject *args) 4117db96d56Sopenharmony_ci{ 4127db96d56Sopenharmony_ci PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable)); 4137db96d56Sopenharmony_ci if (res == NULL) 4147db96d56Sopenharmony_ci return NULL; 4157db96d56Sopenharmony_ci if (res != Py_True) { 4167db96d56Sopenharmony_ci Py_CLEAR(res); 4177db96d56Sopenharmony_ci iobase_unsupported("File or stream is not readable."); 4187db96d56Sopenharmony_ci return NULL; 4197db96d56Sopenharmony_ci } 4207db96d56Sopenharmony_ci if (args == Py_True) { 4217db96d56Sopenharmony_ci Py_DECREF(res); 4227db96d56Sopenharmony_ci } 4237db96d56Sopenharmony_ci return res; 4247db96d56Sopenharmony_ci} 4257db96d56Sopenharmony_ci 4267db96d56Sopenharmony_ci/*[clinic input] 4277db96d56Sopenharmony_ci_io._IOBase.writable 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ciReturn whether object was opened for writing. 4307db96d56Sopenharmony_ci 4317db96d56Sopenharmony_ciIf False, write() will raise OSError. 4327db96d56Sopenharmony_ci[clinic start generated code]*/ 4337db96d56Sopenharmony_ci 4347db96d56Sopenharmony_cistatic PyObject * 4357db96d56Sopenharmony_ci_io__IOBase_writable_impl(PyObject *self) 4367db96d56Sopenharmony_ci/*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/ 4377db96d56Sopenharmony_ci{ 4387db96d56Sopenharmony_ci Py_RETURN_FALSE; 4397db96d56Sopenharmony_ci} 4407db96d56Sopenharmony_ci 4417db96d56Sopenharmony_ci/* May be called with any object */ 4427db96d56Sopenharmony_ciPyObject * 4437db96d56Sopenharmony_ci_PyIOBase_check_writable(PyObject *self, PyObject *args) 4447db96d56Sopenharmony_ci{ 4457db96d56Sopenharmony_ci PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable)); 4467db96d56Sopenharmony_ci if (res == NULL) 4477db96d56Sopenharmony_ci return NULL; 4487db96d56Sopenharmony_ci if (res != Py_True) { 4497db96d56Sopenharmony_ci Py_CLEAR(res); 4507db96d56Sopenharmony_ci iobase_unsupported("File or stream is not writable."); 4517db96d56Sopenharmony_ci return NULL; 4527db96d56Sopenharmony_ci } 4537db96d56Sopenharmony_ci if (args == Py_True) { 4547db96d56Sopenharmony_ci Py_DECREF(res); 4557db96d56Sopenharmony_ci } 4567db96d56Sopenharmony_ci return res; 4577db96d56Sopenharmony_ci} 4587db96d56Sopenharmony_ci 4597db96d56Sopenharmony_ci/* Context manager */ 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_cistatic PyObject * 4627db96d56Sopenharmony_ciiobase_enter(PyObject *self, PyObject *args) 4637db96d56Sopenharmony_ci{ 4647db96d56Sopenharmony_ci if (iobase_check_closed(self)) 4657db96d56Sopenharmony_ci return NULL; 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_ci Py_INCREF(self); 4687db96d56Sopenharmony_ci return self; 4697db96d56Sopenharmony_ci} 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_cistatic PyObject * 4727db96d56Sopenharmony_ciiobase_exit(PyObject *self, PyObject *args) 4737db96d56Sopenharmony_ci{ 4747db96d56Sopenharmony_ci return PyObject_CallMethodNoArgs(self, &_Py_ID(close)); 4757db96d56Sopenharmony_ci} 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ci/* Lower-level APIs */ 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci/* XXX Should these be present even if unimplemented? */ 4807db96d56Sopenharmony_ci 4817db96d56Sopenharmony_ci/*[clinic input] 4827db96d56Sopenharmony_ci_io._IOBase.fileno 4837db96d56Sopenharmony_ci 4847db96d56Sopenharmony_ciReturns underlying file descriptor if one exists. 4857db96d56Sopenharmony_ci 4867db96d56Sopenharmony_ciOSError is raised if the IO object does not use a file descriptor. 4877db96d56Sopenharmony_ci[clinic start generated code]*/ 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_cistatic PyObject * 4907db96d56Sopenharmony_ci_io__IOBase_fileno_impl(PyObject *self) 4917db96d56Sopenharmony_ci/*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/ 4927db96d56Sopenharmony_ci{ 4937db96d56Sopenharmony_ci return iobase_unsupported("fileno"); 4947db96d56Sopenharmony_ci} 4957db96d56Sopenharmony_ci 4967db96d56Sopenharmony_ci/*[clinic input] 4977db96d56Sopenharmony_ci_io._IOBase.isatty 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ciReturn whether this is an 'interactive' stream. 5007db96d56Sopenharmony_ci 5017db96d56Sopenharmony_ciReturn False if it can't be determined. 5027db96d56Sopenharmony_ci[clinic start generated code]*/ 5037db96d56Sopenharmony_ci 5047db96d56Sopenharmony_cistatic PyObject * 5057db96d56Sopenharmony_ci_io__IOBase_isatty_impl(PyObject *self) 5067db96d56Sopenharmony_ci/*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/ 5077db96d56Sopenharmony_ci{ 5087db96d56Sopenharmony_ci if (iobase_check_closed(self)) 5097db96d56Sopenharmony_ci return NULL; 5107db96d56Sopenharmony_ci Py_RETURN_FALSE; 5117db96d56Sopenharmony_ci} 5127db96d56Sopenharmony_ci 5137db96d56Sopenharmony_ci/* Readline(s) and writelines */ 5147db96d56Sopenharmony_ci 5157db96d56Sopenharmony_ci/*[clinic input] 5167db96d56Sopenharmony_ci_io._IOBase.readline 5177db96d56Sopenharmony_ci size as limit: Py_ssize_t(accept={int, NoneType}) = -1 5187db96d56Sopenharmony_ci / 5197db96d56Sopenharmony_ci 5207db96d56Sopenharmony_ciRead and return a line from the stream. 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ciIf size is specified, at most size bytes will be read. 5237db96d56Sopenharmony_ci 5247db96d56Sopenharmony_ciThe line terminator is always b'\n' for binary files; for text 5257db96d56Sopenharmony_cifiles, the newlines argument to open can be used to select the line 5267db96d56Sopenharmony_citerminator(s) recognized. 5277db96d56Sopenharmony_ci[clinic start generated code]*/ 5287db96d56Sopenharmony_ci 5297db96d56Sopenharmony_cistatic PyObject * 5307db96d56Sopenharmony_ci_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) 5317db96d56Sopenharmony_ci/*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/ 5327db96d56Sopenharmony_ci{ 5337db96d56Sopenharmony_ci /* For backwards compatibility, a (slowish) readline(). */ 5347db96d56Sopenharmony_ci 5357db96d56Sopenharmony_ci PyObject *peek, *buffer, *result; 5367db96d56Sopenharmony_ci Py_ssize_t old_size = -1; 5377db96d56Sopenharmony_ci 5387db96d56Sopenharmony_ci if (_PyObject_LookupAttr(self, &_Py_ID(peek), &peek) < 0) { 5397db96d56Sopenharmony_ci return NULL; 5407db96d56Sopenharmony_ci } 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci buffer = PyByteArray_FromStringAndSize(NULL, 0); 5437db96d56Sopenharmony_ci if (buffer == NULL) { 5447db96d56Sopenharmony_ci Py_XDECREF(peek); 5457db96d56Sopenharmony_ci return NULL; 5467db96d56Sopenharmony_ci } 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) { 5497db96d56Sopenharmony_ci Py_ssize_t nreadahead = 1; 5507db96d56Sopenharmony_ci PyObject *b; 5517db96d56Sopenharmony_ci 5527db96d56Sopenharmony_ci if (peek != NULL) { 5537db96d56Sopenharmony_ci PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_GetOne()); 5547db96d56Sopenharmony_ci if (readahead == NULL) { 5557db96d56Sopenharmony_ci /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() 5567db96d56Sopenharmony_ci when EINTR occurs so we needn't do it ourselves. */ 5577db96d56Sopenharmony_ci if (_PyIO_trap_eintr()) { 5587db96d56Sopenharmony_ci continue; 5597db96d56Sopenharmony_ci } 5607db96d56Sopenharmony_ci goto fail; 5617db96d56Sopenharmony_ci } 5627db96d56Sopenharmony_ci if (!PyBytes_Check(readahead)) { 5637db96d56Sopenharmony_ci PyErr_Format(PyExc_OSError, 5647db96d56Sopenharmony_ci "peek() should have returned a bytes object, " 5657db96d56Sopenharmony_ci "not '%.200s'", Py_TYPE(readahead)->tp_name); 5667db96d56Sopenharmony_ci Py_DECREF(readahead); 5677db96d56Sopenharmony_ci goto fail; 5687db96d56Sopenharmony_ci } 5697db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(readahead) > 0) { 5707db96d56Sopenharmony_ci Py_ssize_t n = 0; 5717db96d56Sopenharmony_ci const char *buf = PyBytes_AS_STRING(readahead); 5727db96d56Sopenharmony_ci if (limit >= 0) { 5737db96d56Sopenharmony_ci do { 5747db96d56Sopenharmony_ci if (n >= PyBytes_GET_SIZE(readahead) || n >= limit) 5757db96d56Sopenharmony_ci break; 5767db96d56Sopenharmony_ci if (buf[n++] == '\n') 5777db96d56Sopenharmony_ci break; 5787db96d56Sopenharmony_ci } while (1); 5797db96d56Sopenharmony_ci } 5807db96d56Sopenharmony_ci else { 5817db96d56Sopenharmony_ci do { 5827db96d56Sopenharmony_ci if (n >= PyBytes_GET_SIZE(readahead)) 5837db96d56Sopenharmony_ci break; 5847db96d56Sopenharmony_ci if (buf[n++] == '\n') 5857db96d56Sopenharmony_ci break; 5867db96d56Sopenharmony_ci } while (1); 5877db96d56Sopenharmony_ci } 5887db96d56Sopenharmony_ci nreadahead = n; 5897db96d56Sopenharmony_ci } 5907db96d56Sopenharmony_ci Py_DECREF(readahead); 5917db96d56Sopenharmony_ci } 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci b = _PyObject_CallMethod(self, &_Py_ID(read), "n", nreadahead); 5947db96d56Sopenharmony_ci if (b == NULL) { 5957db96d56Sopenharmony_ci /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() 5967db96d56Sopenharmony_ci when EINTR occurs so we needn't do it ourselves. */ 5977db96d56Sopenharmony_ci if (_PyIO_trap_eintr()) { 5987db96d56Sopenharmony_ci continue; 5997db96d56Sopenharmony_ci } 6007db96d56Sopenharmony_ci goto fail; 6017db96d56Sopenharmony_ci } 6027db96d56Sopenharmony_ci if (!PyBytes_Check(b)) { 6037db96d56Sopenharmony_ci PyErr_Format(PyExc_OSError, 6047db96d56Sopenharmony_ci "read() should have returned a bytes object, " 6057db96d56Sopenharmony_ci "not '%.200s'", Py_TYPE(b)->tp_name); 6067db96d56Sopenharmony_ci Py_DECREF(b); 6077db96d56Sopenharmony_ci goto fail; 6087db96d56Sopenharmony_ci } 6097db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(b) == 0) { 6107db96d56Sopenharmony_ci Py_DECREF(b); 6117db96d56Sopenharmony_ci break; 6127db96d56Sopenharmony_ci } 6137db96d56Sopenharmony_ci 6147db96d56Sopenharmony_ci old_size = PyByteArray_GET_SIZE(buffer); 6157db96d56Sopenharmony_ci if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) { 6167db96d56Sopenharmony_ci Py_DECREF(b); 6177db96d56Sopenharmony_ci goto fail; 6187db96d56Sopenharmony_ci } 6197db96d56Sopenharmony_ci memcpy(PyByteArray_AS_STRING(buffer) + old_size, 6207db96d56Sopenharmony_ci PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b)); 6217db96d56Sopenharmony_ci 6227db96d56Sopenharmony_ci Py_DECREF(b); 6237db96d56Sopenharmony_ci 6247db96d56Sopenharmony_ci if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n') 6257db96d56Sopenharmony_ci break; 6267db96d56Sopenharmony_ci } 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer), 6297db96d56Sopenharmony_ci PyByteArray_GET_SIZE(buffer)); 6307db96d56Sopenharmony_ci Py_XDECREF(peek); 6317db96d56Sopenharmony_ci Py_DECREF(buffer); 6327db96d56Sopenharmony_ci return result; 6337db96d56Sopenharmony_ci fail: 6347db96d56Sopenharmony_ci Py_XDECREF(peek); 6357db96d56Sopenharmony_ci Py_DECREF(buffer); 6367db96d56Sopenharmony_ci return NULL; 6377db96d56Sopenharmony_ci} 6387db96d56Sopenharmony_ci 6397db96d56Sopenharmony_cistatic PyObject * 6407db96d56Sopenharmony_ciiobase_iter(PyObject *self) 6417db96d56Sopenharmony_ci{ 6427db96d56Sopenharmony_ci if (iobase_check_closed(self)) 6437db96d56Sopenharmony_ci return NULL; 6447db96d56Sopenharmony_ci 6457db96d56Sopenharmony_ci Py_INCREF(self); 6467db96d56Sopenharmony_ci return self; 6477db96d56Sopenharmony_ci} 6487db96d56Sopenharmony_ci 6497db96d56Sopenharmony_cistatic PyObject * 6507db96d56Sopenharmony_ciiobase_iternext(PyObject *self) 6517db96d56Sopenharmony_ci{ 6527db96d56Sopenharmony_ci PyObject *line = PyObject_CallMethodNoArgs(self, &_Py_ID(readline)); 6537db96d56Sopenharmony_ci 6547db96d56Sopenharmony_ci if (line == NULL) 6557db96d56Sopenharmony_ci return NULL; 6567db96d56Sopenharmony_ci 6577db96d56Sopenharmony_ci if (PyObject_Size(line) <= 0) { 6587db96d56Sopenharmony_ci /* Error or empty */ 6597db96d56Sopenharmony_ci Py_DECREF(line); 6607db96d56Sopenharmony_ci return NULL; 6617db96d56Sopenharmony_ci } 6627db96d56Sopenharmony_ci 6637db96d56Sopenharmony_ci return line; 6647db96d56Sopenharmony_ci} 6657db96d56Sopenharmony_ci 6667db96d56Sopenharmony_ci/*[clinic input] 6677db96d56Sopenharmony_ci_io._IOBase.readlines 6687db96d56Sopenharmony_ci hint: Py_ssize_t(accept={int, NoneType}) = -1 6697db96d56Sopenharmony_ci / 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ciReturn a list of lines from the stream. 6727db96d56Sopenharmony_ci 6737db96d56Sopenharmony_cihint can be specified to control the number of lines read: no more 6747db96d56Sopenharmony_cilines will be read if the total size (in bytes/characters) of all 6757db96d56Sopenharmony_cilines so far exceeds hint. 6767db96d56Sopenharmony_ci[clinic start generated code]*/ 6777db96d56Sopenharmony_ci 6787db96d56Sopenharmony_cistatic PyObject * 6797db96d56Sopenharmony_ci_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) 6807db96d56Sopenharmony_ci/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ 6817db96d56Sopenharmony_ci{ 6827db96d56Sopenharmony_ci Py_ssize_t length = 0; 6837db96d56Sopenharmony_ci PyObject *result, *it = NULL; 6847db96d56Sopenharmony_ci 6857db96d56Sopenharmony_ci result = PyList_New(0); 6867db96d56Sopenharmony_ci if (result == NULL) 6877db96d56Sopenharmony_ci return NULL; 6887db96d56Sopenharmony_ci 6897db96d56Sopenharmony_ci if (hint <= 0) { 6907db96d56Sopenharmony_ci /* XXX special-casing this made sense in the Python version in order 6917db96d56Sopenharmony_ci to remove the bytecode interpretation overhead, but it could 6927db96d56Sopenharmony_ci probably be removed here. */ 6937db96d56Sopenharmony_ci PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend), 6947db96d56Sopenharmony_ci self, NULL); 6957db96d56Sopenharmony_ci if (ret == NULL) { 6967db96d56Sopenharmony_ci goto error; 6977db96d56Sopenharmony_ci } 6987db96d56Sopenharmony_ci Py_DECREF(ret); 6997db96d56Sopenharmony_ci return result; 7007db96d56Sopenharmony_ci } 7017db96d56Sopenharmony_ci 7027db96d56Sopenharmony_ci it = PyObject_GetIter(self); 7037db96d56Sopenharmony_ci if (it == NULL) { 7047db96d56Sopenharmony_ci goto error; 7057db96d56Sopenharmony_ci } 7067db96d56Sopenharmony_ci 7077db96d56Sopenharmony_ci while (1) { 7087db96d56Sopenharmony_ci Py_ssize_t line_length; 7097db96d56Sopenharmony_ci PyObject *line = PyIter_Next(it); 7107db96d56Sopenharmony_ci if (line == NULL) { 7117db96d56Sopenharmony_ci if (PyErr_Occurred()) { 7127db96d56Sopenharmony_ci goto error; 7137db96d56Sopenharmony_ci } 7147db96d56Sopenharmony_ci else 7157db96d56Sopenharmony_ci break; /* StopIteration raised */ 7167db96d56Sopenharmony_ci } 7177db96d56Sopenharmony_ci 7187db96d56Sopenharmony_ci if (PyList_Append(result, line) < 0) { 7197db96d56Sopenharmony_ci Py_DECREF(line); 7207db96d56Sopenharmony_ci goto error; 7217db96d56Sopenharmony_ci } 7227db96d56Sopenharmony_ci line_length = PyObject_Size(line); 7237db96d56Sopenharmony_ci Py_DECREF(line); 7247db96d56Sopenharmony_ci if (line_length < 0) { 7257db96d56Sopenharmony_ci goto error; 7267db96d56Sopenharmony_ci } 7277db96d56Sopenharmony_ci if (line_length > hint - length) 7287db96d56Sopenharmony_ci break; 7297db96d56Sopenharmony_ci length += line_length; 7307db96d56Sopenharmony_ci } 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci Py_DECREF(it); 7337db96d56Sopenharmony_ci return result; 7347db96d56Sopenharmony_ci 7357db96d56Sopenharmony_ci error: 7367db96d56Sopenharmony_ci Py_XDECREF(it); 7377db96d56Sopenharmony_ci Py_DECREF(result); 7387db96d56Sopenharmony_ci return NULL; 7397db96d56Sopenharmony_ci} 7407db96d56Sopenharmony_ci 7417db96d56Sopenharmony_ci/*[clinic input] 7427db96d56Sopenharmony_ci_io._IOBase.writelines 7437db96d56Sopenharmony_ci lines: object 7447db96d56Sopenharmony_ci / 7457db96d56Sopenharmony_ci 7467db96d56Sopenharmony_ciWrite a list of lines to stream. 7477db96d56Sopenharmony_ci 7487db96d56Sopenharmony_ciLine separators are not added, so it is usual for each of the 7497db96d56Sopenharmony_cilines provided to have a line separator at the end. 7507db96d56Sopenharmony_ci[clinic start generated code]*/ 7517db96d56Sopenharmony_ci 7527db96d56Sopenharmony_cistatic PyObject * 7537db96d56Sopenharmony_ci_io__IOBase_writelines(PyObject *self, PyObject *lines) 7547db96d56Sopenharmony_ci/*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/ 7557db96d56Sopenharmony_ci{ 7567db96d56Sopenharmony_ci PyObject *iter, *res; 7577db96d56Sopenharmony_ci 7587db96d56Sopenharmony_ci if (iobase_check_closed(self)) 7597db96d56Sopenharmony_ci return NULL; 7607db96d56Sopenharmony_ci 7617db96d56Sopenharmony_ci iter = PyObject_GetIter(lines); 7627db96d56Sopenharmony_ci if (iter == NULL) 7637db96d56Sopenharmony_ci return NULL; 7647db96d56Sopenharmony_ci 7657db96d56Sopenharmony_ci while (1) { 7667db96d56Sopenharmony_ci PyObject *line = PyIter_Next(iter); 7677db96d56Sopenharmony_ci if (line == NULL) { 7687db96d56Sopenharmony_ci if (PyErr_Occurred()) { 7697db96d56Sopenharmony_ci Py_DECREF(iter); 7707db96d56Sopenharmony_ci return NULL; 7717db96d56Sopenharmony_ci } 7727db96d56Sopenharmony_ci else 7737db96d56Sopenharmony_ci break; /* Stop Iteration */ 7747db96d56Sopenharmony_ci } 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci res = NULL; 7777db96d56Sopenharmony_ci do { 7787db96d56Sopenharmony_ci res = PyObject_CallMethodObjArgs(self, &_Py_ID(write), line, NULL); 7797db96d56Sopenharmony_ci } while (res == NULL && _PyIO_trap_eintr()); 7807db96d56Sopenharmony_ci Py_DECREF(line); 7817db96d56Sopenharmony_ci if (res == NULL) { 7827db96d56Sopenharmony_ci Py_DECREF(iter); 7837db96d56Sopenharmony_ci return NULL; 7847db96d56Sopenharmony_ci } 7857db96d56Sopenharmony_ci Py_DECREF(res); 7867db96d56Sopenharmony_ci } 7877db96d56Sopenharmony_ci Py_DECREF(iter); 7887db96d56Sopenharmony_ci Py_RETURN_NONE; 7897db96d56Sopenharmony_ci} 7907db96d56Sopenharmony_ci 7917db96d56Sopenharmony_ci#include "clinic/iobase.c.h" 7927db96d56Sopenharmony_ci 7937db96d56Sopenharmony_cistatic PyMethodDef iobase_methods[] = { 7947db96d56Sopenharmony_ci {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc}, 7957db96d56Sopenharmony_ci _IO__IOBASE_TELL_METHODDEF 7967db96d56Sopenharmony_ci {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc}, 7977db96d56Sopenharmony_ci _IO__IOBASE_FLUSH_METHODDEF 7987db96d56Sopenharmony_ci _IO__IOBASE_CLOSE_METHODDEF 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci _IO__IOBASE_SEEKABLE_METHODDEF 8017db96d56Sopenharmony_ci _IO__IOBASE_READABLE_METHODDEF 8027db96d56Sopenharmony_ci _IO__IOBASE_WRITABLE_METHODDEF 8037db96d56Sopenharmony_ci 8047db96d56Sopenharmony_ci {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, 8057db96d56Sopenharmony_ci {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS}, 8067db96d56Sopenharmony_ci {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, 8077db96d56Sopenharmony_ci {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, 8087db96d56Sopenharmony_ci 8097db96d56Sopenharmony_ci _IO__IOBASE_FILENO_METHODDEF 8107db96d56Sopenharmony_ci _IO__IOBASE_ISATTY_METHODDEF 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci {"__enter__", iobase_enter, METH_NOARGS}, 8137db96d56Sopenharmony_ci {"__exit__", iobase_exit, METH_VARARGS}, 8147db96d56Sopenharmony_ci 8157db96d56Sopenharmony_ci _IO__IOBASE_READLINE_METHODDEF 8167db96d56Sopenharmony_ci _IO__IOBASE_READLINES_METHODDEF 8177db96d56Sopenharmony_ci _IO__IOBASE_WRITELINES_METHODDEF 8187db96d56Sopenharmony_ci 8197db96d56Sopenharmony_ci {NULL, NULL} 8207db96d56Sopenharmony_ci}; 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_cistatic PyGetSetDef iobase_getset[] = { 8237db96d56Sopenharmony_ci {"__dict__", PyObject_GenericGetDict, NULL, NULL}, 8247db96d56Sopenharmony_ci {"closed", (getter)iobase_closed_get, NULL, NULL}, 8257db96d56Sopenharmony_ci {NULL} 8267db96d56Sopenharmony_ci}; 8277db96d56Sopenharmony_ci 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ciPyTypeObject PyIOBase_Type = { 8307db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 8317db96d56Sopenharmony_ci "_io._IOBase", /*tp_name*/ 8327db96d56Sopenharmony_ci sizeof(iobase), /*tp_basicsize*/ 8337db96d56Sopenharmony_ci 0, /*tp_itemsize*/ 8347db96d56Sopenharmony_ci (destructor)iobase_dealloc, /*tp_dealloc*/ 8357db96d56Sopenharmony_ci 0, /*tp_vectorcall_offset*/ 8367db96d56Sopenharmony_ci 0, /*tp_getattr*/ 8377db96d56Sopenharmony_ci 0, /*tp_setattr*/ 8387db96d56Sopenharmony_ci 0, /*tp_as_async*/ 8397db96d56Sopenharmony_ci 0, /*tp_repr*/ 8407db96d56Sopenharmony_ci 0, /*tp_as_number*/ 8417db96d56Sopenharmony_ci 0, /*tp_as_sequence*/ 8427db96d56Sopenharmony_ci 0, /*tp_as_mapping*/ 8437db96d56Sopenharmony_ci 0, /*tp_hash */ 8447db96d56Sopenharmony_ci 0, /*tp_call*/ 8457db96d56Sopenharmony_ci 0, /*tp_str*/ 8467db96d56Sopenharmony_ci 0, /*tp_getattro*/ 8477db96d56Sopenharmony_ci 0, /*tp_setattro*/ 8487db96d56Sopenharmony_ci 0, /*tp_as_buffer*/ 8497db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE 8507db96d56Sopenharmony_ci | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 8517db96d56Sopenharmony_ci iobase_doc, /* tp_doc */ 8527db96d56Sopenharmony_ci (traverseproc)iobase_traverse, /* tp_traverse */ 8537db96d56Sopenharmony_ci (inquiry)iobase_clear, /* tp_clear */ 8547db96d56Sopenharmony_ci 0, /* tp_richcompare */ 8557db96d56Sopenharmony_ci offsetof(iobase, weakreflist), /* tp_weaklistoffset */ 8567db96d56Sopenharmony_ci iobase_iter, /* tp_iter */ 8577db96d56Sopenharmony_ci iobase_iternext, /* tp_iternext */ 8587db96d56Sopenharmony_ci iobase_methods, /* tp_methods */ 8597db96d56Sopenharmony_ci 0, /* tp_members */ 8607db96d56Sopenharmony_ci iobase_getset, /* tp_getset */ 8617db96d56Sopenharmony_ci 0, /* tp_base */ 8627db96d56Sopenharmony_ci 0, /* tp_dict */ 8637db96d56Sopenharmony_ci 0, /* tp_descr_get */ 8647db96d56Sopenharmony_ci 0, /* tp_descr_set */ 8657db96d56Sopenharmony_ci offsetof(iobase, dict), /* tp_dictoffset */ 8667db96d56Sopenharmony_ci 0, /* tp_init */ 8677db96d56Sopenharmony_ci 0, /* tp_alloc */ 8687db96d56Sopenharmony_ci PyType_GenericNew, /* tp_new */ 8697db96d56Sopenharmony_ci 0, /* tp_free */ 8707db96d56Sopenharmony_ci 0, /* tp_is_gc */ 8717db96d56Sopenharmony_ci 0, /* tp_bases */ 8727db96d56Sopenharmony_ci 0, /* tp_mro */ 8737db96d56Sopenharmony_ci 0, /* tp_cache */ 8747db96d56Sopenharmony_ci 0, /* tp_subclasses */ 8757db96d56Sopenharmony_ci 0, /* tp_weaklist */ 8767db96d56Sopenharmony_ci 0, /* tp_del */ 8777db96d56Sopenharmony_ci 0, /* tp_version_tag */ 8787db96d56Sopenharmony_ci iobase_finalize, /* tp_finalize */ 8797db96d56Sopenharmony_ci}; 8807db96d56Sopenharmony_ci 8817db96d56Sopenharmony_ci 8827db96d56Sopenharmony_ci/* 8837db96d56Sopenharmony_ci * RawIOBase class, Inherits from IOBase. 8847db96d56Sopenharmony_ci */ 8857db96d56Sopenharmony_ciPyDoc_STRVAR(rawiobase_doc, 8867db96d56Sopenharmony_ci "Base class for raw binary I/O."); 8877db96d56Sopenharmony_ci 8887db96d56Sopenharmony_ci/* 8897db96d56Sopenharmony_ci * The read() method is implemented by calling readinto(); derived classes 8907db96d56Sopenharmony_ci * that want to support read() only need to implement readinto() as a 8917db96d56Sopenharmony_ci * primitive operation. In general, readinto() can be more efficient than 8927db96d56Sopenharmony_ci * read(). 8937db96d56Sopenharmony_ci * 8947db96d56Sopenharmony_ci * (It would be tempting to also provide an implementation of readinto() in 8957db96d56Sopenharmony_ci * terms of read(), in case the latter is a more suitable primitive operation, 8967db96d56Sopenharmony_ci * but that would lead to nasty recursion in case a subclass doesn't implement 8977db96d56Sopenharmony_ci * either.) 8987db96d56Sopenharmony_ci*/ 8997db96d56Sopenharmony_ci 9007db96d56Sopenharmony_ci/*[clinic input] 9017db96d56Sopenharmony_ci_io._RawIOBase.read 9027db96d56Sopenharmony_ci size as n: Py_ssize_t = -1 9037db96d56Sopenharmony_ci / 9047db96d56Sopenharmony_ci[clinic start generated code]*/ 9057db96d56Sopenharmony_ci 9067db96d56Sopenharmony_cistatic PyObject * 9077db96d56Sopenharmony_ci_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) 9087db96d56Sopenharmony_ci/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/ 9097db96d56Sopenharmony_ci{ 9107db96d56Sopenharmony_ci PyObject *b, *res; 9117db96d56Sopenharmony_ci 9127db96d56Sopenharmony_ci if (n < 0) { 9137db96d56Sopenharmony_ci return PyObject_CallMethodNoArgs(self, &_Py_ID(readall)); 9147db96d56Sopenharmony_ci } 9157db96d56Sopenharmony_ci 9167db96d56Sopenharmony_ci /* TODO: allocate a bytes object directly instead and manually construct 9177db96d56Sopenharmony_ci a writable memoryview pointing to it. */ 9187db96d56Sopenharmony_ci b = PyByteArray_FromStringAndSize(NULL, n); 9197db96d56Sopenharmony_ci if (b == NULL) 9207db96d56Sopenharmony_ci return NULL; 9217db96d56Sopenharmony_ci 9227db96d56Sopenharmony_ci res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL); 9237db96d56Sopenharmony_ci if (res == NULL || res == Py_None) { 9247db96d56Sopenharmony_ci Py_DECREF(b); 9257db96d56Sopenharmony_ci return res; 9267db96d56Sopenharmony_ci } 9277db96d56Sopenharmony_ci 9287db96d56Sopenharmony_ci n = PyNumber_AsSsize_t(res, PyExc_ValueError); 9297db96d56Sopenharmony_ci Py_DECREF(res); 9307db96d56Sopenharmony_ci if (n == -1 && PyErr_Occurred()) { 9317db96d56Sopenharmony_ci Py_DECREF(b); 9327db96d56Sopenharmony_ci return NULL; 9337db96d56Sopenharmony_ci } 9347db96d56Sopenharmony_ci 9357db96d56Sopenharmony_ci res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); 9367db96d56Sopenharmony_ci Py_DECREF(b); 9377db96d56Sopenharmony_ci return res; 9387db96d56Sopenharmony_ci} 9397db96d56Sopenharmony_ci 9407db96d56Sopenharmony_ci 9417db96d56Sopenharmony_ci/*[clinic input] 9427db96d56Sopenharmony_ci_io._RawIOBase.readall 9437db96d56Sopenharmony_ci 9447db96d56Sopenharmony_ciRead until EOF, using multiple read() call. 9457db96d56Sopenharmony_ci[clinic start generated code]*/ 9467db96d56Sopenharmony_ci 9477db96d56Sopenharmony_cistatic PyObject * 9487db96d56Sopenharmony_ci_io__RawIOBase_readall_impl(PyObject *self) 9497db96d56Sopenharmony_ci/*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/ 9507db96d56Sopenharmony_ci{ 9517db96d56Sopenharmony_ci int r; 9527db96d56Sopenharmony_ci PyObject *chunks = PyList_New(0); 9537db96d56Sopenharmony_ci PyObject *result; 9547db96d56Sopenharmony_ci 9557db96d56Sopenharmony_ci if (chunks == NULL) 9567db96d56Sopenharmony_ci return NULL; 9577db96d56Sopenharmony_ci 9587db96d56Sopenharmony_ci while (1) { 9597db96d56Sopenharmony_ci PyObject *data = _PyObject_CallMethod(self, &_Py_ID(read), 9607db96d56Sopenharmony_ci "i", DEFAULT_BUFFER_SIZE); 9617db96d56Sopenharmony_ci if (!data) { 9627db96d56Sopenharmony_ci /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() 9637db96d56Sopenharmony_ci when EINTR occurs so we needn't do it ourselves. */ 9647db96d56Sopenharmony_ci if (_PyIO_trap_eintr()) { 9657db96d56Sopenharmony_ci continue; 9667db96d56Sopenharmony_ci } 9677db96d56Sopenharmony_ci Py_DECREF(chunks); 9687db96d56Sopenharmony_ci return NULL; 9697db96d56Sopenharmony_ci } 9707db96d56Sopenharmony_ci if (data == Py_None) { 9717db96d56Sopenharmony_ci if (PyList_GET_SIZE(chunks) == 0) { 9727db96d56Sopenharmony_ci Py_DECREF(chunks); 9737db96d56Sopenharmony_ci return data; 9747db96d56Sopenharmony_ci } 9757db96d56Sopenharmony_ci Py_DECREF(data); 9767db96d56Sopenharmony_ci break; 9777db96d56Sopenharmony_ci } 9787db96d56Sopenharmony_ci if (!PyBytes_Check(data)) { 9797db96d56Sopenharmony_ci Py_DECREF(chunks); 9807db96d56Sopenharmony_ci Py_DECREF(data); 9817db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "read() should return bytes"); 9827db96d56Sopenharmony_ci return NULL; 9837db96d56Sopenharmony_ci } 9847db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(data) == 0) { 9857db96d56Sopenharmony_ci /* EOF */ 9867db96d56Sopenharmony_ci Py_DECREF(data); 9877db96d56Sopenharmony_ci break; 9887db96d56Sopenharmony_ci } 9897db96d56Sopenharmony_ci r = PyList_Append(chunks, data); 9907db96d56Sopenharmony_ci Py_DECREF(data); 9917db96d56Sopenharmony_ci if (r < 0) { 9927db96d56Sopenharmony_ci Py_DECREF(chunks); 9937db96d56Sopenharmony_ci return NULL; 9947db96d56Sopenharmony_ci } 9957db96d56Sopenharmony_ci } 9967db96d56Sopenharmony_ci result = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks); 9977db96d56Sopenharmony_ci Py_DECREF(chunks); 9987db96d56Sopenharmony_ci return result; 9997db96d56Sopenharmony_ci} 10007db96d56Sopenharmony_ci 10017db96d56Sopenharmony_cistatic PyObject * 10027db96d56Sopenharmony_cirawiobase_readinto(PyObject *self, PyObject *args) 10037db96d56Sopenharmony_ci{ 10047db96d56Sopenharmony_ci PyErr_SetNone(PyExc_NotImplementedError); 10057db96d56Sopenharmony_ci return NULL; 10067db96d56Sopenharmony_ci} 10077db96d56Sopenharmony_ci 10087db96d56Sopenharmony_cistatic PyObject * 10097db96d56Sopenharmony_cirawiobase_write(PyObject *self, PyObject *args) 10107db96d56Sopenharmony_ci{ 10117db96d56Sopenharmony_ci PyErr_SetNone(PyExc_NotImplementedError); 10127db96d56Sopenharmony_ci return NULL; 10137db96d56Sopenharmony_ci} 10147db96d56Sopenharmony_ci 10157db96d56Sopenharmony_cistatic PyMethodDef rawiobase_methods[] = { 10167db96d56Sopenharmony_ci _IO__RAWIOBASE_READ_METHODDEF 10177db96d56Sopenharmony_ci _IO__RAWIOBASE_READALL_METHODDEF 10187db96d56Sopenharmony_ci {"readinto", rawiobase_readinto, METH_VARARGS}, 10197db96d56Sopenharmony_ci {"write", rawiobase_write, METH_VARARGS}, 10207db96d56Sopenharmony_ci {NULL, NULL} 10217db96d56Sopenharmony_ci}; 10227db96d56Sopenharmony_ci 10237db96d56Sopenharmony_ciPyTypeObject PyRawIOBase_Type = { 10247db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 10257db96d56Sopenharmony_ci "_io._RawIOBase", /*tp_name*/ 10267db96d56Sopenharmony_ci 0, /*tp_basicsize*/ 10277db96d56Sopenharmony_ci 0, /*tp_itemsize*/ 10287db96d56Sopenharmony_ci 0, /*tp_dealloc*/ 10297db96d56Sopenharmony_ci 0, /*tp_vectorcall_offset*/ 10307db96d56Sopenharmony_ci 0, /*tp_getattr*/ 10317db96d56Sopenharmony_ci 0, /*tp_setattr*/ 10327db96d56Sopenharmony_ci 0, /*tp_as_async*/ 10337db96d56Sopenharmony_ci 0, /*tp_repr*/ 10347db96d56Sopenharmony_ci 0, /*tp_as_number*/ 10357db96d56Sopenharmony_ci 0, /*tp_as_sequence*/ 10367db96d56Sopenharmony_ci 0, /*tp_as_mapping*/ 10377db96d56Sopenharmony_ci 0, /*tp_hash */ 10387db96d56Sopenharmony_ci 0, /*tp_call*/ 10397db96d56Sopenharmony_ci 0, /*tp_str*/ 10407db96d56Sopenharmony_ci 0, /*tp_getattro*/ 10417db96d56Sopenharmony_ci 0, /*tp_setattro*/ 10427db96d56Sopenharmony_ci 0, /*tp_as_buffer*/ 10437db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 10447db96d56Sopenharmony_ci rawiobase_doc, /* tp_doc */ 10457db96d56Sopenharmony_ci 0, /* tp_traverse */ 10467db96d56Sopenharmony_ci 0, /* tp_clear */ 10477db96d56Sopenharmony_ci 0, /* tp_richcompare */ 10487db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 10497db96d56Sopenharmony_ci 0, /* tp_iter */ 10507db96d56Sopenharmony_ci 0, /* tp_iternext */ 10517db96d56Sopenharmony_ci rawiobase_methods, /* tp_methods */ 10527db96d56Sopenharmony_ci 0, /* tp_members */ 10537db96d56Sopenharmony_ci 0, /* tp_getset */ 10547db96d56Sopenharmony_ci &PyIOBase_Type, /* tp_base */ 10557db96d56Sopenharmony_ci 0, /* tp_dict */ 10567db96d56Sopenharmony_ci 0, /* tp_descr_get */ 10577db96d56Sopenharmony_ci 0, /* tp_descr_set */ 10587db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 10597db96d56Sopenharmony_ci 0, /* tp_init */ 10607db96d56Sopenharmony_ci 0, /* tp_alloc */ 10617db96d56Sopenharmony_ci 0, /* tp_new */ 10627db96d56Sopenharmony_ci 0, /* tp_free */ 10637db96d56Sopenharmony_ci 0, /* tp_is_gc */ 10647db96d56Sopenharmony_ci 0, /* tp_bases */ 10657db96d56Sopenharmony_ci 0, /* tp_mro */ 10667db96d56Sopenharmony_ci 0, /* tp_cache */ 10677db96d56Sopenharmony_ci 0, /* tp_subclasses */ 10687db96d56Sopenharmony_ci 0, /* tp_weaklist */ 10697db96d56Sopenharmony_ci 0, /* tp_del */ 10707db96d56Sopenharmony_ci 0, /* tp_version_tag */ 10717db96d56Sopenharmony_ci 0, /* tp_finalize */ 10727db96d56Sopenharmony_ci}; 1073