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