Home | History | Annotate | Download | only in _io
      1 #include "Python.h"
      2 #include "structmember.h"       /* for offsetof() */
      3 #include "_iomodule.h"
      4 
      5 /*[clinic input]
      6 module _io
      7 class _io.BytesIO "bytesio *" "&PyBytesIO_Type"
      8 [clinic start generated code]*/
      9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
     10 
     11 typedef struct {
     12     PyObject_HEAD
     13     PyObject *buf;
     14     Py_ssize_t pos;
     15     Py_ssize_t string_size;
     16     PyObject *dict;
     17     PyObject *weakreflist;
     18     Py_ssize_t exports;
     19 } bytesio;
     20 
     21 typedef struct {
     22     PyObject_HEAD
     23     bytesio *source;
     24 } bytesiobuf;
     25 
     26 /* The bytesio object can be in three states:
     27   * Py_REFCNT(buf) == 1, exports == 0.
     28   * Py_REFCNT(buf) > 1.  exports == 0,
     29     first modification or export causes the internal buffer copying.
     30   * exports > 0.  Py_REFCNT(buf) == 1, any modifications are forbidden.
     31 */
     32 
     33 #define CHECK_CLOSED(self)                                  \
     34     if ((self)->buf == NULL) {                              \
     35         PyErr_SetString(PyExc_ValueError,                   \
     36                         "I/O operation on closed file.");   \
     37         return NULL;                                        \
     38     }
     39 
     40 #define CHECK_EXPORTS(self) \
     41     if ((self)->exports > 0) { \
     42         PyErr_SetString(PyExc_BufferError, \
     43                         "Existing exports of data: object cannot be re-sized"); \
     44         return NULL; \
     45     }
     46 
     47 #define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
     48 
     49 
     50 /* Internal routine to get a line from the buffer of a BytesIO
     51    object. Returns the length between the current position to the
     52    next newline character. */
     53 static Py_ssize_t
     54 scan_eol(bytesio *self, Py_ssize_t len)
     55 {
     56     const char *start, *n;
     57     Py_ssize_t maxlen;
     58 
     59     assert(self->buf != NULL);
     60     assert(self->pos >= 0);
     61 
     62     if (self->pos >= self->string_size)
     63         return 0;
     64 
     65     /* Move to the end of the line, up to the end of the string, s. */
     66     maxlen = self->string_size - self->pos;
     67     if (len < 0 || len > maxlen)
     68         len = maxlen;
     69 
     70     if (len) {
     71         start = PyBytes_AS_STRING(self->buf) + self->pos;
     72         n = memchr(start, '\n', len);
     73         if (n)
     74             /* Get the length from the current position to the end of
     75                the line. */
     76             len = n - start + 1;
     77     }
     78     assert(len >= 0);
     79     assert(self->pos < PY_SSIZE_T_MAX - len);
     80 
     81     return len;
     82 }
     83 
     84 /* Internal routine for detaching the shared buffer of BytesIO objects.
     85    The caller should ensure that the 'size' argument is non-negative and
     86    not lesser than self->string_size.  Returns 0 on success, -1 otherwise. */
     87 static int
     88 unshare_buffer(bytesio *self, size_t size)
     89 {
     90     PyObject *new_buf;
     91     assert(SHARED_BUF(self));
     92     assert(self->exports == 0);
     93     assert(size >= (size_t)self->string_size);
     94     new_buf = PyBytes_FromStringAndSize(NULL, size);
     95     if (new_buf == NULL)
     96         return -1;
     97     memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
     98            self->string_size);
     99     Py_SETREF(self->buf, new_buf);
    100     return 0;
    101 }
    102 
    103 /* Internal routine for changing the size of the buffer of BytesIO objects.
    104    The caller should ensure that the 'size' argument is non-negative.  Returns
    105    0 on success, -1 otherwise. */
    106 static int
    107 resize_buffer(bytesio *self, size_t size)
    108 {
    109     /* Here, unsigned types are used to avoid dealing with signed integer
    110        overflow, which is undefined in C. */
    111     size_t alloc = PyBytes_GET_SIZE(self->buf);
    112 
    113     assert(self->buf != NULL);
    114 
    115     /* For simplicity, stay in the range of the signed type. Anyway, Python
    116        doesn't allow strings to be longer than this. */
    117     if (size > PY_SSIZE_T_MAX)
    118         goto overflow;
    119 
    120     if (size < alloc / 2) {
    121         /* Major downsize; resize down to exact size. */
    122         alloc = size + 1;
    123     }
    124     else if (size < alloc) {
    125         /* Within allocated size; quick exit */
    126         return 0;
    127     }
    128     else if (size <= alloc * 1.125) {
    129         /* Moderate upsize; overallocate similar to list_resize() */
    130         alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
    131     }
    132     else {
    133         /* Major upsize; resize up to exact size */
    134         alloc = size + 1;
    135     }
    136 
    137     if (alloc > ((size_t)-1) / sizeof(char))
    138         goto overflow;
    139 
    140     if (SHARED_BUF(self)) {
    141         if (unshare_buffer(self, alloc) < 0)
    142             return -1;
    143     }
    144     else {
    145         if (_PyBytes_Resize(&self->buf, alloc) < 0)
    146             return -1;
    147     }
    148 
    149     return 0;
    150 
    151   overflow:
    152     PyErr_SetString(PyExc_OverflowError,
    153                     "new buffer size too large");
    154     return -1;
    155 }
    156 
    157 /* Internal routine for writing a string of bytes to the buffer of a BytesIO
    158    object. Returns the number of bytes written, or -1 on error. */
    159 static Py_ssize_t
    160 write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
    161 {
    162     size_t endpos;
    163     assert(self->buf != NULL);
    164     assert(self->pos >= 0);
    165     assert(len >= 0);
    166 
    167     endpos = (size_t)self->pos + len;
    168     if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
    169         if (resize_buffer(self, endpos) < 0)
    170             return -1;
    171     }
    172     else if (SHARED_BUF(self)) {
    173         if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
    174             return -1;
    175     }
    176 
    177     if (self->pos > self->string_size) {
    178         /* In case of overseek, pad with null bytes the buffer region between
    179            the end of stream and the current position.
    180 
    181           0   lo      string_size                           hi
    182           |   |<---used--->|<----------available----------->|
    183           |   |            <--to pad-->|<---to write--->    |
    184           0   buf                   position
    185         */
    186         memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
    187                (self->pos - self->string_size) * sizeof(char));
    188     }
    189 
    190     /* Copy the data to the internal buffer, overwriting some of the existing
    191        data if self->pos < self->string_size. */
    192     memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
    193     self->pos = endpos;
    194 
    195     /* Set the new length of the internal string if it has changed. */
    196     if ((size_t)self->string_size < endpos) {
    197         self->string_size = endpos;
    198     }
    199 
    200     return len;
    201 }
    202 
    203 static PyObject *
    204 bytesio_get_closed(bytesio *self)
    205 {
    206     if (self->buf == NULL) {
    207         Py_RETURN_TRUE;
    208     }
    209     else {
    210         Py_RETURN_FALSE;
    211     }
    212 }
    213 
    214 /*[clinic input]
    215 _io.BytesIO.readable
    216 
    217 Returns True if the IO object can be read.
    218 [clinic start generated code]*/
    219 
    220 static PyObject *
    221 _io_BytesIO_readable_impl(bytesio *self)
    222 /*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
    223 {
    224     CHECK_CLOSED(self);
    225     Py_RETURN_TRUE;
    226 }
    227 
    228 /*[clinic input]
    229 _io.BytesIO.writable
    230 
    231 Returns True if the IO object can be written.
    232 [clinic start generated code]*/
    233 
    234 static PyObject *
    235 _io_BytesIO_writable_impl(bytesio *self)
    236 /*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
    237 {
    238     CHECK_CLOSED(self);
    239     Py_RETURN_TRUE;
    240 }
    241 
    242 /*[clinic input]
    243 _io.BytesIO.seekable
    244 
    245 Returns True if the IO object can be seeked.
    246 [clinic start generated code]*/
    247 
    248 static PyObject *
    249 _io_BytesIO_seekable_impl(bytesio *self)
    250 /*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
    251 {
    252     CHECK_CLOSED(self);
    253     Py_RETURN_TRUE;
    254 }
    255 
    256 /*[clinic input]
    257 _io.BytesIO.flush
    258 
    259 Does nothing.
    260 [clinic start generated code]*/
    261 
    262 static PyObject *
    263 _io_BytesIO_flush_impl(bytesio *self)
    264 /*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
    265 {
    266     CHECK_CLOSED(self);
    267     Py_RETURN_NONE;
    268 }
    269 
    270 /*[clinic input]
    271 _io.BytesIO.getbuffer
    272 
    273 Get a read-write view over the contents of the BytesIO object.
    274 [clinic start generated code]*/
    275 
    276 static PyObject *
    277 _io_BytesIO_getbuffer_impl(bytesio *self)
    278 /*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
    279 {
    280     PyTypeObject *type = &_PyBytesIOBuffer_Type;
    281     bytesiobuf *buf;
    282     PyObject *view;
    283 
    284     CHECK_CLOSED(self);
    285 
    286     buf = (bytesiobuf *) type->tp_alloc(type, 0);
    287     if (buf == NULL)
    288         return NULL;
    289     Py_INCREF(self);
    290     buf->source = self;
    291     view = PyMemoryView_FromObject((PyObject *) buf);
    292     Py_DECREF(buf);
    293     return view;
    294 }
    295 
    296 /*[clinic input]
    297 _io.BytesIO.getvalue
    298 
    299 Retrieve the entire contents of the BytesIO object.
    300 [clinic start generated code]*/
    301 
    302 static PyObject *
    303 _io_BytesIO_getvalue_impl(bytesio *self)
    304 /*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
    305 {
    306     CHECK_CLOSED(self);
    307     if (self->string_size <= 1 || self->exports > 0)
    308         return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
    309                                          self->string_size);
    310 
    311     if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
    312         if (SHARED_BUF(self)) {
    313             if (unshare_buffer(self, self->string_size) < 0)
    314                 return NULL;
    315         }
    316         else {
    317             if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
    318                 return NULL;
    319         }
    320     }
    321     Py_INCREF(self->buf);
    322     return self->buf;
    323 }
    324 
    325 /*[clinic input]
    326 _io.BytesIO.isatty
    327 
    328 Always returns False.
    329 
    330 BytesIO objects are not connected to a TTY-like device.
    331 [clinic start generated code]*/
    332 
    333 static PyObject *
    334 _io_BytesIO_isatty_impl(bytesio *self)
    335 /*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
    336 {
    337     CHECK_CLOSED(self);
    338     Py_RETURN_FALSE;
    339 }
    340 
    341 /*[clinic input]
    342 _io.BytesIO.tell
    343 
    344 Current file position, an integer.
    345 [clinic start generated code]*/
    346 
    347 static PyObject *
    348 _io_BytesIO_tell_impl(bytesio *self)
    349 /*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
    350 {
    351     CHECK_CLOSED(self);
    352     return PyLong_FromSsize_t(self->pos);
    353 }
    354 
    355 static PyObject *
    356 read_bytes(bytesio *self, Py_ssize_t size)
    357 {
    358     char *output;
    359 
    360     assert(self->buf != NULL);
    361     assert(size <= self->string_size);
    362     if (size > 1 &&
    363         self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
    364         self->exports == 0) {
    365         self->pos += size;
    366         Py_INCREF(self->buf);
    367         return self->buf;
    368     }
    369 
    370     output = PyBytes_AS_STRING(self->buf) + self->pos;
    371     self->pos += size;
    372     return PyBytes_FromStringAndSize(output, size);
    373 }
    374 
    375 /*[clinic input]
    376 _io.BytesIO.read
    377     size as arg: object = None
    378     /
    379 
    380 Read at most size bytes, returned as a bytes object.
    381 
    382 If the size argument is negative, read until EOF is reached.
    383 Return an empty bytes object at EOF.
    384 [clinic start generated code]*/
    385 
    386 static PyObject *
    387 _io_BytesIO_read_impl(bytesio *self, PyObject *arg)
    388 /*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
    389 {
    390     Py_ssize_t size, n;
    391 
    392     CHECK_CLOSED(self);
    393 
    394     if (PyLong_Check(arg)) {
    395         size = PyLong_AsSsize_t(arg);
    396         if (size == -1 && PyErr_Occurred())
    397             return NULL;
    398     }
    399     else if (arg == Py_None) {
    400         /* Read until EOF is reached, by default. */
    401         size = -1;
    402     }
    403     else {
    404         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    405                      Py_TYPE(arg)->tp_name);
    406         return NULL;
    407     }
    408 
    409     /* adjust invalid sizes */
    410     n = self->string_size - self->pos;
    411     if (size < 0 || size > n) {
    412         size = n;
    413         if (size < 0)
    414             size = 0;
    415     }
    416 
    417     return read_bytes(self, size);
    418 }
    419 
    420 
    421 /*[clinic input]
    422 _io.BytesIO.read1
    423     size: object
    424     /
    425 
    426 Read at most size bytes, returned as a bytes object.
    427 
    428 If the size argument is negative or omitted, read until EOF is reached.
    429 Return an empty bytes object at EOF.
    430 [clinic start generated code]*/
    431 
    432 static PyObject *
    433 _io_BytesIO_read1(bytesio *self, PyObject *size)
    434 /*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/
    435 {
    436     return _io_BytesIO_read_impl(self, size);
    437 }
    438 
    439 /*[clinic input]
    440 _io.BytesIO.readline
    441     size as arg: object = None
    442     /
    443 
    444 Next line from the file, as a bytes object.
    445 
    446 Retain newline.  A non-negative size argument limits the maximum
    447 number of bytes to return (an incomplete line may be returned then).
    448 Return an empty bytes object at EOF.
    449 [clinic start generated code]*/
    450 
    451 static PyObject *
    452 _io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
    453 /*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
    454 {
    455     Py_ssize_t size, n;
    456 
    457     CHECK_CLOSED(self);
    458 
    459     if (PyLong_Check(arg)) {
    460         size = PyLong_AsSsize_t(arg);
    461         if (size == -1 && PyErr_Occurred())
    462             return NULL;
    463     }
    464     else if (arg == Py_None) {
    465         /* No size limit, by default. */
    466         size = -1;
    467     }
    468     else {
    469         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    470                      Py_TYPE(arg)->tp_name);
    471         return NULL;
    472     }
    473 
    474     n = scan_eol(self, size);
    475 
    476     return read_bytes(self, n);
    477 }
    478 
    479 /*[clinic input]
    480 _io.BytesIO.readlines
    481     size as arg: object = None
    482     /
    483 
    484 List of bytes objects, each a line from the file.
    485 
    486 Call readline() repeatedly and return a list of the lines so read.
    487 The optional size argument, if given, is an approximate bound on the
    488 total number of bytes in the lines returned.
    489 [clinic start generated code]*/
    490 
    491 static PyObject *
    492 _io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
    493 /*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
    494 {
    495     Py_ssize_t maxsize, size, n;
    496     PyObject *result, *line;
    497     char *output;
    498 
    499     CHECK_CLOSED(self);
    500 
    501     if (PyLong_Check(arg)) {
    502         maxsize = PyLong_AsSsize_t(arg);
    503         if (maxsize == -1 && PyErr_Occurred())
    504             return NULL;
    505     }
    506     else if (arg == Py_None) {
    507         /* No size limit, by default. */
    508         maxsize = -1;
    509     }
    510     else {
    511         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    512                      Py_TYPE(arg)->tp_name);
    513         return NULL;
    514     }
    515 
    516     size = 0;
    517     result = PyList_New(0);
    518     if (!result)
    519         return NULL;
    520 
    521     output = PyBytes_AS_STRING(self->buf) + self->pos;
    522     while ((n = scan_eol(self, -1)) != 0) {
    523         self->pos += n;
    524         line = PyBytes_FromStringAndSize(output, n);
    525         if (!line)
    526             goto on_error;
    527         if (PyList_Append(result, line) == -1) {
    528             Py_DECREF(line);
    529             goto on_error;
    530         }
    531         Py_DECREF(line);
    532         size += n;
    533         if (maxsize > 0 && size >= maxsize)
    534             break;
    535         output += n;
    536     }
    537     return result;
    538 
    539   on_error:
    540     Py_DECREF(result);
    541     return NULL;
    542 }
    543 
    544 /*[clinic input]
    545 _io.BytesIO.readinto
    546     buffer: Py_buffer(accept={rwbuffer})
    547     /
    548 
    549 Read bytes into buffer.
    550 
    551 Returns number of bytes read (0 for EOF), or None if the object
    552 is set not to block and has no data to read.
    553 [clinic start generated code]*/
    554 
    555 static PyObject *
    556 _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
    557 /*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
    558 {
    559     Py_ssize_t len, n;
    560 
    561     CHECK_CLOSED(self);
    562 
    563     /* adjust invalid sizes */
    564     len = buffer->len;
    565     n = self->string_size - self->pos;
    566     if (len > n) {
    567         len = n;
    568         if (len < 0)
    569             len = 0;
    570     }
    571 
    572     memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
    573     assert(self->pos + len < PY_SSIZE_T_MAX);
    574     assert(len >= 0);
    575     self->pos += len;
    576 
    577     return PyLong_FromSsize_t(len);
    578 }
    579 
    580 /*[clinic input]
    581 _io.BytesIO.truncate
    582     size as arg: object = None
    583     /
    584 
    585 Truncate the file to at most size bytes.
    586 
    587 Size defaults to the current file position, as returned by tell().
    588 The current file position is unchanged.  Returns the new size.
    589 [clinic start generated code]*/
    590 
    591 static PyObject *
    592 _io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
    593 /*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
    594 {
    595     Py_ssize_t size;
    596 
    597     CHECK_CLOSED(self);
    598     CHECK_EXPORTS(self);
    599 
    600     if (PyLong_Check(arg)) {
    601         size = PyLong_AsSsize_t(arg);
    602         if (size == -1 && PyErr_Occurred())
    603             return NULL;
    604     }
    605     else if (arg == Py_None) {
    606         /* Truncate to current position if no argument is passed. */
    607         size = self->pos;
    608     }
    609     else {
    610         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    611                      Py_TYPE(arg)->tp_name);
    612         return NULL;
    613     }
    614 
    615     if (size < 0) {
    616         PyErr_Format(PyExc_ValueError,
    617                      "negative size value %zd", size);
    618         return NULL;
    619     }
    620 
    621     if (size < self->string_size) {
    622         self->string_size = size;
    623         if (resize_buffer(self, size) < 0)
    624             return NULL;
    625     }
    626 
    627     return PyLong_FromSsize_t(size);
    628 }
    629 
    630 static PyObject *
    631 bytesio_iternext(bytesio *self)
    632 {
    633     Py_ssize_t n;
    634 
    635     CHECK_CLOSED(self);
    636 
    637     n = scan_eol(self, -1);
    638 
    639     if (n == 0)
    640         return NULL;
    641 
    642     return read_bytes(self, n);
    643 }
    644 
    645 /*[clinic input]
    646 _io.BytesIO.seek
    647     pos: Py_ssize_t
    648     whence: int = 0
    649     /
    650 
    651 Change stream position.
    652 
    653 Seek to byte offset pos relative to position indicated by whence:
    654      0  Start of stream (the default).  pos should be >= 0;
    655      1  Current position - pos may be negative;
    656      2  End of stream - pos usually negative.
    657 Returns the new absolute position.
    658 [clinic start generated code]*/
    659 
    660 static PyObject *
    661 _io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
    662 /*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
    663 {
    664     CHECK_CLOSED(self);
    665 
    666     if (pos < 0 && whence == 0) {
    667         PyErr_Format(PyExc_ValueError,
    668                      "negative seek value %zd", pos);
    669         return NULL;
    670     }
    671 
    672     /* whence = 0: offset relative to beginning of the string.
    673        whence = 1: offset relative to current position.
    674        whence = 2: offset relative the end of the string. */
    675     if (whence == 1) {
    676         if (pos > PY_SSIZE_T_MAX - self->pos) {
    677             PyErr_SetString(PyExc_OverflowError,
    678                             "new position too large");
    679             return NULL;
    680         }
    681         pos += self->pos;
    682     }
    683     else if (whence == 2) {
    684         if (pos > PY_SSIZE_T_MAX - self->string_size) {
    685             PyErr_SetString(PyExc_OverflowError,
    686                             "new position too large");
    687             return NULL;
    688         }
    689         pos += self->string_size;
    690     }
    691     else if (whence != 0) {
    692         PyErr_Format(PyExc_ValueError,
    693                      "invalid whence (%i, should be 0, 1 or 2)", whence);
    694         return NULL;
    695     }
    696 
    697     if (pos < 0)
    698         pos = 0;
    699     self->pos = pos;
    700 
    701     return PyLong_FromSsize_t(self->pos);
    702 }
    703 
    704 /*[clinic input]
    705 _io.BytesIO.write
    706     b: object
    707     /
    708 
    709 Write bytes to file.
    710 
    711 Return the number of bytes written.
    712 [clinic start generated code]*/
    713 
    714 static PyObject *
    715 _io_BytesIO_write(bytesio *self, PyObject *b)
    716 /*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
    717 {
    718     Py_ssize_t n = 0;
    719     Py_buffer buf;
    720 
    721     CHECK_CLOSED(self);
    722     CHECK_EXPORTS(self);
    723 
    724     if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
    725         return NULL;
    726 
    727     if (buf.len != 0)
    728         n = write_bytes(self, buf.buf, buf.len);
    729 
    730     PyBuffer_Release(&buf);
    731     return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
    732 }
    733 
    734 /*[clinic input]
    735 _io.BytesIO.writelines
    736     lines: object
    737     /
    738 
    739 Write lines to the file.
    740 
    741 Note that newlines are not added.  lines can be any iterable object
    742 producing bytes-like objects. This is equivalent to calling write() for
    743 each element.
    744 [clinic start generated code]*/
    745 
    746 static PyObject *
    747 _io_BytesIO_writelines(bytesio *self, PyObject *lines)
    748 /*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
    749 {
    750     PyObject *it, *item;
    751     PyObject *ret;
    752 
    753     CHECK_CLOSED(self);
    754 
    755     it = PyObject_GetIter(lines);
    756     if (it == NULL)
    757         return NULL;
    758 
    759     while ((item = PyIter_Next(it)) != NULL) {
    760         ret = _io_BytesIO_write(self, item);
    761         Py_DECREF(item);
    762         if (ret == NULL) {
    763             Py_DECREF(it);
    764             return NULL;
    765         }
    766         Py_DECREF(ret);
    767     }
    768     Py_DECREF(it);
    769 
    770     /* See if PyIter_Next failed */
    771     if (PyErr_Occurred())
    772         return NULL;
    773 
    774     Py_RETURN_NONE;
    775 }
    776 
    777 /*[clinic input]
    778 _io.BytesIO.close
    779 
    780 Disable all I/O operations.
    781 [clinic start generated code]*/
    782 
    783 static PyObject *
    784 _io_BytesIO_close_impl(bytesio *self)
    785 /*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
    786 {
    787     CHECK_EXPORTS(self);
    788     Py_CLEAR(self->buf);
    789     Py_RETURN_NONE;
    790 }
    791 
    792 /* Pickling support.
    793 
    794    Note that only pickle protocol 2 and onward are supported since we use
    795    extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
    796 
    797    Providing support for protocol < 2 would require the __reduce_ex__ method
    798    which is notably long-winded when defined properly.
    799 
    800    For BytesIO, the implementation would similar to one coded for
    801    object.__reduce_ex__, but slightly less general. To be more specific, we
    802    could call bytesio_getstate directly and avoid checking for the presence of
    803    a fallback __reduce__ method. However, we would still need a __newobj__
    804    function to use the efficient instance representation of PEP 307.
    805  */
    806 
    807 static PyObject *
    808 bytesio_getstate(bytesio *self)
    809 {
    810     PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
    811     PyObject *dict;
    812     PyObject *state;
    813 
    814     if (initvalue == NULL)
    815         return NULL;
    816     if (self->dict == NULL) {
    817         Py_INCREF(Py_None);
    818         dict = Py_None;
    819     }
    820     else {
    821         dict = PyDict_Copy(self->dict);
    822         if (dict == NULL) {
    823             Py_DECREF(initvalue);
    824             return NULL;
    825         }
    826     }
    827 
    828     state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
    829     Py_DECREF(initvalue);
    830     return state;
    831 }
    832 
    833 static PyObject *
    834 bytesio_setstate(bytesio *self, PyObject *state)
    835 {
    836     PyObject *result;
    837     PyObject *position_obj;
    838     PyObject *dict;
    839     Py_ssize_t pos;
    840 
    841     assert(state != NULL);
    842 
    843     /* We allow the state tuple to be longer than 3, because we may need
    844        someday to extend the object's state without breaking
    845        backward-compatibility. */
    846     if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
    847         PyErr_Format(PyExc_TypeError,
    848                      "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
    849                      Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
    850         return NULL;
    851     }
    852     CHECK_EXPORTS(self);
    853     /* Reset the object to its default state. This is only needed to handle
    854        the case of repeated calls to __setstate__. */
    855     self->string_size = 0;
    856     self->pos = 0;
    857 
    858     /* Set the value of the internal buffer. If state[0] does not support the
    859        buffer protocol, bytesio_write will raise the appropriate TypeError. */
    860     result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
    861     if (result == NULL)
    862         return NULL;
    863     Py_DECREF(result);
    864 
    865     /* Set carefully the position value. Alternatively, we could use the seek
    866        method instead of modifying self->pos directly to better protect the
    867        object internal state against errneous (or malicious) inputs. */
    868     position_obj = PyTuple_GET_ITEM(state, 1);
    869     if (!PyLong_Check(position_obj)) {
    870         PyErr_Format(PyExc_TypeError,
    871                      "second item of state must be an integer, not %.200s",
    872                      Py_TYPE(position_obj)->tp_name);
    873         return NULL;
    874     }
    875     pos = PyLong_AsSsize_t(position_obj);
    876     if (pos == -1 && PyErr_Occurred())
    877         return NULL;
    878     if (pos < 0) {
    879         PyErr_SetString(PyExc_ValueError,
    880                         "position value cannot be negative");
    881         return NULL;
    882     }
    883     self->pos = pos;
    884 
    885     /* Set the dictionary of the instance variables. */
    886     dict = PyTuple_GET_ITEM(state, 2);
    887     if (dict != Py_None) {
    888         if (!PyDict_Check(dict)) {
    889             PyErr_Format(PyExc_TypeError,
    890                          "third item of state should be a dict, got a %.200s",
    891                          Py_TYPE(dict)->tp_name);
    892             return NULL;
    893         }
    894         if (self->dict) {
    895             /* Alternatively, we could replace the internal dictionary
    896                completely. However, it seems more practical to just update it. */
    897             if (PyDict_Update(self->dict, dict) < 0)
    898                 return NULL;
    899         }
    900         else {
    901             Py_INCREF(dict);
    902             self->dict = dict;
    903         }
    904     }
    905 
    906     Py_RETURN_NONE;
    907 }
    908 
    909 static void
    910 bytesio_dealloc(bytesio *self)
    911 {
    912     _PyObject_GC_UNTRACK(self);
    913     if (self->exports > 0) {
    914         PyErr_SetString(PyExc_SystemError,
    915                         "deallocated BytesIO object has exported buffers");
    916         PyErr_Print();
    917     }
    918     Py_CLEAR(self->buf);
    919     Py_CLEAR(self->dict);
    920     if (self->weakreflist != NULL)
    921         PyObject_ClearWeakRefs((PyObject *) self);
    922     Py_TYPE(self)->tp_free(self);
    923 }
    924 
    925 static PyObject *
    926 bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    927 {
    928     bytesio *self;
    929 
    930     assert(type != NULL && type->tp_alloc != NULL);
    931     self = (bytesio *)type->tp_alloc(type, 0);
    932     if (self == NULL)
    933         return NULL;
    934 
    935     /* tp_alloc initializes all the fields to zero. So we don't have to
    936        initialize them here. */
    937 
    938     self->buf = PyBytes_FromStringAndSize(NULL, 0);
    939     if (self->buf == NULL) {
    940         Py_DECREF(self);
    941         return PyErr_NoMemory();
    942     }
    943 
    944     return (PyObject *)self;
    945 }
    946 
    947 /*[clinic input]
    948 _io.BytesIO.__init__
    949     initial_bytes as initvalue: object(c_default="NULL") = b''
    950 
    951 Buffered I/O implementation using an in-memory bytes buffer.
    952 [clinic start generated code]*/
    953 
    954 static int
    955 _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
    956 /*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
    957 {
    958     /* In case, __init__ is called multiple times. */
    959     self->string_size = 0;
    960     self->pos = 0;
    961 
    962     if (self->exports > 0) {
    963         PyErr_SetString(PyExc_BufferError,
    964                         "Existing exports of data: object cannot be re-sized");
    965         return -1;
    966     }
    967     if (initvalue && initvalue != Py_None) {
    968         if (PyBytes_CheckExact(initvalue)) {
    969             Py_INCREF(initvalue);
    970             Py_XSETREF(self->buf, initvalue);
    971             self->string_size = PyBytes_GET_SIZE(initvalue);
    972         }
    973         else {
    974             PyObject *res;
    975             res = _io_BytesIO_write(self, initvalue);
    976             if (res == NULL)
    977                 return -1;
    978             Py_DECREF(res);
    979             self->pos = 0;
    980         }
    981     }
    982 
    983     return 0;
    984 }
    985 
    986 static PyObject *
    987 bytesio_sizeof(bytesio *self, void *unused)
    988 {
    989     Py_ssize_t res;
    990 
    991     res = _PyObject_SIZE(Py_TYPE(self));
    992     if (self->buf && !SHARED_BUF(self))
    993         res += _PySys_GetSizeOf(self->buf);
    994     return PyLong_FromSsize_t(res);
    995 }
    996 
    997 static int
    998 bytesio_traverse(bytesio *self, visitproc visit, void *arg)
    999 {
   1000     Py_VISIT(self->dict);
   1001     return 0;
   1002 }
   1003 
   1004 static int
   1005 bytesio_clear(bytesio *self)
   1006 {
   1007     Py_CLEAR(self->dict);
   1008     return 0;
   1009 }
   1010 
   1011 
   1012 #include "clinic/bytesio.c.h"
   1013 
   1014 static PyGetSetDef bytesio_getsetlist[] = {
   1015     {"closed",  (getter)bytesio_get_closed, NULL,
   1016      "True if the file is closed."},
   1017     {NULL},            /* sentinel */
   1018 };
   1019 
   1020 static struct PyMethodDef bytesio_methods[] = {
   1021     _IO_BYTESIO_READABLE_METHODDEF
   1022     _IO_BYTESIO_SEEKABLE_METHODDEF
   1023     _IO_BYTESIO_WRITABLE_METHODDEF
   1024     _IO_BYTESIO_CLOSE_METHODDEF
   1025     _IO_BYTESIO_FLUSH_METHODDEF
   1026     _IO_BYTESIO_ISATTY_METHODDEF
   1027     _IO_BYTESIO_TELL_METHODDEF
   1028     _IO_BYTESIO_WRITE_METHODDEF
   1029     _IO_BYTESIO_WRITELINES_METHODDEF
   1030     _IO_BYTESIO_READ1_METHODDEF
   1031     _IO_BYTESIO_READINTO_METHODDEF
   1032     _IO_BYTESIO_READLINE_METHODDEF
   1033     _IO_BYTESIO_READLINES_METHODDEF
   1034     _IO_BYTESIO_READ_METHODDEF
   1035     _IO_BYTESIO_GETBUFFER_METHODDEF
   1036     _IO_BYTESIO_GETVALUE_METHODDEF
   1037     _IO_BYTESIO_SEEK_METHODDEF
   1038     _IO_BYTESIO_TRUNCATE_METHODDEF
   1039     {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
   1040     {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
   1041     {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
   1042     {NULL, NULL}        /* sentinel */
   1043 };
   1044 
   1045 PyTypeObject PyBytesIO_Type = {
   1046     PyVarObject_HEAD_INIT(NULL, 0)
   1047     "_io.BytesIO",                             /*tp_name*/
   1048     sizeof(bytesio),                     /*tp_basicsize*/
   1049     0,                                         /*tp_itemsize*/
   1050     (destructor)bytesio_dealloc,               /*tp_dealloc*/
   1051     0,                                         /*tp_print*/
   1052     0,                                         /*tp_getattr*/
   1053     0,                                         /*tp_setattr*/
   1054     0,                                         /*tp_reserved*/
   1055     0,                                         /*tp_repr*/
   1056     0,                                         /*tp_as_number*/
   1057     0,                                         /*tp_as_sequence*/
   1058     0,                                         /*tp_as_mapping*/
   1059     0,                                         /*tp_hash*/
   1060     0,                                         /*tp_call*/
   1061     0,                                         /*tp_str*/
   1062     0,                                         /*tp_getattro*/
   1063     0,                                         /*tp_setattro*/
   1064     0,                                         /*tp_as_buffer*/
   1065     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
   1066     Py_TPFLAGS_HAVE_GC,                        /*tp_flags*/
   1067     _io_BytesIO___init____doc__,               /*tp_doc*/
   1068     (traverseproc)bytesio_traverse,            /*tp_traverse*/
   1069     (inquiry)bytesio_clear,                    /*tp_clear*/
   1070     0,                                         /*tp_richcompare*/
   1071     offsetof(bytesio, weakreflist),      /*tp_weaklistoffset*/
   1072     PyObject_SelfIter,                         /*tp_iter*/
   1073     (iternextfunc)bytesio_iternext,            /*tp_iternext*/
   1074     bytesio_methods,                           /*tp_methods*/
   1075     0,                                         /*tp_members*/
   1076     bytesio_getsetlist,                        /*tp_getset*/
   1077     0,                                         /*tp_base*/
   1078     0,                                         /*tp_dict*/
   1079     0,                                         /*tp_descr_get*/
   1080     0,                                         /*tp_descr_set*/
   1081     offsetof(bytesio, dict),             /*tp_dictoffset*/
   1082     _io_BytesIO___init__,                      /*tp_init*/
   1083     0,                                         /*tp_alloc*/
   1084     bytesio_new,                               /*tp_new*/
   1085 };
   1086 
   1087 
   1088 /*
   1089  * Implementation of the small intermediate object used by getbuffer().
   1090  * getbuffer() returns a memoryview over this object, which should make it
   1091  * invisible from Python code.
   1092  */
   1093 
   1094 static int
   1095 bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
   1096 {
   1097     bytesio *b = (bytesio *) obj->source;
   1098 
   1099     if (view == NULL) {
   1100         PyErr_SetString(PyExc_BufferError,
   1101             "bytesiobuf_getbuffer: view==NULL argument is obsolete");
   1102         return -1;
   1103     }
   1104     if (SHARED_BUF(b)) {
   1105         if (unshare_buffer(b, b->string_size) < 0)
   1106             return -1;
   1107     }
   1108 
   1109     /* cannot fail if view != NULL and readonly == 0 */
   1110     (void)PyBuffer_FillInfo(view, (PyObject*)obj,
   1111                             PyBytes_AS_STRING(b->buf), b->string_size,
   1112                             0, flags);
   1113     b->exports++;
   1114     return 0;
   1115 }
   1116 
   1117 static void
   1118 bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
   1119 {
   1120     bytesio *b = (bytesio *) obj->source;
   1121     b->exports--;
   1122 }
   1123 
   1124 static int
   1125 bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
   1126 {
   1127     Py_VISIT(self->source);
   1128     return 0;
   1129 }
   1130 
   1131 static void
   1132 bytesiobuf_dealloc(bytesiobuf *self)
   1133 {
   1134     Py_CLEAR(self->source);
   1135     Py_TYPE(self)->tp_free(self);
   1136 }
   1137 
   1138 static PyBufferProcs bytesiobuf_as_buffer = {
   1139     (getbufferproc) bytesiobuf_getbuffer,
   1140     (releasebufferproc) bytesiobuf_releasebuffer,
   1141 };
   1142 
   1143 PyTypeObject _PyBytesIOBuffer_Type = {
   1144     PyVarObject_HEAD_INIT(NULL, 0)
   1145     "_io._BytesIOBuffer",                      /*tp_name*/
   1146     sizeof(bytesiobuf),                        /*tp_basicsize*/
   1147     0,                                         /*tp_itemsize*/
   1148     (destructor)bytesiobuf_dealloc,            /*tp_dealloc*/
   1149     0,                                         /*tp_print*/
   1150     0,                                         /*tp_getattr*/
   1151     0,                                         /*tp_setattr*/
   1152     0,                                         /*tp_reserved*/
   1153     0,                                         /*tp_repr*/
   1154     0,                                         /*tp_as_number*/
   1155     0,                                         /*tp_as_sequence*/
   1156     0,                                         /*tp_as_mapping*/
   1157     0,                                         /*tp_hash*/
   1158     0,                                         /*tp_call*/
   1159     0,                                         /*tp_str*/
   1160     0,                                         /*tp_getattro*/
   1161     0,                                         /*tp_setattro*/
   1162     &bytesiobuf_as_buffer,                     /*tp_as_buffer*/
   1163     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
   1164     0,                                         /*tp_doc*/
   1165     (traverseproc)bytesiobuf_traverse,         /*tp_traverse*/
   1166     0,                                         /*tp_clear*/
   1167     0,                                         /*tp_richcompare*/
   1168     0,                                         /*tp_weaklistoffset*/
   1169     0,                                         /*tp_iter*/
   1170     0,                                         /*tp_iternext*/
   1171     0,                                         /*tp_methods*/
   1172     0,                                         /*tp_members*/
   1173     0,                                         /*tp_getset*/
   1174     0,                                         /*tp_base*/
   1175     0,                                         /*tp_dict*/
   1176     0,                                         /*tp_descr_get*/
   1177     0,                                         /*tp_descr_set*/
   1178     0,                                         /*tp_dictoffset*/
   1179     0,                                         /*tp_init*/
   1180     0,                                         /*tp_alloc*/
   1181     0,                                         /*tp_new*/
   1182 };
   1183