Home | History | Annotate | Download | only in _io
      1 #include "Python.h"
      2 #include "structmember.h"       /* for offsetof() */
      3 #include "_iomodule.h"
      4 
      5 typedef struct {
      6     PyObject_HEAD
      7     char *buf;
      8     Py_ssize_t pos;
      9     Py_ssize_t string_size;
     10     size_t buf_size;
     11     PyObject *dict;
     12     PyObject *weakreflist;
     13 } bytesio;
     14 
     15 #define CHECK_CLOSED(self)                                  \
     16     if ((self)->buf == NULL) {                              \
     17         PyErr_SetString(PyExc_ValueError,                   \
     18                         "I/O operation on closed file.");   \
     19         return NULL;                                        \
     20     }
     21 
     22 /* Internal routine to get a line from the buffer of a BytesIO
     23    object. Returns the length between the current position to the
     24    next newline character. */
     25 static Py_ssize_t
     26 get_line(bytesio *self, char **output)
     27 {
     28     char *n;
     29     const char *str_end;
     30     Py_ssize_t len;
     31 
     32     assert(self->buf != NULL);
     33 
     34     /* Move to the end of the line, up to the end of the string, s. */
     35     str_end = self->buf + self->string_size;
     36     for (n = self->buf + self->pos;
     37          n < str_end && *n != '\n';
     38          n++);
     39 
     40     /* Skip the newline character */
     41     if (n < str_end)
     42         n++;
     43 
     44     /* Get the length from the current position to the end of the line. */
     45     len = n - (self->buf + self->pos);
     46     *output = self->buf + self->pos;
     47 
     48     assert(len >= 0);
     49     assert(self->pos < PY_SSIZE_T_MAX - len);
     50     self->pos += len;
     51 
     52     return len;
     53 }
     54 
     55 /* Internal routine for changing the size of the buffer of BytesIO objects.
     56    The caller should ensure that the 'size' argument is non-negative.  Returns
     57    0 on success, -1 otherwise. */
     58 static int
     59 resize_buffer(bytesio *self, size_t size)
     60 {
     61     /* Here, unsigned types are used to avoid dealing with signed integer
     62        overflow, which is undefined in C. */
     63     size_t alloc = self->buf_size;
     64     char *new_buf = NULL;
     65 
     66     assert(self->buf != NULL);
     67 
     68     /* For simplicity, stay in the range of the signed type. Anyway, Python
     69        doesn't allow strings to be longer than this. */
     70     if (size > PY_SSIZE_T_MAX)
     71         goto overflow;
     72 
     73     if (size < alloc / 2) {
     74         /* Major downsize; resize down to exact size. */
     75         alloc = size + 1;
     76     }
     77     else if (size < alloc) {
     78         /* Within allocated size; quick exit */
     79         return 0;
     80     }
     81     else if (size <= alloc * 1.125) {
     82         /* Moderate upsize; overallocate similar to list_resize() */
     83         alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
     84     }
     85     else {
     86         /* Major upsize; resize up to exact size */
     87         alloc = size + 1;
     88     }
     89 
     90     if (alloc > ((size_t)-1) / sizeof(char))
     91         goto overflow;
     92     new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char));
     93     if (new_buf == NULL) {
     94         PyErr_NoMemory();
     95         return -1;
     96     }
     97     self->buf_size = alloc;
     98     self->buf = new_buf;
     99 
    100     return 0;
    101 
    102   overflow:
    103     PyErr_SetString(PyExc_OverflowError,
    104                     "new buffer size too large");
    105     return -1;
    106 }
    107 
    108 /* Internal routine for writing a string of bytes to the buffer of a BytesIO
    109    object. Returns the number of bytes written, or -1 on error. */
    110 static Py_ssize_t
    111 write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
    112 {
    113     assert(self->buf != NULL);
    114     assert(self->pos >= 0);
    115     assert(len >= 0);
    116 
    117     if ((size_t)self->pos + len > self->buf_size) {
    118         if (resize_buffer(self, (size_t)self->pos + len) < 0)
    119             return -1;
    120     }
    121 
    122     if (self->pos > self->string_size) {
    123         /* In case of overseek, pad with null bytes the buffer region between
    124            the end of stream and the current position.
    125 
    126           0   lo      string_size                           hi
    127           |   |<---used--->|<----------available----------->|
    128           |   |            <--to pad-->|<---to write--->    |
    129           0   buf                   position
    130         */
    131         memset(self->buf + self->string_size, '\0',
    132                (self->pos - self->string_size) * sizeof(char));
    133     }
    134 
    135     /* Copy the data to the internal buffer, overwriting some of the existing
    136        data if self->pos < self->string_size. */
    137     memcpy(self->buf + self->pos, bytes, len);
    138     self->pos += len;
    139 
    140     /* Set the new length of the internal string if it has changed. */
    141     if (self->string_size < self->pos) {
    142         self->string_size = self->pos;
    143     }
    144 
    145     return len;
    146 }
    147 
    148 static PyObject *
    149 bytesio_get_closed(bytesio *self)
    150 {
    151     if (self->buf == NULL) {
    152         Py_RETURN_TRUE;
    153     }
    154     else {
    155         Py_RETURN_FALSE;
    156     }
    157 }
    158 
    159 PyDoc_STRVAR(readable_doc,
    160 "readable() -> bool. Returns True if the IO object can be read.");
    161 
    162 PyDoc_STRVAR(writable_doc,
    163 "writable() -> bool. Returns True if the IO object can be written.");
    164 
    165 PyDoc_STRVAR(seekable_doc,
    166 "seekable() -> bool. Returns True if the IO object can be seeked.");
    167 
    168 /* Generic getter for the writable, readable and seekable properties */
    169 static PyObject *
    170 return_not_closed(bytesio *self)
    171 {
    172     CHECK_CLOSED(self);
    173     Py_RETURN_TRUE;
    174 }
    175 
    176 PyDoc_STRVAR(flush_doc,
    177 "flush() -> None.  Does nothing.");
    178 
    179 static PyObject *
    180 bytesio_flush(bytesio *self)
    181 {
    182     CHECK_CLOSED(self);
    183     Py_RETURN_NONE;
    184 }
    185 
    186 PyDoc_STRVAR(getval_doc,
    187 "getvalue() -> bytes.\n"
    188 "\n"
    189 "Retrieve the entire contents of the BytesIO object.");
    190 
    191 static PyObject *
    192 bytesio_getvalue(bytesio *self)
    193 {
    194     CHECK_CLOSED(self);
    195     return PyBytes_FromStringAndSize(self->buf, self->string_size);
    196 }
    197 
    198 PyDoc_STRVAR(isatty_doc,
    199 "isatty() -> False.\n"
    200 "\n"
    201 "Always returns False since BytesIO objects are not connected\n"
    202 "to a tty-like device.");
    203 
    204 static PyObject *
    205 bytesio_isatty(bytesio *self)
    206 {
    207     CHECK_CLOSED(self);
    208     Py_RETURN_FALSE;
    209 }
    210 
    211 PyDoc_STRVAR(tell_doc,
    212 "tell() -> current file position, an integer\n");
    213 
    214 static PyObject *
    215 bytesio_tell(bytesio *self)
    216 {
    217     CHECK_CLOSED(self);
    218     return PyLong_FromSsize_t(self->pos);
    219 }
    220 
    221 PyDoc_STRVAR(read_doc,
    222 "read([size]) -> read at most size bytes, returned as a string.\n"
    223 "\n"
    224 "If the size argument is negative, read until EOF is reached.\n"
    225 "Return an empty string at EOF.");
    226 
    227 static PyObject *
    228 bytesio_read(bytesio *self, PyObject *args)
    229 {
    230     Py_ssize_t size, n;
    231     char *output;
    232     PyObject *arg = Py_None;
    233 
    234     CHECK_CLOSED(self);
    235 
    236     if (!PyArg_ParseTuple(args, "|O:read", &arg))
    237         return NULL;
    238 
    239     if (PyNumber_Check(arg)) {
    240         size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
    241         if (size == -1 && PyErr_Occurred())
    242             return NULL;
    243     }
    244     else if (arg == Py_None) {
    245         /* Read until EOF is reached, by default. */
    246         size = -1;
    247     }
    248     else {
    249         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    250                      Py_TYPE(arg)->tp_name);
    251         return NULL;
    252     }
    253 
    254     /* adjust invalid sizes */
    255     n = self->string_size - self->pos;
    256     if (size < 0 || size > n) {
    257         size = n;
    258         if (size < 0)
    259             size = 0;
    260     }
    261 
    262     assert(self->buf != NULL);
    263     output = self->buf + self->pos;
    264     self->pos += size;
    265 
    266     return PyBytes_FromStringAndSize(output, size);
    267 }
    268 
    269 
    270 PyDoc_STRVAR(read1_doc,
    271 "read1(size) -> read at most size bytes, returned as a string.\n"
    272 "\n"
    273 "If the size argument is negative or omitted, read until EOF is reached.\n"
    274 "Return an empty string at EOF.");
    275 
    276 static PyObject *
    277 bytesio_read1(bytesio *self, PyObject *n)
    278 {
    279     PyObject *arg, *res;
    280 
    281     arg = PyTuple_Pack(1, n);
    282     if (arg == NULL)
    283         return NULL;
    284     res  = bytesio_read(self, arg);
    285     Py_DECREF(arg);
    286     return res;
    287 }
    288 
    289 PyDoc_STRVAR(readline_doc,
    290 "readline([size]) -> next line from the file, as a string.\n"
    291 "\n"
    292 "Retain newline.  A non-negative size argument limits the maximum\n"
    293 "number of bytes to return (an incomplete line may be returned then).\n"
    294 "Return an empty string at EOF.\n");
    295 
    296 static PyObject *
    297 bytesio_readline(bytesio *self, PyObject *args)
    298 {
    299     Py_ssize_t size, n;
    300     char *output;
    301     PyObject *arg = Py_None;
    302 
    303     CHECK_CLOSED(self);
    304 
    305     if (!PyArg_ParseTuple(args, "|O:readline", &arg))
    306         return NULL;
    307 
    308     if (PyNumber_Check(arg)) {
    309         size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
    310         if (size == -1 && PyErr_Occurred())
    311             return NULL;
    312     }
    313     else if (arg == Py_None) {
    314         /* No size limit, by default. */
    315         size = -1;
    316     }
    317     else {
    318         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    319                      Py_TYPE(arg)->tp_name);
    320         return NULL;
    321     }
    322 
    323     n = get_line(self, &output);
    324 
    325     if (size >= 0 && size < n) {
    326         size = n - size;
    327         n -= size;
    328         self->pos -= size;
    329     }
    330 
    331     return PyBytes_FromStringAndSize(output, n);
    332 }
    333 
    334 PyDoc_STRVAR(readlines_doc,
    335 "readlines([size]) -> list of strings, each a line from the file.\n"
    336 "\n"
    337 "Call readline() repeatedly and return a list of the lines so read.\n"
    338 "The optional size argument, if given, is an approximate bound on the\n"
    339 "total number of bytes in the lines returned.\n");
    340 
    341 static PyObject *
    342 bytesio_readlines(bytesio *self, PyObject *args)
    343 {
    344     Py_ssize_t maxsize, size, n;
    345     PyObject *result, *line;
    346     char *output;
    347     PyObject *arg = Py_None;
    348 
    349     CHECK_CLOSED(self);
    350 
    351     if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
    352         return NULL;
    353 
    354     if (PyNumber_Check(arg)) {
    355         maxsize = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
    356         if (maxsize == -1 && PyErr_Occurred())
    357             return NULL;
    358     }
    359     else if (arg == Py_None) {
    360         /* No size limit, by default. */
    361         maxsize = -1;
    362     }
    363     else {
    364         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    365                      Py_TYPE(arg)->tp_name);
    366         return NULL;
    367     }
    368 
    369     size = 0;
    370     result = PyList_New(0);
    371     if (!result)
    372         return NULL;
    373 
    374     while ((n = get_line(self, &output)) != 0) {
    375         line = PyBytes_FromStringAndSize(output, n);
    376         if (!line)
    377             goto on_error;
    378         if (PyList_Append(result, line) == -1) {
    379             Py_DECREF(line);
    380             goto on_error;
    381         }
    382         Py_DECREF(line);
    383         size += n;
    384         if (maxsize > 0 && size >= maxsize)
    385             break;
    386     }
    387     return result;
    388 
    389   on_error:
    390     Py_DECREF(result);
    391     return NULL;
    392 }
    393 
    394 PyDoc_STRVAR(readinto_doc,
    395 "readinto(bytearray) -> int.  Read up to len(b) bytes into b.\n"
    396 "\n"
    397 "Returns number of bytes read (0 for EOF), or None if the object\n"
    398 "is set not to block as has no data to read.");
    399 
    400 static PyObject *
    401 bytesio_readinto(bytesio *self, PyObject *args)
    402 {
    403     Py_buffer buf;
    404     Py_ssize_t len, n;
    405 
    406     CHECK_CLOSED(self);
    407 
    408     if (!PyArg_ParseTuple(args, "w*", &buf))
    409         return NULL;
    410 
    411     len = buf.len;
    412     /* adjust invalid sizes */
    413     n = self->string_size - self->pos;
    414     if (len > n) {
    415         len = n;
    416         if (len < 0)
    417             len = 0;
    418     }
    419 
    420     memcpy(buf.buf, self->buf + self->pos, len);
    421     assert(self->pos + len < PY_SSIZE_T_MAX);
    422     assert(len >= 0);
    423     self->pos += len;
    424 
    425     PyBuffer_Release(&buf);
    426     return PyLong_FromSsize_t(len);
    427 }
    428 
    429 PyDoc_STRVAR(truncate_doc,
    430 "truncate([size]) -> int.  Truncate the file to at most size bytes.\n"
    431 "\n"
    432 "Size defaults to the current file position, as returned by tell().\n"
    433 "The current file position is unchanged.  Returns the new size.\n");
    434 
    435 static PyObject *
    436 bytesio_truncate(bytesio *self, PyObject *args)
    437 {
    438     Py_ssize_t size;
    439     PyObject *arg = Py_None;
    440 
    441     CHECK_CLOSED(self);
    442 
    443     if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
    444         return NULL;
    445 
    446     if (PyNumber_Check(arg)) {
    447         size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
    448         if (size == -1 && PyErr_Occurred())
    449             return NULL;
    450     }
    451     else if (arg == Py_None) {
    452         /* Truncate to current position if no argument is passed. */
    453         size = self->pos;
    454     }
    455     else {
    456         PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
    457                      Py_TYPE(arg)->tp_name);
    458         return NULL;
    459     }
    460 
    461     if (size < 0) {
    462         PyErr_Format(PyExc_ValueError,
    463                      "negative size value %zd", size);
    464         return NULL;
    465     }
    466 
    467     if (size < self->string_size) {
    468         self->string_size = size;
    469         if (resize_buffer(self, size) < 0)
    470             return NULL;
    471     }
    472 
    473     return PyLong_FromSsize_t(size);
    474 }
    475 
    476 static PyObject *
    477 bytesio_iternext(bytesio *self)
    478 {
    479     char *next;
    480     Py_ssize_t n;
    481 
    482     CHECK_CLOSED(self);
    483 
    484     n = get_line(self, &next);
    485 
    486     if (!next || n == 0)
    487         return NULL;
    488 
    489     return PyBytes_FromStringAndSize(next, n);
    490 }
    491 
    492 PyDoc_STRVAR(seek_doc,
    493 "seek(pos, whence=0) -> int.  Change stream position.\n"
    494 "\n"
    495 "Seek to byte offset pos relative to position indicated by whence:\n"
    496 "     0  Start of stream (the default).  pos should be >= 0;\n"
    497 "     1  Current position - pos may be negative;\n"
    498 "     2  End of stream - pos usually negative.\n"
    499 "Returns the new absolute position.");
    500 
    501 static PyObject *
    502 bytesio_seek(bytesio *self, PyObject *args)
    503 {
    504     PyObject *posobj;
    505     Py_ssize_t pos;
    506     int mode = 0;
    507 
    508     CHECK_CLOSED(self);
    509 
    510     if (!PyArg_ParseTuple(args, "O|i:seek", &posobj, &mode))
    511         return NULL;
    512 
    513     pos = PyNumber_AsSsize_t(posobj, PyExc_OverflowError);
    514     if (pos == -1 && PyErr_Occurred())
    515         return NULL;
    516 
    517     if (pos < 0 && mode == 0) {
    518         PyErr_Format(PyExc_ValueError,
    519                      "negative seek value %zd", pos);
    520         return NULL;
    521     }
    522 
    523     /* mode 0: offset relative to beginning of the string.
    524        mode 1: offset relative to current position.
    525        mode 2: offset relative the end of the string. */
    526     if (mode == 1) {
    527         if (pos > PY_SSIZE_T_MAX - self->pos) {
    528             PyErr_SetString(PyExc_OverflowError,
    529                             "new position too large");
    530             return NULL;
    531         }
    532         pos += self->pos;
    533     }
    534     else if (mode == 2) {
    535         if (pos > PY_SSIZE_T_MAX - self->string_size) {
    536             PyErr_SetString(PyExc_OverflowError,
    537                             "new position too large");
    538             return NULL;
    539         }
    540         pos += self->string_size;
    541     }
    542     else if (mode != 0) {
    543         PyErr_Format(PyExc_ValueError,
    544                      "invalid whence (%i, should be 0, 1 or 2)", mode);
    545         return NULL;
    546     }
    547 
    548     if (pos < 0)
    549         pos = 0;
    550     self->pos = pos;
    551 
    552     return PyLong_FromSsize_t(self->pos);
    553 }
    554 
    555 PyDoc_STRVAR(write_doc,
    556 "write(bytes) -> int.  Write bytes to file.\n"
    557 "\n"
    558 "Return the number of bytes written.");
    559 
    560 static PyObject *
    561 bytesio_write(bytesio *self, PyObject *obj)
    562 {
    563     Py_ssize_t n = 0;
    564     Py_buffer buf;
    565     PyObject *result = NULL;
    566 
    567     CHECK_CLOSED(self);
    568 
    569     if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
    570         return NULL;
    571 
    572     if (buf.len != 0)
    573         n = write_bytes(self, buf.buf, buf.len);
    574     if (n >= 0)
    575         result = PyLong_FromSsize_t(n);
    576 
    577     PyBuffer_Release(&buf);
    578     return result;
    579 }
    580 
    581 PyDoc_STRVAR(writelines_doc,
    582 "writelines(sequence_of_strings) -> None.  Write strings to the file.\n"
    583 "\n"
    584 "Note that newlines are not added.  The sequence can be any iterable\n"
    585 "object producing strings. This is equivalent to calling write() for\n"
    586 "each string.");
    587 
    588 static PyObject *
    589 bytesio_writelines(bytesio *self, PyObject *v)
    590 {
    591     PyObject *it, *item;
    592     PyObject *ret;
    593 
    594     CHECK_CLOSED(self);
    595 
    596     it = PyObject_GetIter(v);
    597     if (it == NULL)
    598         return NULL;
    599 
    600     while ((item = PyIter_Next(it)) != NULL) {
    601         ret = bytesio_write(self, item);
    602         Py_DECREF(item);
    603         if (ret == NULL) {
    604             Py_DECREF(it);
    605             return NULL;
    606         }
    607         Py_DECREF(ret);
    608     }
    609     Py_DECREF(it);
    610 
    611     /* See if PyIter_Next failed */
    612     if (PyErr_Occurred())
    613         return NULL;
    614 
    615     Py_RETURN_NONE;
    616 }
    617 
    618 PyDoc_STRVAR(close_doc,
    619 "close() -> None.  Disable all I/O operations.");
    620 
    621 static PyObject *
    622 bytesio_close(bytesio *self)
    623 {
    624     if (self->buf != NULL) {
    625         PyMem_Free(self->buf);
    626         self->buf = NULL;
    627     }
    628     Py_RETURN_NONE;
    629 }
    630 
    631 /* Pickling support.
    632 
    633    Note that only pickle protocol 2 and onward are supported since we use
    634    extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
    635 
    636    Providing support for protocol < 2 would require the __reduce_ex__ method
    637    which is notably long-winded when defined properly.
    638 
    639    For BytesIO, the implementation would similar to one coded for
    640    object.__reduce_ex__, but slightly less general. To be more specific, we
    641    could call bytesio_getstate directly and avoid checking for the presence of
    642    a fallback __reduce__ method. However, we would still need a __newobj__
    643    function to use the efficient instance representation of PEP 307.
    644  */
    645 
    646 static PyObject *
    647 bytesio_getstate(bytesio *self)
    648 {
    649     PyObject *initvalue = bytesio_getvalue(self);
    650     PyObject *dict;
    651     PyObject *state;
    652 
    653     if (initvalue == NULL)
    654         return NULL;
    655     if (self->dict == NULL) {
    656         Py_INCREF(Py_None);
    657         dict = Py_None;
    658     }
    659     else {
    660         dict = PyDict_Copy(self->dict);
    661         if (dict == NULL)
    662             return NULL;
    663     }
    664 
    665     state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
    666     Py_DECREF(initvalue);
    667     return state;
    668 }
    669 
    670 static PyObject *
    671 bytesio_setstate(bytesio *self, PyObject *state)
    672 {
    673     PyObject *result;
    674     PyObject *position_obj;
    675     PyObject *dict;
    676     Py_ssize_t pos;
    677 
    678     assert(state != NULL);
    679 
    680     /* We allow the state tuple to be longer than 3, because we may need
    681        someday to extend the object's state without breaking
    682        backward-compatibility. */
    683     if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
    684         PyErr_Format(PyExc_TypeError,
    685                      "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
    686                      Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
    687         return NULL;
    688     }
    689     /* Reset the object to its default state. This is only needed to handle
    690        the case of repeated calls to __setstate__. */
    691     self->string_size = 0;
    692     self->pos = 0;
    693 
    694     /* Set the value of the internal buffer. If state[0] does not support the
    695        buffer protocol, bytesio_write will raise the appropriate TypeError. */
    696     result = bytesio_write(self, PyTuple_GET_ITEM(state, 0));
    697     if (result == NULL)
    698         return NULL;
    699     Py_DECREF(result);
    700 
    701     /* Set carefully the position value. Alternatively, we could use the seek
    702        method instead of modifying self->pos directly to better protect the
    703        object internal state against errneous (or malicious) inputs. */
    704     position_obj = PyTuple_GET_ITEM(state, 1);
    705     if (!PyIndex_Check(position_obj)) {
    706         PyErr_Format(PyExc_TypeError,
    707                      "second item of state must be an integer, not %.200s",
    708                      Py_TYPE(position_obj)->tp_name);
    709         return NULL;
    710     }
    711     pos = PyNumber_AsSsize_t(position_obj, PyExc_OverflowError);
    712     if (pos == -1 && PyErr_Occurred())
    713         return NULL;
    714     if (pos < 0) {
    715         PyErr_SetString(PyExc_ValueError,
    716                         "position value cannot be negative");
    717         return NULL;
    718     }
    719     self->pos = pos;
    720 
    721     /* Set the dictionary of the instance variables. */
    722     dict = PyTuple_GET_ITEM(state, 2);
    723     if (dict != Py_None) {
    724         if (!PyDict_Check(dict)) {
    725             PyErr_Format(PyExc_TypeError,
    726                          "third item of state should be a dict, got a %.200s",
    727                          Py_TYPE(dict)->tp_name);
    728             return NULL;
    729         }
    730         if (self->dict) {
    731             /* Alternatively, we could replace the internal dictionary
    732                completely. However, it seems more practical to just update it. */
    733             if (PyDict_Update(self->dict, dict) < 0)
    734                 return NULL;
    735         }
    736         else {
    737             Py_INCREF(dict);
    738             self->dict = dict;
    739         }
    740     }
    741 
    742     Py_RETURN_NONE;
    743 }
    744 
    745 static void
    746 bytesio_dealloc(bytesio *self)
    747 {
    748     _PyObject_GC_UNTRACK(self);
    749     if (self->buf != NULL) {
    750         PyMem_Free(self->buf);
    751         self->buf = NULL;
    752     }
    753     Py_CLEAR(self->dict);
    754     if (self->weakreflist != NULL)
    755         PyObject_ClearWeakRefs((PyObject *) self);
    756     Py_TYPE(self)->tp_free(self);
    757 }
    758 
    759 static PyObject *
    760 bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    761 {
    762     bytesio *self;
    763 
    764     assert(type != NULL && type->tp_alloc != NULL);
    765     self = (bytesio *)type->tp_alloc(type, 0);
    766     if (self == NULL)
    767         return NULL;
    768 
    769     /* tp_alloc initializes all the fields to zero. So we don't have to
    770        initialize them here. */
    771 
    772     self->buf = (char *)PyMem_Malloc(0);
    773     if (self->buf == NULL) {
    774         Py_DECREF(self);
    775         return PyErr_NoMemory();
    776     }
    777 
    778     return (PyObject *)self;
    779 }
    780 
    781 static int
    782 bytesio_init(bytesio *self, PyObject *args, PyObject *kwds)
    783 {
    784     char *kwlist[] = {"initial_bytes", NULL};
    785     PyObject *initvalue = NULL;
    786 
    787     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:BytesIO", kwlist,
    788                                      &initvalue))
    789         return -1;
    790 
    791     /* In case, __init__ is called multiple times. */
    792     self->string_size = 0;
    793     self->pos = 0;
    794 
    795     if (initvalue && initvalue != Py_None) {
    796         PyObject *res;
    797         res = bytesio_write(self, initvalue);
    798         if (res == NULL)
    799             return -1;
    800         Py_DECREF(res);
    801         self->pos = 0;
    802     }
    803 
    804     return 0;
    805 }
    806 
    807 static PyObject *
    808 bytesio_sizeof(bytesio *self, void *unused)
    809 {
    810     Py_ssize_t res;
    811 
    812     res = sizeof(bytesio);
    813     if (self->buf)
    814         res += self->buf_size;
    815     return PyLong_FromSsize_t(res);
    816 }
    817 
    818 static int
    819 bytesio_traverse(bytesio *self, visitproc visit, void *arg)
    820 {
    821     Py_VISIT(self->dict);
    822     return 0;
    823 }
    824 
    825 static int
    826 bytesio_clear(bytesio *self)
    827 {
    828     Py_CLEAR(self->dict);
    829     return 0;
    830 }
    831 
    832 
    833 static PyGetSetDef bytesio_getsetlist[] = {
    834     {"closed",  (getter)bytesio_get_closed, NULL,
    835      "True if the file is closed."},
    836     {NULL},            /* sentinel */
    837 };
    838 
    839 static struct PyMethodDef bytesio_methods[] = {
    840     {"readable",   (PyCFunction)return_not_closed,  METH_NOARGS, readable_doc},
    841     {"seekable",   (PyCFunction)return_not_closed,  METH_NOARGS, seekable_doc},
    842     {"writable",   (PyCFunction)return_not_closed,  METH_NOARGS, writable_doc},
    843     {"close",      (PyCFunction)bytesio_close,      METH_NOARGS, close_doc},
    844     {"flush",      (PyCFunction)bytesio_flush,      METH_NOARGS, flush_doc},
    845     {"isatty",     (PyCFunction)bytesio_isatty,     METH_NOARGS, isatty_doc},
    846     {"tell",       (PyCFunction)bytesio_tell,       METH_NOARGS, tell_doc},
    847     {"write",      (PyCFunction)bytesio_write,      METH_O, write_doc},
    848     {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
    849     {"read1",      (PyCFunction)bytesio_read1,      METH_O, read1_doc},
    850     {"readinto",   (PyCFunction)bytesio_readinto,   METH_VARARGS, readinto_doc},
    851     {"readline",   (PyCFunction)bytesio_readline,   METH_VARARGS, readline_doc},
    852     {"readlines",  (PyCFunction)bytesio_readlines,  METH_VARARGS, readlines_doc},
    853     {"read",       (PyCFunction)bytesio_read,       METH_VARARGS, read_doc},
    854     {"getvalue",   (PyCFunction)bytesio_getvalue,   METH_NOARGS,  getval_doc},
    855     {"seek",       (PyCFunction)bytesio_seek,       METH_VARARGS, seek_doc},
    856     {"truncate",   (PyCFunction)bytesio_truncate,   METH_VARARGS, truncate_doc},
    857     {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
    858     {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
    859     {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
    860     {NULL, NULL}        /* sentinel */
    861 };
    862 
    863 PyDoc_STRVAR(bytesio_doc,
    864 "BytesIO([buffer]) -> object\n"
    865 "\n"
    866 "Create a buffered I/O implementation using an in-memory bytes\n"
    867 "buffer, ready for reading and writing.");
    868 
    869 PyTypeObject PyBytesIO_Type = {
    870     PyVarObject_HEAD_INIT(NULL, 0)
    871     "_io.BytesIO",                             /*tp_name*/
    872     sizeof(bytesio),                     /*tp_basicsize*/
    873     0,                                         /*tp_itemsize*/
    874     (destructor)bytesio_dealloc,               /*tp_dealloc*/
    875     0,                                         /*tp_print*/
    876     0,                                         /*tp_getattr*/
    877     0,                                         /*tp_setattr*/
    878     0,                                         /*tp_reserved*/
    879     0,                                         /*tp_repr*/
    880     0,                                         /*tp_as_number*/
    881     0,                                         /*tp_as_sequence*/
    882     0,                                         /*tp_as_mapping*/
    883     0,                                         /*tp_hash*/
    884     0,                                         /*tp_call*/
    885     0,                                         /*tp_str*/
    886     0,                                         /*tp_getattro*/
    887     0,                                         /*tp_setattro*/
    888     0,                                         /*tp_as_buffer*/
    889     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
    890     Py_TPFLAGS_HAVE_GC,                        /*tp_flags*/
    891     bytesio_doc,                               /*tp_doc*/
    892     (traverseproc)bytesio_traverse,            /*tp_traverse*/
    893     (inquiry)bytesio_clear,                    /*tp_clear*/
    894     0,                                         /*tp_richcompare*/
    895     offsetof(bytesio, weakreflist),      /*tp_weaklistoffset*/
    896     PyObject_SelfIter,                         /*tp_iter*/
    897     (iternextfunc)bytesio_iternext,            /*tp_iternext*/
    898     bytesio_methods,                           /*tp_methods*/
    899     0,                                         /*tp_members*/
    900     bytesio_getsetlist,                        /*tp_getset*/
    901     0,                                         /*tp_base*/
    902     0,                                         /*tp_dict*/
    903     0,                                         /*tp_descr_get*/
    904     0,                                         /*tp_descr_set*/
    905     offsetof(bytesio, dict),             /*tp_dictoffset*/
    906     (initproc)bytesio_init,                    /*tp_init*/
    907     0,                                         /*tp_alloc*/
    908     bytesio_new,                               /*tp_new*/
    909 };
    910