LCOV - code coverage report
Current view: top level - Modules/_io - iobase.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 0 323 0.0 %
Date: 2017-04-19 Functions: 0 30 0.0 %

          Line data    Source code
       1             : /*
       2             :     An implementation of the I/O abstract base classes hierarchy
       3             :     as defined by PEP 3116 - "New I/O"
       4             :     
       5             :     Classes defined here: IOBase, RawIOBase.
       6             :     
       7             :     Written by Amaury Forgeot d'Arc and Antoine Pitrou
       8             : */
       9             : 
      10             : 
      11             : #define PY_SSIZE_T_CLEAN
      12             : #include "Python.h"
      13             : #include "structmember.h"
      14             : #include "_iomodule.h"
      15             : 
      16             : /*
      17             :  * IOBase class, an abstract class
      18             :  */
      19             : 
      20             : typedef struct {
      21             :     PyObject_HEAD
      22             :     
      23             :     PyObject *dict;
      24             :     PyObject *weakreflist;
      25             : } iobase;
      26             : 
      27             : PyDoc_STRVAR(iobase_doc,
      28             :     "The abstract base class for all I/O classes, acting on streams of\n"
      29             :     "bytes. There is no public constructor.\n"
      30             :     "\n"
      31             :     "This class provides dummy implementations for many methods that\n"
      32             :     "derived classes can override selectively; the default implementations\n"
      33             :     "represent a file that cannot be read, written or seeked.\n"
      34             :     "\n"
      35             :     "Even though IOBase does not declare read, readinto, or write because\n"
      36             :     "their signatures will vary, implementations and clients should\n"
      37             :     "consider those methods part of the interface. Also, implementations\n"
      38             :     "may raise an IOError when operations they do not support are called.\n"
      39             :     "\n"
      40             :     "The basic type used for binary data read from or written to a file is\n"
      41             :     "the bytes type. Method arguments may also be bytearray or memoryview\n"
      42             :     "of arrays of bytes. In some cases, such as readinto, a writable\n"
      43             :     "object such as bytearray is required. Text I/O classes work with\n"
      44             :     "unicode data.\n"
      45             :     "\n"
      46             :     "Note that calling any method (except additional calls to close(),\n"
      47             :     "which are ignored) on a closed stream should raise a ValueError.\n"
      48             :     "\n"
      49             :     "IOBase (and its subclasses) support the iterator protocol, meaning\n"
      50             :     "that an IOBase object can be iterated over yielding the lines in a\n"
      51             :     "stream.\n"
      52             :     "\n"
      53             :     "IOBase also supports the :keyword:`with` statement. In this example,\n"
      54             :     "fp is closed after the suite of the with statement is complete:\n"
      55             :     "\n"
      56             :     "with open('spam.txt', 'r') as fp:\n"
      57             :     "    fp.write('Spam and eggs!')\n");
      58             : 
      59             : /* Use this macro whenever you want to check the internal `closed` status
      60             :    of the IOBase object rather than the virtual `closed` attribute as returned
      61             :    by whatever subclass. */
      62             : 
      63             : #define IS_CLOSED(self) \
      64             :     PyObject_HasAttrString(self, "__IOBase_closed")
      65             : 
      66             : /* Internal methods */
      67             : static PyObject *
      68           0 : iobase_unsupported(const char *message)
      69             : {
      70           0 :     PyErr_SetString(_PyIO_unsupported_operation, message);
      71           0 :     return NULL;
      72             : }
      73             : 
      74             : /* Positioning */
      75             : 
      76             : PyDoc_STRVAR(iobase_seek_doc,
      77             :     "Change stream position.\n"
      78             :     "\n"
      79             :     "Change the stream position to the given byte offset. The offset is\n"
      80             :     "interpreted relative to the position indicated by whence.  Values\n"
      81             :     "for whence are:\n"
      82             :     "\n"
      83             :     "* 0 -- start of stream (the default); offset should be zero or positive\n"
      84             :     "* 1 -- current stream position; offset may be negative\n"
      85             :     "* 2 -- end of stream; offset is usually negative\n"
      86             :     "\n"
      87             :     "Return the new absolute position.");
      88             : 
      89             : static PyObject *
      90           0 : iobase_seek(PyObject *self, PyObject *args)
      91             : {
      92           0 :     return iobase_unsupported("seek");
      93             : }
      94             : 
      95             : PyDoc_STRVAR(iobase_tell_doc,
      96             :              "Return current stream position.");
      97             : 
      98             : static PyObject *
      99           0 : iobase_tell(PyObject *self, PyObject *args)
     100             : {
     101           0 :     return PyObject_CallMethod(self, "seek", "ii", 0, 1);
     102             : }
     103             : 
     104             : PyDoc_STRVAR(iobase_truncate_doc,
     105             :     "Truncate file to size bytes.\n"
     106             :     "\n"
     107             :     "File pointer is left unchanged.  Size defaults to the current IO\n"
     108             :     "position as reported by tell().  Returns the new size.");
     109             : 
     110             : static PyObject *
     111           0 : iobase_truncate(PyObject *self, PyObject *args)
     112             : {
     113           0 :     return iobase_unsupported("truncate");
     114             : }
     115             : 
     116             : /* Flush and close methods */
     117             : 
     118             : PyDoc_STRVAR(iobase_flush_doc,
     119             :     "Flush write buffers, if applicable.\n"
     120             :     "\n"
     121             :     "This is not implemented for read-only and non-blocking streams.\n");
     122             : 
     123             : static PyObject *
     124           0 : iobase_flush(PyObject *self, PyObject *args)
     125             : {
     126             :     /* XXX Should this return the number of bytes written??? */
     127           0 :     if (IS_CLOSED(self)) {
     128           0 :         PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
     129           0 :         return NULL;
     130             :     }
     131           0 :     Py_RETURN_NONE;
     132             : }
     133             : 
     134             : PyDoc_STRVAR(iobase_close_doc,
     135             :     "Flush and close the IO object.\n"
     136             :     "\n"
     137             :     "This method has no effect if the file is already closed.\n");
     138             : 
     139             : static int
     140           0 : iobase_closed(PyObject *self)
     141             : {
     142             :     PyObject *res;
     143             :     int closed;
     144             :     /* This gets the derived attribute, which is *not* __IOBase_closed
     145             :        in most cases! */
     146           0 :     res = PyObject_GetAttr(self, _PyIO_str_closed);
     147           0 :     if (res == NULL)
     148           0 :         return 0;
     149           0 :     closed = PyObject_IsTrue(res);
     150           0 :     Py_DECREF(res);
     151           0 :     return closed;
     152             : }
     153             : 
     154             : static PyObject *
     155           0 : iobase_closed_get(PyObject *self, void *context)
     156             : {
     157           0 :     return PyBool_FromLong(IS_CLOSED(self));
     158             : }
     159             : 
     160             : PyObject *
     161           0 : _PyIOBase_check_closed(PyObject *self, PyObject *args)
     162             : {
     163           0 :     if (iobase_closed(self)) {
     164           0 :         PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
     165           0 :         return NULL;
     166             :     }
     167           0 :     if (args == Py_True)
     168           0 :         return Py_None;
     169             :     else
     170           0 :         Py_RETURN_NONE;
     171             : }
     172             : 
     173             : /* XXX: IOBase thinks it has to maintain its own internal state in
     174             :    `__IOBase_closed` and call flush() by itself, but it is redundant with
     175             :    whatever behaviour a non-trivial derived class will implement. */
     176             : 
     177             : static PyObject *
     178           0 : iobase_close(PyObject *self, PyObject *args)
     179             : {
     180             :     PyObject *res;
     181             : 
     182           0 :     if (IS_CLOSED(self))
     183           0 :         Py_RETURN_NONE;
     184             : 
     185           0 :     res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
     186           0 :     PyObject_SetAttrString(self, "__IOBase_closed", Py_True);
     187           0 :     if (res == NULL) {
     188           0 :         return NULL;
     189             :     }
     190           0 :     Py_XDECREF(res);
     191           0 :     Py_RETURN_NONE;
     192             : }
     193             : 
     194             : /* Finalization and garbage collection support */
     195             : 
     196             : int
     197           0 : _PyIOBase_finalize(PyObject *self)
     198             : {
     199             :     PyObject *res;
     200             :     PyObject *tp, *v, *tb;
     201           0 :     int closed = 1;
     202             :     int is_zombie;
     203             : 
     204             :     /* If _PyIOBase_finalize() is called from a destructor, we need to
     205             :        resurrect the object as calling close() can invoke arbitrary code. */
     206           0 :     is_zombie = (Py_REFCNT(self) == 0);
     207           0 :     if (is_zombie) {
     208           0 :         ++Py_REFCNT(self);
     209             :     }
     210           0 :     PyErr_Fetch(&tp, &v, &tb);
     211             :     /* If `closed` doesn't exist or can't be evaluated as bool, then the
     212             :        object is probably in an unusable state, so ignore. */
     213           0 :     res = PyObject_GetAttr(self, _PyIO_str_closed);
     214           0 :     if (res == NULL)
     215           0 :         PyErr_Clear();
     216             :     else {
     217           0 :         closed = PyObject_IsTrue(res);
     218           0 :         Py_DECREF(res);
     219           0 :         if (closed == -1)
     220           0 :             PyErr_Clear();
     221             :     }
     222           0 :     if (closed == 0) {
     223           0 :         res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
     224             :                                           NULL);
     225             :         /* Silencing I/O errors is bad, but printing spurious tracebacks is
     226             :            equally as bad, and potentially more frequent (because of
     227             :            shutdown issues). */
     228           0 :         if (res == NULL)
     229           0 :             PyErr_Clear();
     230             :         else
     231           0 :             Py_DECREF(res);
     232             :     }
     233           0 :     PyErr_Restore(tp, v, tb);
     234           0 :     if (is_zombie) {
     235           0 :         if (--Py_REFCNT(self) != 0) {
     236             :             /* The object lives again. The following code is taken from
     237             :                slot_tp_del in typeobject.c. */
     238           0 :             Py_ssize_t refcnt = Py_REFCNT(self);
     239           0 :             _Py_NewReference(self);
     240           0 :             Py_REFCNT(self) = refcnt;
     241             :             /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
     242             :              * we need to undo that. */
     243             :             _Py_DEC_REFTOTAL;
     244             :             /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
     245             :              * chain, so no more to do there.
     246             :              * If COUNT_ALLOCS, the original decref bumped tp_frees, and
     247             :              * _Py_NewReference bumped tp_allocs:  both of those need to be
     248             :              * undone.
     249             :              */
     250             : #ifdef COUNT_ALLOCS
     251             :             --Py_TYPE(self)->tp_frees;
     252             :             --Py_TYPE(self)->tp_allocs;
     253             : #endif
     254           0 :             return -1;
     255             :         }
     256             :     }
     257           0 :     return 0;
     258             : }
     259             : 
     260             : static int
     261           0 : iobase_traverse(iobase *self, visitproc visit, void *arg)
     262             : {
     263           0 :     Py_VISIT(self->dict);
     264           0 :     return 0;
     265             : }
     266             : 
     267             : static int
     268           0 : iobase_clear(iobase *self)
     269             : {
     270           0 :     if (_PyIOBase_finalize((PyObject *) self) < 0)
     271           0 :         return -1;
     272           0 :     Py_CLEAR(self->dict);
     273           0 :     return 0;
     274             : }
     275             : 
     276             : /* Destructor */
     277             : 
     278             : static void
     279           0 : iobase_dealloc(iobase *self)
     280             : {
     281             :     /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
     282             :        are still available here for close() to use.
     283             :        However, if the derived class declares a __slots__, those slots are
     284             :        already gone.
     285             :     */
     286           0 :     if (_PyIOBase_finalize((PyObject *) self) < 0) {
     287             :         /* When called from a heap type's dealloc, the type will be
     288             :            decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
     289           0 :         if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
     290           0 :             Py_INCREF(Py_TYPE(self));
     291           0 :         return;
     292             :     }
     293           0 :     _PyObject_GC_UNTRACK(self);
     294           0 :     if (self->weakreflist != NULL)
     295           0 :         PyObject_ClearWeakRefs((PyObject *) self);
     296           0 :     Py_CLEAR(self->dict);
     297           0 :     Py_TYPE(self)->tp_free((PyObject *) self);
     298             : }
     299             : 
     300             : /* Inquiry methods */
     301             : 
     302             : PyDoc_STRVAR(iobase_seekable_doc,
     303             :     "Return whether object supports random access.\n"
     304             :     "\n"
     305             :     "If False, seek(), tell() and truncate() will raise IOError.\n"
     306             :     "This method may need to do a test seek().");
     307             : 
     308             : static PyObject *
     309           0 : iobase_seekable(PyObject *self, PyObject *args)
     310             : {
     311           0 :     Py_RETURN_FALSE;
     312             : }
     313             : 
     314             : PyObject *
     315           0 : _PyIOBase_check_seekable(PyObject *self, PyObject *args)
     316             : {
     317           0 :     PyObject *res  = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL);
     318           0 :     if (res == NULL)
     319           0 :         return NULL;
     320           0 :     if (res != Py_True) {
     321           0 :         Py_CLEAR(res);
     322           0 :         PyErr_SetString(PyExc_IOError, "File or stream is not seekable.");
     323           0 :         return NULL;
     324             :     }
     325           0 :     if (args == Py_True) {
     326           0 :         Py_DECREF(res);
     327             :     }
     328           0 :     return res;
     329             : }
     330             : 
     331             : PyDoc_STRVAR(iobase_readable_doc,
     332             :     "Return whether object was opened for reading.\n"
     333             :     "\n"
     334             :     "If False, read() will raise IOError.");
     335             : 
     336             : static PyObject *
     337           0 : iobase_readable(PyObject *self, PyObject *args)
     338             : {
     339           0 :     Py_RETURN_FALSE;
     340             : }
     341             : 
     342             : /* May be called with any object */
     343             : PyObject *
     344           0 : _PyIOBase_check_readable(PyObject *self, PyObject *args)
     345             : {
     346           0 :     PyObject *res  = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL);
     347           0 :     if (res == NULL)
     348           0 :         return NULL;
     349           0 :     if (res != Py_True) {
     350           0 :         Py_CLEAR(res);
     351           0 :         PyErr_SetString(PyExc_IOError, "File or stream is not readable.");
     352           0 :         return NULL;
     353             :     }
     354           0 :     if (args == Py_True) {
     355           0 :         Py_DECREF(res);
     356             :     }
     357           0 :     return res;
     358             : }
     359             : 
     360             : PyDoc_STRVAR(iobase_writable_doc,
     361             :     "Return whether object was opened for writing.\n"
     362             :     "\n"
     363             :     "If False, read() will raise IOError.");
     364             : 
     365             : static PyObject *
     366           0 : iobase_writable(PyObject *self, PyObject *args)
     367             : {
     368           0 :     Py_RETURN_FALSE;
     369             : }
     370             : 
     371             : /* May be called with any object */
     372             : PyObject *
     373           0 : _PyIOBase_check_writable(PyObject *self, PyObject *args)
     374             : {
     375           0 :     PyObject *res  = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL);
     376           0 :     if (res == NULL)
     377           0 :         return NULL;
     378           0 :     if (res != Py_True) {
     379           0 :         Py_CLEAR(res);
     380           0 :         PyErr_SetString(PyExc_IOError, "File or stream is not writable.");
     381           0 :         return NULL;
     382             :     }
     383           0 :     if (args == Py_True) {
     384           0 :         Py_DECREF(res);
     385             :     }
     386           0 :     return res;
     387             : }
     388             : 
     389             : /* Context manager */
     390             : 
     391             : static PyObject *
     392           0 : iobase_enter(PyObject *self, PyObject *args)
     393             : {
     394           0 :     if (_PyIOBase_check_closed(self, Py_True) == NULL)
     395           0 :         return NULL;
     396             : 
     397           0 :     Py_INCREF(self);
     398           0 :     return self;
     399             : }
     400             : 
     401             : static PyObject *
     402           0 : iobase_exit(PyObject *self, PyObject *args)
     403             : {
     404           0 :     return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL);
     405             : }
     406             : 
     407             : /* Lower-level APIs */
     408             : 
     409             : /* XXX Should these be present even if unimplemented? */
     410             : 
     411             : PyDoc_STRVAR(iobase_fileno_doc,
     412             :     "Returns underlying file descriptor if one exists.\n"
     413             :     "\n"
     414             :     "An IOError is raised if the IO object does not use a file descriptor.\n");
     415             : 
     416             : static PyObject *
     417           0 : iobase_fileno(PyObject *self, PyObject *args)
     418             : {
     419           0 :     return iobase_unsupported("fileno");
     420             : }
     421             : 
     422             : PyDoc_STRVAR(iobase_isatty_doc,
     423             :     "Return whether this is an 'interactive' stream.\n"
     424             :     "\n"
     425             :     "Return False if it can't be determined.\n");
     426             : 
     427             : static PyObject *
     428           0 : iobase_isatty(PyObject *self, PyObject *args)
     429             : {
     430           0 :     if (_PyIOBase_check_closed(self, Py_True) == NULL)
     431           0 :         return NULL;
     432           0 :     Py_RETURN_FALSE;
     433             : }
     434             : 
     435             : /* Readline(s) and writelines */
     436             : 
     437             : PyDoc_STRVAR(iobase_readline_doc,
     438             :     "Read and return a line from the stream.\n"
     439             :     "\n"
     440             :     "If limit is specified, at most limit bytes will be read.\n"
     441             :     "\n"
     442             :     "The line terminator is always b'\\n' for binary files; for text\n"
     443             :     "files, the newlines argument to open can be used to select the line\n"
     444             :     "terminator(s) recognized.\n");
     445             : 
     446             : static PyObject *
     447           0 : iobase_readline(PyObject *self, PyObject *args)
     448             : {
     449             :     /* For backwards compatibility, a (slowish) readline(). */
     450             : 
     451           0 :     Py_ssize_t limit = -1;
     452           0 :     int has_peek = 0;
     453             :     PyObject *buffer, *result;
     454           0 :     Py_ssize_t old_size = -1;
     455             : 
     456           0 :     if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
     457           0 :         return NULL;
     458             :     }
     459             : 
     460           0 :     if (PyObject_HasAttrString(self, "peek"))
     461           0 :         has_peek = 1;
     462             : 
     463           0 :     buffer = PyByteArray_FromStringAndSize(NULL, 0);
     464           0 :     if (buffer == NULL)
     465           0 :         return NULL;
     466             : 
     467           0 :     while (limit < 0 || Py_SIZE(buffer) < limit) {
     468           0 :         Py_ssize_t nreadahead = 1;
     469             :         PyObject *b;
     470             : 
     471           0 :         if (has_peek) {
     472           0 :             PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
     473           0 :             if (readahead == NULL) {
     474             :                 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
     475             :                    when EINTR occurs so we needn't do it ourselves. */
     476           0 :                 if (_PyIO_trap_eintr()) {
     477           0 :                     continue;
     478             :                 }
     479           0 :                 goto fail;
     480             :             }
     481           0 :             if (!PyBytes_Check(readahead)) {
     482           0 :                 PyErr_Format(PyExc_IOError,
     483             :                              "peek() should have returned a bytes object, "
     484           0 :                              "not '%.200s'", Py_TYPE(readahead)->tp_name);
     485           0 :                 Py_DECREF(readahead);
     486           0 :                 goto fail;
     487             :             }
     488           0 :             if (PyBytes_GET_SIZE(readahead) > 0) {
     489           0 :                 Py_ssize_t n = 0;
     490           0 :                 const char *buf = PyBytes_AS_STRING(readahead);
     491           0 :                 if (limit >= 0) {
     492             :                     do {
     493           0 :                         if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
     494             :                             break;
     495           0 :                         if (buf[n++] == '\n')
     496           0 :                             break;
     497           0 :                     } while (1);
     498             :                 }
     499             :                 else {
     500             :                     do {
     501           0 :                         if (n >= PyBytes_GET_SIZE(readahead))
     502           0 :                             break;
     503           0 :                         if (buf[n++] == '\n')
     504           0 :                             break;
     505           0 :                     } while (1);
     506             :                 }
     507           0 :                 nreadahead = n;
     508             :             }
     509           0 :             Py_DECREF(readahead);
     510             :         }
     511             : 
     512           0 :         b = PyObject_CallMethod(self, "read", "n", nreadahead);
     513           0 :         if (b == NULL) {
     514             :             /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
     515             :                when EINTR occurs so we needn't do it ourselves. */
     516           0 :             if (_PyIO_trap_eintr()) {
     517           0 :                 continue;
     518             :             }
     519           0 :             goto fail;
     520             :         }
     521           0 :         if (!PyBytes_Check(b)) {
     522           0 :             PyErr_Format(PyExc_IOError,
     523             :                          "read() should have returned a bytes object, "
     524           0 :                          "not '%.200s'", Py_TYPE(b)->tp_name);
     525           0 :             Py_DECREF(b);
     526           0 :             goto fail;
     527             :         }
     528           0 :         if (PyBytes_GET_SIZE(b) == 0) {
     529           0 :             Py_DECREF(b);
     530           0 :             break;
     531             :         }
     532             : 
     533           0 :         old_size = PyByteArray_GET_SIZE(buffer);
     534           0 :         if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) {
     535           0 :             Py_DECREF(b);
     536           0 :             goto fail;
     537             :         }
     538           0 :         memcpy(PyByteArray_AS_STRING(buffer) + old_size,
     539           0 :                PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
     540             : 
     541           0 :         Py_DECREF(b);
     542             : 
     543           0 :         if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
     544           0 :             break;
     545             :     }
     546             : 
     547           0 :     result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
     548             :                                        PyByteArray_GET_SIZE(buffer));
     549           0 :     Py_DECREF(buffer);
     550           0 :     return result;
     551             :   fail:
     552           0 :     Py_DECREF(buffer);
     553           0 :     return NULL;
     554             : }
     555             : 
     556             : static PyObject *
     557           0 : iobase_iter(PyObject *self)
     558             : {
     559           0 :     if (_PyIOBase_check_closed(self, Py_True) == NULL)
     560           0 :         return NULL;
     561             : 
     562           0 :     Py_INCREF(self);
     563           0 :     return self;
     564             : }
     565             : 
     566             : static PyObject *
     567           0 : iobase_iternext(PyObject *self)
     568             : {
     569           0 :     PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL);
     570             : 
     571           0 :     if (line == NULL)
     572           0 :         return NULL;
     573             : 
     574           0 :     if (PyObject_Size(line) == 0) {
     575           0 :         Py_DECREF(line);
     576           0 :         return NULL;
     577             :     }
     578             : 
     579           0 :     return line;
     580             : }
     581             : 
     582             : PyDoc_STRVAR(iobase_readlines_doc,
     583             :     "Return a list of lines from the stream.\n"
     584             :     "\n"
     585             :     "hint can be specified to control the number of lines read: no more\n"
     586             :     "lines will be read if the total size (in bytes/characters) of all\n"
     587             :     "lines so far exceeds hint.");
     588             : 
     589             : static PyObject *
     590           0 : iobase_readlines(PyObject *self, PyObject *args)
     591             : {
     592           0 :     Py_ssize_t hint = -1, length = 0;
     593             :     PyObject *result;
     594             : 
     595           0 :     if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) {
     596           0 :         return NULL;
     597             :     }
     598             : 
     599           0 :     result = PyList_New(0);
     600           0 :     if (result == NULL)
     601           0 :         return NULL;
     602             : 
     603           0 :     if (hint <= 0) {
     604             :         /* XXX special-casing this made sense in the Python version in order
     605             :            to remove the bytecode interpretation overhead, but it could
     606             :            probably be removed here. */
     607           0 :         PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
     608           0 :         if (ret == NULL) {
     609           0 :             Py_DECREF(result);
     610           0 :             return NULL;
     611             :         }
     612           0 :         Py_DECREF(ret);
     613           0 :         return result;
     614             :     }
     615             : 
     616             :     while (1) {
     617           0 :         PyObject *line = PyIter_Next(self);
     618           0 :         if (line == NULL) {
     619           0 :             if (PyErr_Occurred()) {
     620           0 :                 Py_DECREF(result);
     621           0 :                 return NULL;
     622             :             }
     623             :             else
     624           0 :                 break; /* StopIteration raised */
     625             :         }
     626             : 
     627           0 :         if (PyList_Append(result, line) < 0) {
     628           0 :             Py_DECREF(line);
     629           0 :             Py_DECREF(result);
     630           0 :             return NULL;
     631             :         }
     632           0 :         length += PyObject_Size(line);
     633           0 :         Py_DECREF(line);
     634             : 
     635           0 :         if (length > hint)
     636           0 :             break;
     637           0 :     }
     638           0 :     return result;
     639             : }
     640             : 
     641             : static PyObject *
     642           0 : iobase_writelines(PyObject *self, PyObject *args)
     643             : {
     644             :     PyObject *lines, *iter, *res;
     645             : 
     646           0 :     if (!PyArg_ParseTuple(args, "O:writelines", &lines)) {
     647           0 :         return NULL;
     648             :     }
     649             : 
     650           0 :     if (_PyIOBase_check_closed(self, Py_True) == NULL)
     651           0 :         return NULL;
     652             : 
     653           0 :     iter = PyObject_GetIter(lines);
     654           0 :     if (iter == NULL)
     655           0 :         return NULL;
     656             : 
     657             :     while (1) {
     658           0 :         PyObject *line = PyIter_Next(iter);
     659           0 :         if (line == NULL) {
     660           0 :             if (PyErr_Occurred()) {
     661           0 :                 Py_DECREF(iter);
     662           0 :                 return NULL;
     663             :             }
     664             :             else
     665           0 :                 break; /* Stop Iteration */
     666             :         }
     667             : 
     668           0 :         res = NULL;
     669             :         do {
     670           0 :             res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL);
     671           0 :         } while (res == NULL && _PyIO_trap_eintr());
     672           0 :         Py_DECREF(line);
     673           0 :         if (res == NULL) {
     674           0 :             Py_DECREF(iter);
     675           0 :             return NULL;
     676             :         }
     677           0 :         Py_DECREF(res);
     678           0 :     }
     679           0 :     Py_DECREF(iter);
     680           0 :     Py_RETURN_NONE;
     681             : }
     682             : 
     683             : static PyMethodDef iobase_methods[] = {
     684             :     {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc},
     685             :     {"tell", iobase_tell, METH_NOARGS, iobase_tell_doc},
     686             :     {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc},
     687             :     {"flush", iobase_flush, METH_NOARGS, iobase_flush_doc},
     688             :     {"close", iobase_close, METH_NOARGS, iobase_close_doc},
     689             : 
     690             :     {"seekable", iobase_seekable, METH_NOARGS, iobase_seekable_doc},
     691             :     {"readable", iobase_readable, METH_NOARGS, iobase_readable_doc},
     692             :     {"writable", iobase_writable, METH_NOARGS, iobase_writable_doc},
     693             : 
     694             :     {"_checkClosed",   _PyIOBase_check_closed, METH_NOARGS},
     695             :     {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS},
     696             :     {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS},
     697             :     {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS},
     698             : 
     699             :     {"fileno", iobase_fileno, METH_NOARGS, iobase_fileno_doc},
     700             :     {"isatty", iobase_isatty, METH_NOARGS, iobase_isatty_doc},
     701             : 
     702             :     {"__enter__", iobase_enter, METH_NOARGS},
     703             :     {"__exit__", iobase_exit, METH_VARARGS},
     704             : 
     705             :     {"readline", iobase_readline, METH_VARARGS, iobase_readline_doc},
     706             :     {"readlines", iobase_readlines, METH_VARARGS, iobase_readlines_doc},
     707             :     {"writelines", iobase_writelines, METH_VARARGS},
     708             : 
     709             :     {NULL, NULL}
     710             : };
     711             : 
     712             : static PyGetSetDef iobase_getset[] = {
     713             :     {"closed", (getter)iobase_closed_get, NULL, NULL},
     714             :     {NULL}
     715             : };
     716             : 
     717             : 
     718             : PyTypeObject PyIOBase_Type = {
     719             :     PyVarObject_HEAD_INIT(NULL, 0)
     720             :     "_io._IOBase",              /*tp_name*/
     721             :     sizeof(iobase),             /*tp_basicsize*/
     722             :     0,                          /*tp_itemsize*/
     723             :     (destructor)iobase_dealloc, /*tp_dealloc*/
     724             :     0,                          /*tp_print*/
     725             :     0,                          /*tp_getattr*/
     726             :     0,                          /*tp_setattr*/
     727             :     0,                          /*tp_compare */
     728             :     0,                          /*tp_repr*/
     729             :     0,                          /*tp_as_number*/
     730             :     0,                          /*tp_as_sequence*/
     731             :     0,                          /*tp_as_mapping*/
     732             :     0,                          /*tp_hash */
     733             :     0,                          /*tp_call*/
     734             :     0,                          /*tp_str*/
     735             :     0,                          /*tp_getattro*/
     736             :     0,                          /*tp_setattro*/
     737             :     0,                          /*tp_as_buffer*/
     738             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
     739             :         | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
     740             :     iobase_doc,                 /* tp_doc */
     741             :     (traverseproc)iobase_traverse, /* tp_traverse */
     742             :     (inquiry)iobase_clear,      /* tp_clear */
     743             :     0,                          /* tp_richcompare */
     744             :     offsetof(iobase, weakreflist), /* tp_weaklistoffset */
     745             :     iobase_iter,                /* tp_iter */
     746             :     iobase_iternext,            /* tp_iternext */
     747             :     iobase_methods,             /* tp_methods */
     748             :     0,                          /* tp_members */
     749             :     iobase_getset,              /* tp_getset */
     750             :     0,                          /* tp_base */
     751             :     0,                          /* tp_dict */
     752             :     0,                          /* tp_descr_get */
     753             :     0,                          /* tp_descr_set */
     754             :     offsetof(iobase, dict),     /* tp_dictoffset */
     755             :     0,                          /* tp_init */
     756             :     0,                          /* tp_alloc */
     757             :     PyType_GenericNew,          /* tp_new */
     758             : };
     759             : 
     760             : 
     761             : /*
     762             :  * RawIOBase class, Inherits from IOBase.
     763             :  */
     764             : PyDoc_STRVAR(rawiobase_doc,
     765             :              "Base class for raw binary I/O.");
     766             : 
     767             : /*
     768             :  * The read() method is implemented by calling readinto(); derived classes
     769             :  * that want to support read() only need to implement readinto() as a
     770             :  * primitive operation.  In general, readinto() can be more efficient than
     771             :  * read().
     772             :  *
     773             :  * (It would be tempting to also provide an implementation of readinto() in
     774             :  * terms of read(), in case the latter is a more suitable primitive operation,
     775             :  * but that would lead to nasty recursion in case a subclass doesn't implement
     776             :  * either.)
     777             : */
     778             : 
     779             : static PyObject *
     780           0 : rawiobase_read(PyObject *self, PyObject *args)
     781             : {
     782           0 :     Py_ssize_t n = -1;
     783             :     PyObject *b, *res;
     784             : 
     785           0 :     if (!PyArg_ParseTuple(args, "|n:read", &n)) {
     786           0 :         return NULL;
     787             :     }
     788             : 
     789           0 :     if (n < 0)
     790           0 :         return PyObject_CallMethod(self, "readall", NULL);
     791             : 
     792             :     /* TODO: allocate a bytes object directly instead and manually construct
     793             :        a writable memoryview pointing to it. */
     794           0 :     b = PyByteArray_FromStringAndSize(NULL, n);
     795           0 :     if (b == NULL)
     796           0 :         return NULL;
     797             : 
     798           0 :     res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
     799           0 :     if (res == NULL || res == Py_None) {
     800           0 :         Py_DECREF(b);
     801           0 :         return res;
     802             :     }
     803             : 
     804           0 :     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
     805           0 :     Py_DECREF(res);
     806           0 :     if (n == -1 && PyErr_Occurred()) {
     807           0 :         Py_DECREF(b);
     808           0 :         return NULL;
     809             :     }
     810             : 
     811           0 :     res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
     812           0 :     Py_DECREF(b);
     813           0 :     return res;
     814             : }
     815             : 
     816             : 
     817             : PyDoc_STRVAR(rawiobase_readall_doc,
     818             :              "Read until EOF, using multiple read() call.");
     819             : 
     820             : static PyObject *
     821           0 : rawiobase_readall(PyObject *self, PyObject *args)
     822             : {
     823             :     int r;
     824           0 :     PyObject *chunks = PyList_New(0);
     825             :     PyObject *result;
     826             :     
     827           0 :     if (chunks == NULL)
     828           0 :         return NULL;
     829             : 
     830             :     while (1) {
     831           0 :         PyObject *data = PyObject_CallMethod(self, "read",
     832             :                                              "i", DEFAULT_BUFFER_SIZE);
     833           0 :         if (!data) {
     834             :             /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
     835             :                when EINTR occurs so we needn't do it ourselves. */
     836           0 :             if (_PyIO_trap_eintr()) {
     837           0 :                 continue;
     838             :             }
     839           0 :             Py_DECREF(chunks);
     840           0 :             return NULL;
     841             :         }
     842           0 :         if (data == Py_None) {
     843           0 :             if (PyList_GET_SIZE(chunks) == 0) {
     844           0 :                 Py_DECREF(chunks);
     845           0 :                 return data;
     846             :             }
     847           0 :             Py_DECREF(data);
     848           0 :             break;
     849             :         }
     850           0 :         if (!PyBytes_Check(data)) {
     851           0 :             Py_DECREF(chunks);
     852           0 :             Py_DECREF(data);
     853           0 :             PyErr_SetString(PyExc_TypeError, "read() should return bytes");
     854           0 :             return NULL;
     855             :         }
     856           0 :         if (PyBytes_GET_SIZE(data) == 0) {
     857             :             /* EOF */
     858           0 :             Py_DECREF(data);
     859           0 :             break;
     860             :         }
     861           0 :         r = PyList_Append(chunks, data);
     862           0 :         Py_DECREF(data);
     863           0 :         if (r < 0) {
     864           0 :             Py_DECREF(chunks);
     865           0 :             return NULL;
     866             :         }
     867           0 :     }
     868           0 :     result = _PyBytes_Join(_PyIO_empty_bytes, chunks);
     869           0 :     Py_DECREF(chunks);
     870           0 :     return result;
     871             : }
     872             : 
     873             : static PyMethodDef rawiobase_methods[] = {
     874             :     {"read", rawiobase_read, METH_VARARGS},
     875             :     {"readall", rawiobase_readall, METH_NOARGS, rawiobase_readall_doc},
     876             :     {NULL, NULL}
     877             : };
     878             : 
     879             : PyTypeObject PyRawIOBase_Type = {
     880             :     PyVarObject_HEAD_INIT(NULL, 0)
     881             :     "_io._RawIOBase",                /*tp_name*/
     882             :     0,                          /*tp_basicsize*/
     883             :     0,                          /*tp_itemsize*/
     884             :     0,                          /*tp_dealloc*/
     885             :     0,                          /*tp_print*/
     886             :     0,                          /*tp_getattr*/
     887             :     0,                          /*tp_setattr*/
     888             :     0,                          /*tp_compare */
     889             :     0,                          /*tp_repr*/
     890             :     0,                          /*tp_as_number*/
     891             :     0,                          /*tp_as_sequence*/
     892             :     0,                          /*tp_as_mapping*/
     893             :     0,                          /*tp_hash */
     894             :     0,                          /*tp_call*/
     895             :     0,                          /*tp_str*/
     896             :     0,                          /*tp_getattro*/
     897             :     0,                          /*tp_setattro*/
     898             :     0,                          /*tp_as_buffer*/
     899             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
     900             :     rawiobase_doc,              /* tp_doc */
     901             :     0,                          /* tp_traverse */
     902             :     0,                          /* tp_clear */
     903             :     0,                          /* tp_richcompare */
     904             :     0,                          /* tp_weaklistoffset */
     905             :     0,                          /* tp_iter */
     906             :     0,                          /* tp_iternext */
     907             :     rawiobase_methods,          /* tp_methods */
     908             :     0,                          /* tp_members */
     909             :     0,                          /* tp_getset */
     910             :     &PyIOBase_Type,             /* tp_base */
     911             :     0,                          /* tp_dict */
     912             :     0,                          /* tp_descr_get */
     913             :     0,                          /* tp_descr_set */
     914             :     0,                          /* tp_dictoffset */
     915             :     0,                          /* tp_init */
     916             :     0,                          /* tp_alloc */
     917             :     0,                          /* tp_new */
     918             : };

Generated by: LCOV version 1.10