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