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