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, void *Py_UNUSED(ignored))
    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: Py_ssize_t(accept={int, NoneType}) = -1
    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, Py_ssize_t size)
    388 /*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/
    389 {
    390     Py_ssize_t n;
    391 
    392     CHECK_CLOSED(self);
    393 
    394     /* adjust invalid sizes */
    395     n = self->string_size - self->pos;
    396     if (size < 0 || size > n) {
    397         size = n;
    398         if (size < 0)
    399             size = 0;
    400     }
    401 
    402     return read_bytes(self, size);
    403 }
    404 
    405 
    406 /*[clinic input]
    407 _io.BytesIO.read1
    408     size: Py_ssize_t(accept={int, NoneType}) = -1
    409     /
    410 
    411 Read at most size bytes, returned as a bytes object.
    412 
    413 If the size argument is negative or omitted, read until EOF is reached.
    414 Return an empty bytes object at EOF.
    415 [clinic start generated code]*/
    416 
    417 static PyObject *
    418 _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
    419 /*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/
    420 {
    421     return _io_BytesIO_read_impl(self, size);
    422 }
    423 
    424 /*[clinic input]
    425 _io.BytesIO.readline
    426     size: Py_ssize_t(accept={int, NoneType}) = -1
    427     /
    428 
    429 Next line from the file, as a bytes object.
    430 
    431 Retain newline.  A non-negative size argument limits the maximum
    432 number of bytes to return (an incomplete line may be returned then).
    433 Return an empty bytes object at EOF.
    434 [clinic start generated code]*/
    435 
    436 static PyObject *
    437 _io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
    438 /*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/
    439 {
    440     Py_ssize_t n;
    441 
    442     CHECK_CLOSED(self);
    443 
    444     n = scan_eol(self, size);
    445 
    446     return read_bytes(self, n);
    447 }
    448 
    449 /*[clinic input]
    450 _io.BytesIO.readlines
    451     size as arg: object = None
    452     /
    453 
    454 List of bytes objects, each a line from the file.
    455 
    456 Call readline() repeatedly and return a list of the lines so read.
    457 The optional size argument, if given, is an approximate bound on the
    458 total number of bytes in the lines returned.
    459 [clinic start generated code]*/
    460 
    461 static PyObject *
    462 _io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
    463 /*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
    464 {
    465     Py_ssize_t maxsize, size, n;
    466     PyObject *result, *line;
    467     char *output;
    468 
    469     CHECK_CLOSED(self);
    470 
    471     if (PyLong_Check(arg)) {
    472         maxsize = PyLong_AsSsize_t(arg);
    473         if (maxsize == -1 && PyErr_Occurred())
    474             return NULL;
    475     }
    476     else if (arg == Py_None) {
    477         /* No size limit, by default. */
    478         maxsize = -1;
    479     }
    480     else {
    481         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    482                      Py_TYPE(arg)->tp_name);
    483         return NULL;
    484     }
    485 
    486     size = 0;
    487     result = PyList_New(0);
    488     if (!result)
    489         return NULL;
    490 
    491     output = PyBytes_AS_STRING(self->buf) + self->pos;
    492     while ((n = scan_eol(self, -1)) != 0) {
    493         self->pos += n;
    494         line = PyBytes_FromStringAndSize(output, n);
    495         if (!line)
    496             goto on_error;
    497         if (PyList_Append(result, line) == -1) {
    498             Py_DECREF(line);
    499             goto on_error;
    500         }
    501         Py_DECREF(line);
    502         size += n;
    503         if (maxsize > 0 && size >= maxsize)
    504             break;
    505         output += n;
    506     }
    507     return result;
    508 
    509   on_error:
    510     Py_DECREF(result);
    511     return NULL;
    512 }
    513 
    514 /*[clinic input]
    515 _io.BytesIO.readinto
    516     buffer: Py_buffer(accept={rwbuffer})
    517     /
    518 
    519 Read bytes into buffer.
    520 
    521 Returns number of bytes read (0 for EOF), or None if the object
    522 is set not to block and has no data to read.
    523 [clinic start generated code]*/
    524 
    525 static PyObject *
    526 _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
    527 /*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
    528 {
    529     Py_ssize_t len, n;
    530 
    531     CHECK_CLOSED(self);
    532 
    533     /* adjust invalid sizes */
    534     len = buffer->len;
    535     n = self->string_size - self->pos;
    536     if (len > n) {
    537         len = n;
    538         if (len < 0)
    539             len = 0;
    540     }
    541 
    542     memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
    543     assert(self->pos + len < PY_SSIZE_T_MAX);
    544     assert(len >= 0);
    545     self->pos += len;
    546 
    547     return PyLong_FromSsize_t(len);
    548 }
    549 
    550 /*[clinic input]
    551 _io.BytesIO.truncate
    552     size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
    553     /
    554 
    555 Truncate the file to at most size bytes.
    556 
    557 Size defaults to the current file position, as returned by tell().
    558 The current file position is unchanged.  Returns the new size.
    559 [clinic start generated code]*/
    560 
    561 static PyObject *
    562 _io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size)
    563 /*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/
    564 {
    565     CHECK_CLOSED(self);
    566     CHECK_EXPORTS(self);
    567 
    568     if (size < 0) {
    569         PyErr_Format(PyExc_ValueError,
    570                      "negative size value %zd", size);
    571         return NULL;
    572     }
    573 
    574     if (size < self->string_size) {
    575         self->string_size = size;
    576         if (resize_buffer(self, size) < 0)
    577             return NULL;
    578     }
    579 
    580     return PyLong_FromSsize_t(size);
    581 }
    582 
    583 static PyObject *
    584 bytesio_iternext(bytesio *self)
    585 {
    586     Py_ssize_t n;
    587 
    588     CHECK_CLOSED(self);
    589 
    590     n = scan_eol(self, -1);
    591 
    592     if (n == 0)
    593         return NULL;
    594 
    595     return read_bytes(self, n);
    596 }
    597 
    598 /*[clinic input]
    599 _io.BytesIO.seek
    600     pos: Py_ssize_t
    601     whence: int = 0
    602     /
    603 
    604 Change stream position.
    605 
    606 Seek to byte offset pos relative to position indicated by whence:
    607      0  Start of stream (the default).  pos should be >= 0;
    608      1  Current position - pos may be negative;
    609      2  End of stream - pos usually negative.
    610 Returns the new absolute position.
    611 [clinic start generated code]*/
    612 
    613 static PyObject *
    614 _io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
    615 /*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
    616 {
    617     CHECK_CLOSED(self);
    618 
    619     if (pos < 0 && whence == 0) {
    620         PyErr_Format(PyExc_ValueError,
    621                      "negative seek value %zd", pos);
    622         return NULL;
    623     }
    624 
    625     /* whence = 0: offset relative to beginning of the string.
    626        whence = 1: offset relative to current position.
    627        whence = 2: offset relative the end of the string. */
    628     if (whence == 1) {
    629         if (pos > PY_SSIZE_T_MAX - self->pos) {
    630             PyErr_SetString(PyExc_OverflowError,
    631                             "new position too large");
    632             return NULL;
    633         }
    634         pos += self->pos;
    635     }
    636     else if (whence == 2) {
    637         if (pos > PY_SSIZE_T_MAX - self->string_size) {
    638             PyErr_SetString(PyExc_OverflowError,
    639                             "new position too large");
    640             return NULL;
    641         }
    642         pos += self->string_size;
    643     }
    644     else if (whence != 0) {
    645         PyErr_Format(PyExc_ValueError,
    646                      "invalid whence (%i, should be 0, 1 or 2)", whence);
    647         return NULL;
    648     }
    649 
    650     if (pos < 0)
    651         pos = 0;
    652     self->pos = pos;
    653 
    654     return PyLong_FromSsize_t(self->pos);
    655 }
    656 
    657 /*[clinic input]
    658 _io.BytesIO.write
    659     b: object
    660     /
    661 
    662 Write bytes to file.
    663 
    664 Return the number of bytes written.
    665 [clinic start generated code]*/
    666 
    667 static PyObject *
    668 _io_BytesIO_write(bytesio *self, PyObject *b)
    669 /*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
    670 {
    671     Py_ssize_t n = 0;
    672     Py_buffer buf;
    673 
    674     CHECK_CLOSED(self);
    675     CHECK_EXPORTS(self);
    676 
    677     if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
    678         return NULL;
    679 
    680     if (buf.len != 0)
    681         n = write_bytes(self, buf.buf, buf.len);
    682 
    683     PyBuffer_Release(&buf);
    684     return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
    685 }
    686 
    687 /*[clinic input]
    688 _io.BytesIO.writelines
    689     lines: object
    690     /
    691 
    692 Write lines to the file.
    693 
    694 Note that newlines are not added.  lines can be any iterable object
    695 producing bytes-like objects. This is equivalent to calling write() for
    696 each element.
    697 [clinic start generated code]*/
    698 
    699 static PyObject *
    700 _io_BytesIO_writelines(bytesio *self, PyObject *lines)
    701 /*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
    702 {
    703     PyObject *it, *item;
    704     PyObject *ret;
    705 
    706     CHECK_CLOSED(self);
    707 
    708     it = PyObject_GetIter(lines);
    709     if (it == NULL)
    710         return NULL;
    711 
    712     while ((item = PyIter_Next(it)) != NULL) {
    713         ret = _io_BytesIO_write(self, item);
    714         Py_DECREF(item);
    715         if (ret == NULL) {
    716             Py_DECREF(it);
    717             return NULL;
    718         }
    719         Py_DECREF(ret);
    720     }
    721     Py_DECREF(it);
    722 
    723     /* See if PyIter_Next failed */
    724     if (PyErr_Occurred())
    725         return NULL;
    726 
    727     Py_RETURN_NONE;
    728 }
    729 
    730 /*[clinic input]
    731 _io.BytesIO.close
    732 
    733 Disable all I/O operations.
    734 [clinic start generated code]*/
    735 
    736 static PyObject *
    737 _io_BytesIO_close_impl(bytesio *self)
    738 /*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
    739 {
    740     CHECK_EXPORTS(self);
    741     Py_CLEAR(self->buf);
    742     Py_RETURN_NONE;
    743 }
    744 
    745 /* Pickling support.
    746 
    747    Note that only pickle protocol 2 and onward are supported since we use
    748    extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
    749 
    750    Providing support for protocol < 2 would require the __reduce_ex__ method
    751    which is notably long-winded when defined properly.
    752 
    753    For BytesIO, the implementation would similar to one coded for
    754    object.__reduce_ex__, but slightly less general. To be more specific, we
    755    could call bytesio_getstate directly and avoid checking for the presence of
    756    a fallback __reduce__ method. However, we would still need a __newobj__
    757    function to use the efficient instance representation of PEP 307.
    758  */
    759 
    760 static PyObject *
    761 bytesio_getstate(bytesio *self)
    762 {
    763     PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
    764     PyObject *dict;
    765     PyObject *state;
    766 
    767     if (initvalue == NULL)
    768         return NULL;
    769     if (self->dict == NULL) {
    770         Py_INCREF(Py_None);
    771         dict = Py_None;
    772     }
    773     else {
    774         dict = PyDict_Copy(self->dict);
    775         if (dict == NULL) {
    776             Py_DECREF(initvalue);
    777             return NULL;
    778         }
    779     }
    780 
    781     state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
    782     Py_DECREF(initvalue);
    783     return state;
    784 }
    785 
    786 static PyObject *
    787 bytesio_setstate(bytesio *self, PyObject *state)
    788 {
    789     PyObject *result;
    790     PyObject *position_obj;
    791     PyObject *dict;
    792     Py_ssize_t pos;
    793 
    794     assert(state != NULL);
    795 
    796     /* We allow the state tuple to be longer than 3, because we may need
    797        someday to extend the object's state without breaking
    798        backward-compatibility. */
    799     if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 3) {
    800         PyErr_Format(PyExc_TypeError,
    801                      "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
    802                      Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
    803         return NULL;
    804     }
    805     CHECK_EXPORTS(self);
    806     /* Reset the object to its default state. This is only needed to handle
    807        the case of repeated calls to __setstate__. */
    808     self->string_size = 0;
    809     self->pos = 0;
    810 
    811     /* Set the value of the internal buffer. If state[0] does not support the
    812        buffer protocol, bytesio_write will raise the appropriate TypeError. */
    813     result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
    814     if (result == NULL)
    815         return NULL;
    816     Py_DECREF(result);
    817 
    818     /* Set carefully the position value. Alternatively, we could use the seek
    819        method instead of modifying self->pos directly to better protect the
    820        object internal state against errneous (or malicious) inputs. */
    821     position_obj = PyTuple_GET_ITEM(state, 1);
    822     if (!PyLong_Check(position_obj)) {
    823         PyErr_Format(PyExc_TypeError,
    824                      "second item of state must be an integer, not %.200s",
    825                      Py_TYPE(position_obj)->tp_name);
    826         return NULL;
    827     }
    828     pos = PyLong_AsSsize_t(position_obj);
    829     if (pos == -1 && PyErr_Occurred())
    830         return NULL;
    831     if (pos < 0) {
    832         PyErr_SetString(PyExc_ValueError,
    833                         "position value cannot be negative");
    834         return NULL;
    835     }
    836     self->pos = pos;
    837 
    838     /* Set the dictionary of the instance variables. */
    839     dict = PyTuple_GET_ITEM(state, 2);
    840     if (dict != Py_None) {
    841         if (!PyDict_Check(dict)) {
    842             PyErr_Format(PyExc_TypeError,
    843                          "third item of state should be a dict, got a %.200s",
    844                          Py_TYPE(dict)->tp_name);
    845             return NULL;
    846         }
    847         if (self->dict) {
    848             /* Alternatively, we could replace the internal dictionary
    849                completely. However, it seems more practical to just update it. */
    850             if (PyDict_Update(self->dict, dict) < 0)
    851                 return NULL;
    852         }
    853         else {
    854             Py_INCREF(dict);
    855             self->dict = dict;
    856         }
    857     }
    858 
    859     Py_RETURN_NONE;
    860 }
    861 
    862 static void
    863 bytesio_dealloc(bytesio *self)
    864 {
    865     _PyObject_GC_UNTRACK(self);
    866     if (self->exports > 0) {
    867         PyErr_SetString(PyExc_SystemError,
    868                         "deallocated BytesIO object has exported buffers");
    869         PyErr_Print();
    870     }
    871     Py_CLEAR(self->buf);
    872     Py_CLEAR(self->dict);
    873     if (self->weakreflist != NULL)
    874         PyObject_ClearWeakRefs((PyObject *) self);
    875     Py_TYPE(self)->tp_free(self);
    876 }
    877 
    878 static PyObject *
    879 bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    880 {
    881     bytesio *self;
    882 
    883     assert(type != NULL && type->tp_alloc != NULL);
    884     self = (bytesio *)type->tp_alloc(type, 0);
    885     if (self == NULL)
    886         return NULL;
    887 
    888     /* tp_alloc initializes all the fields to zero. So we don't have to
    889        initialize them here. */
    890 
    891     self->buf = PyBytes_FromStringAndSize(NULL, 0);
    892     if (self->buf == NULL) {
    893         Py_DECREF(self);
    894         return PyErr_NoMemory();
    895     }
    896 
    897     return (PyObject *)self;
    898 }
    899 
    900 /*[clinic input]
    901 _io.BytesIO.__init__
    902     initial_bytes as initvalue: object(c_default="NULL") = b''
    903 
    904 Buffered I/O implementation using an in-memory bytes buffer.
    905 [clinic start generated code]*/
    906 
    907 static int
    908 _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
    909 /*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
    910 {
    911     /* In case, __init__ is called multiple times. */
    912     self->string_size = 0;
    913     self->pos = 0;
    914 
    915     if (self->exports > 0) {
    916         PyErr_SetString(PyExc_BufferError,
    917                         "Existing exports of data: object cannot be re-sized");
    918         return -1;
    919     }
    920     if (initvalue && initvalue != Py_None) {
    921         if (PyBytes_CheckExact(initvalue)) {
    922             Py_INCREF(initvalue);
    923             Py_XSETREF(self->buf, initvalue);
    924             self->string_size = PyBytes_GET_SIZE(initvalue);
    925         }
    926         else {
    927             PyObject *res;
    928             res = _io_BytesIO_write(self, initvalue);
    929             if (res == NULL)
    930                 return -1;
    931             Py_DECREF(res);
    932             self->pos = 0;
    933         }
    934     }
    935 
    936     return 0;
    937 }
    938 
    939 static PyObject *
    940 bytesio_sizeof(bytesio *self, void *unused)
    941 {
    942     Py_ssize_t res;
    943 
    944     res = _PyObject_SIZE(Py_TYPE(self));
    945     if (self->buf && !SHARED_BUF(self))
    946         res += _PySys_GetSizeOf(self->buf);
    947     return PyLong_FromSsize_t(res);
    948 }
    949 
    950 static int
    951 bytesio_traverse(bytesio *self, visitproc visit, void *arg)
    952 {
    953     Py_VISIT(self->dict);
    954     return 0;
    955 }
    956 
    957 static int
    958 bytesio_clear(bytesio *self)
    959 {
    960     Py_CLEAR(self->dict);
    961     return 0;
    962 }
    963 
    964 
    965 #include "clinic/bytesio.c.h"
    966 
    967 static PyGetSetDef bytesio_getsetlist[] = {
    968     {"closed",  (getter)bytesio_get_closed, NULL,
    969      "True if the file is closed."},
    970     {NULL},            /* sentinel */
    971 };
    972 
    973 static struct PyMethodDef bytesio_methods[] = {
    974     _IO_BYTESIO_READABLE_METHODDEF
    975     _IO_BYTESIO_SEEKABLE_METHODDEF
    976     _IO_BYTESIO_WRITABLE_METHODDEF
    977     _IO_BYTESIO_CLOSE_METHODDEF
    978     _IO_BYTESIO_FLUSH_METHODDEF
    979     _IO_BYTESIO_ISATTY_METHODDEF
    980     _IO_BYTESIO_TELL_METHODDEF
    981     _IO_BYTESIO_WRITE_METHODDEF
    982     _IO_BYTESIO_WRITELINES_METHODDEF
    983     _IO_BYTESIO_READ1_METHODDEF
    984     _IO_BYTESIO_READINTO_METHODDEF
    985     _IO_BYTESIO_READLINE_METHODDEF
    986     _IO_BYTESIO_READLINES_METHODDEF
    987     _IO_BYTESIO_READ_METHODDEF
    988     _IO_BYTESIO_GETBUFFER_METHODDEF
    989     _IO_BYTESIO_GETVALUE_METHODDEF
    990     _IO_BYTESIO_SEEK_METHODDEF
    991     _IO_BYTESIO_TRUNCATE_METHODDEF
    992     {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
    993     {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
    994     {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
    995     {NULL, NULL}        /* sentinel */
    996 };
    997 
    998 PyTypeObject PyBytesIO_Type = {
    999     PyVarObject_HEAD_INIT(NULL, 0)
   1000     "_io.BytesIO",                             /*tp_name*/
   1001     sizeof(bytesio),                     /*tp_basicsize*/
   1002     0,                                         /*tp_itemsize*/
   1003     (destructor)bytesio_dealloc,               /*tp_dealloc*/
   1004     0,                                         /*tp_print*/
   1005     0,                                         /*tp_getattr*/
   1006     0,                                         /*tp_setattr*/
   1007     0,                                         /*tp_reserved*/
   1008     0,                                         /*tp_repr*/
   1009     0,                                         /*tp_as_number*/
   1010     0,                                         /*tp_as_sequence*/
   1011     0,                                         /*tp_as_mapping*/
   1012     0,                                         /*tp_hash*/
   1013     0,                                         /*tp_call*/
   1014     0,                                         /*tp_str*/
   1015     0,                                         /*tp_getattro*/
   1016     0,                                         /*tp_setattro*/
   1017     0,                                         /*tp_as_buffer*/
   1018     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
   1019     Py_TPFLAGS_HAVE_GC,                        /*tp_flags*/
   1020     _io_BytesIO___init____doc__,               /*tp_doc*/
   1021     (traverseproc)bytesio_traverse,            /*tp_traverse*/
   1022     (inquiry)bytesio_clear,                    /*tp_clear*/
   1023     0,                                         /*tp_richcompare*/
   1024     offsetof(bytesio, weakreflist),      /*tp_weaklistoffset*/
   1025     PyObject_SelfIter,                         /*tp_iter*/
   1026     (iternextfunc)bytesio_iternext,            /*tp_iternext*/
   1027     bytesio_methods,                           /*tp_methods*/
   1028     0,                                         /*tp_members*/
   1029     bytesio_getsetlist,                        /*tp_getset*/
   1030     0,                                         /*tp_base*/
   1031     0,                                         /*tp_dict*/
   1032     0,                                         /*tp_descr_get*/
   1033     0,                                         /*tp_descr_set*/
   1034     offsetof(bytesio, dict),             /*tp_dictoffset*/
   1035     _io_BytesIO___init__,                      /*tp_init*/
   1036     0,                                         /*tp_alloc*/
   1037     bytesio_new,                               /*tp_new*/
   1038 };
   1039 
   1040 
   1041 /*
   1042  * Implementation of the small intermediate object used by getbuffer().
   1043  * getbuffer() returns a memoryview over this object, which should make it
   1044  * invisible from Python code.
   1045  */
   1046 
   1047 static int
   1048 bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
   1049 {
   1050     bytesio *b = (bytesio *) obj->source;
   1051 
   1052     if (view == NULL) {
   1053         PyErr_SetString(PyExc_BufferError,
   1054             "bytesiobuf_getbuffer: view==NULL argument is obsolete");
   1055         return -1;
   1056     }
   1057     if (SHARED_BUF(b)) {
   1058         if (unshare_buffer(b, b->string_size) < 0)
   1059             return -1;
   1060     }
   1061 
   1062     /* cannot fail if view != NULL and readonly == 0 */
   1063     (void)PyBuffer_FillInfo(view, (PyObject*)obj,
   1064                             PyBytes_AS_STRING(b->buf), b->string_size,
   1065                             0, flags);
   1066     b->exports++;
   1067     return 0;
   1068 }
   1069 
   1070 static void
   1071 bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
   1072 {
   1073     bytesio *b = (bytesio *) obj->source;
   1074     b->exports--;
   1075 }
   1076 
   1077 static int
   1078 bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
   1079 {
   1080     Py_VISIT(self->source);
   1081     return 0;
   1082 }
   1083 
   1084 static void
   1085 bytesiobuf_dealloc(bytesiobuf *self)
   1086 {
   1087     /* bpo-31095: UnTrack is needed before calling any callbacks */
   1088     PyObject_GC_UnTrack(self);
   1089     Py_CLEAR(self->source);
   1090     Py_TYPE(self)->tp_free(self);
   1091 }
   1092 
   1093 static PyBufferProcs bytesiobuf_as_buffer = {
   1094     (getbufferproc) bytesiobuf_getbuffer,
   1095     (releasebufferproc) bytesiobuf_releasebuffer,
   1096 };
   1097 
   1098 PyTypeObject _PyBytesIOBuffer_Type = {
   1099     PyVarObject_HEAD_INIT(NULL, 0)
   1100     "_io._BytesIOBuffer",                      /*tp_name*/
   1101     sizeof(bytesiobuf),                        /*tp_basicsize*/
   1102     0,                                         /*tp_itemsize*/
   1103     (destructor)bytesiobuf_dealloc,            /*tp_dealloc*/
   1104     0,                                         /*tp_print*/
   1105     0,                                         /*tp_getattr*/
   1106     0,                                         /*tp_setattr*/
   1107     0,                                         /*tp_reserved*/
   1108     0,                                         /*tp_repr*/
   1109     0,                                         /*tp_as_number*/
   1110     0,                                         /*tp_as_sequence*/
   1111     0,                                         /*tp_as_mapping*/
   1112     0,                                         /*tp_hash*/
   1113     0,                                         /*tp_call*/
   1114     0,                                         /*tp_str*/
   1115     0,                                         /*tp_getattro*/
   1116     0,                                         /*tp_setattro*/
   1117     &bytesiobuf_as_buffer,                     /*tp_as_buffer*/
   1118     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
   1119     0,                                         /*tp_doc*/
   1120     (traverseproc)bytesiobuf_traverse,         /*tp_traverse*/
   1121     0,                                         /*tp_clear*/
   1122     0,                                         /*tp_richcompare*/
   1123     0,                                         /*tp_weaklistoffset*/
   1124     0,                                         /*tp_iter*/
   1125     0,                                         /*tp_iternext*/
   1126     0,                                         /*tp_methods*/
   1127     0,                                         /*tp_members*/
   1128     0,                                         /*tp_getset*/
   1129     0,                                         /*tp_base*/
   1130     0,                                         /*tp_dict*/
   1131     0,                                         /*tp_descr_get*/
   1132     0,                                         /*tp_descr_set*/
   1133     0,                                         /*tp_dictoffset*/
   1134     0,                                         /*tp_init*/
   1135     0,                                         /*tp_alloc*/
   1136     0,                                         /*tp_new*/
   1137 };
   1138