177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti#include "Python.h"
24fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson#include "structmember.h"       /* for offsetof() */
34fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson#include "_iomodule.h"
477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
5f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
6f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakamodule _io
7f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakaclass _io.BytesIO "bytesio *" "&PyBytesIO_Type"
8f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
9f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
10f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
1177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottitypedef struct {
1277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyObject_HEAD
1387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    PyObject *buf;
1477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t pos;
1577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t string_size;
164fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    PyObject *dict;
174fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    PyObject *weakreflist;
18972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_ssize_t exports;
19680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Peterson} bytesio;
2077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
21972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroutypedef struct {
22972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    PyObject_HEAD
23972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    bytesio *source;
24972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou} bytesiobuf;
25972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
2687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka/* The bytesio object can be in three states:
2787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka  * Py_REFCNT(buf) == 1, exports == 0.
2838c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka  * Py_REFCNT(buf) > 1.  exports == 0,
2987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    first modification or export causes the internal buffer copying.
3087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka  * exports > 0.  Py_REFCNT(buf) == 1, any modifications are forbidden.
3187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka*/
32972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
3387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka#define CHECK_CLOSED(self)                                  \
3477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if ((self)->buf == NULL) {                              \
3577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_SetString(PyExc_ValueError,                   \
3677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                        "I/O operation on closed file.");   \
3787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        return NULL;                                        \
3877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
3977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
40972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou#define CHECK_EXPORTS(self) \
41972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    if ((self)->exports > 0) { \
42972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou        PyErr_SetString(PyExc_BufferError, \
43972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou                        "Existing exports of data: object cannot be re-sized"); \
44972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou        return NULL; \
45972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    }
46972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
4738c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
48cc66a73d27ba8b3051586221f96effef67c3bb3aAntoine Pitrou
49972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
5077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti/* Internal routine to get a line from the buffer of a BytesIO
5177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti   object. Returns the length between the current position to the
5277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti   next newline character. */
5377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic Py_ssize_t
54d7728cafc585b554d347250afd923740432dac5aSerhiy Storchakascan_eol(bytesio *self, Py_ssize_t len)
5577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
56d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    const char *start, *n;
57d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    Py_ssize_t maxlen;
5877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
5977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(self->buf != NULL);
604e63f7a2b4e3602c420c8ae59a16020b14f8ee13Serhiy Storchaka    assert(self->pos >= 0);
614e63f7a2b4e3602c420c8ae59a16020b14f8ee13Serhiy Storchaka
624e63f7a2b4e3602c420c8ae59a16020b14f8ee13Serhiy Storchaka    if (self->pos >= self->string_size)
634e63f7a2b4e3602c420c8ae59a16020b14f8ee13Serhiy Storchaka        return 0;
6477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
6577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* Move to the end of the line, up to the end of the string, s. */
66d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    maxlen = self->string_size - self->pos;
67d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    if (len < 0 || len > maxlen)
68d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka        len = maxlen;
69d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka
70d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    if (len) {
714e63f7a2b4e3602c420c8ae59a16020b14f8ee13Serhiy Storchaka        start = PyBytes_AS_STRING(self->buf) + self->pos;
72d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka        n = memchr(start, '\n', len);
73d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka        if (n)
74d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka            /* Get the length from the current position to the end of
75d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka               the line. */
76d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka            len = n - start + 1;
77d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    }
7877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(len >= 0);
7977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(self->pos < PY_SSIZE_T_MAX - len);
8077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
8177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return len;
8277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
8377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
8487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka/* Internal routine for detaching the shared buffer of BytesIO objects.
8587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka   The caller should ensure that the 'size' argument is non-negative and
8687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka   not lesser than self->string_size.  Returns 0 on success, -1 otherwise. */
8787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchakastatic int
8887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchakaunshare_buffer(bytesio *self, size_t size)
8987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka{
901ed017ae92b32b27186d5793f6e58c526f350a2bSerhiy Storchaka    PyObject *new_buf;
9187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    assert(SHARED_BUF(self));
9287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    assert(self->exports == 0);
9387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    assert(size >= (size_t)self->string_size);
9487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    new_buf = PyBytes_FromStringAndSize(NULL, size);
9587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (new_buf == NULL)
9687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        return -1;
9787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
9887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka           self->string_size);
99f01e408c1688a207eba18444da8c151c872fba59Serhiy Storchaka    Py_SETREF(self->buf, new_buf);
10087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return 0;
10187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka}
10287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
10377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti/* Internal routine for changing the size of the buffer of BytesIO objects.
10477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti   The caller should ensure that the 'size' argument is non-negative.  Returns
10577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti   0 on success, -1 otherwise. */
10677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic int
107680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonresize_buffer(bytesio *self, size_t size)
10877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
10977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* Here, unsigned types are used to avoid dealing with signed integer
11077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti       overflow, which is undefined in C. */
11187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    size_t alloc = PyBytes_GET_SIZE(self->buf);
11277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
11377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(self->buf != NULL);
11477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
11577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* For simplicity, stay in the range of the signed type. Anyway, Python
11677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti       doesn't allow strings to be longer than this. */
11777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (size > PY_SSIZE_T_MAX)
11877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        goto overflow;
11977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
12077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (size < alloc / 2) {
12177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* Major downsize; resize down to exact size. */
12277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        alloc = size + 1;
12377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
12477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else if (size < alloc) {
12577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* Within allocated size; quick exit */
12677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return 0;
12777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
12877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else if (size <= alloc * 1.125) {
12977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* Moderate upsize; overallocate similar to list_resize() */
13077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
13177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
13277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else {
13377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* Major upsize; resize up to exact size */
13477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        alloc = size + 1;
13577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
13677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
13777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (alloc > ((size_t)-1) / sizeof(char))
13877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        goto overflow;
13987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
14087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (SHARED_BUF(self)) {
14187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        if (unshare_buffer(self, alloc) < 0)
14287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            return -1;
14387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
14487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    else {
14587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        if (_PyBytes_Resize(&self->buf, alloc) < 0)
14687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            return -1;
14777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
14877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
14977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return 0;
15077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
15177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti  overflow:
15277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyErr_SetString(PyExc_OverflowError,
15377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                    "new buffer size too large");
15477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return -1;
15577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
15677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
15777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti/* Internal routine for writing a string of bytes to the buffer of a BytesIO
1581d857453b7065dafdc34a72c1bbb2a993782b383Antoine Pitrou   object. Returns the number of bytes written, or -1 on error. */
15977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic Py_ssize_t
160680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonwrite_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
16177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
16238c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka    size_t endpos;
16377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(self->buf != NULL);
16477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(self->pos >= 0);
16577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(len >= 0);
16677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
16738c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka    endpos = (size_t)self->pos + len;
16838c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka    if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
16938c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka        if (resize_buffer(self, endpos) < 0)
17077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            return -1;
17177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
17287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    else if (SHARED_BUF(self)) {
17338c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka        if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
17487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            return -1;
17587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
17677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
17777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (self->pos > self->string_size) {
17877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* In case of overseek, pad with null bytes the buffer region between
17977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti           the end of stream and the current position.
18077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
18177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti          0   lo      string_size                           hi
18277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti          |   |<---used--->|<----------available----------->|
18377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti          |   |            <--to pad-->|<---to write--->    |
18477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti          0   buf                   position
18577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        */
18687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
18777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti               (self->pos - self->string_size) * sizeof(char));
18877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
18977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
19077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* Copy the data to the internal buffer, overwriting some of the existing
19177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti       data if self->pos < self->string_size. */
19287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
19338c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka    self->pos = endpos;
19477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
19577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* Set the new length of the internal string if it has changed. */
19638c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka    if ((size_t)self->string_size < endpos) {
19738c30e6c8e34241a1ea226fdd4ff74be6a8ee846Serhiy Storchaka        self->string_size = endpos;
19877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
19977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
20077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return len;
20177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
20277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
20377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
204680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonbytesio_get_closed(bytesio *self)
20577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
2064fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    if (self->buf == NULL) {
20777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        Py_RETURN_TRUE;
2084fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    }
2094fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    else {
21077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        Py_RETURN_FALSE;
2114fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    }
21277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
21377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
214f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
215f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.readable
2161d857453b7065dafdc34a72c1bbb2a993782b383Antoine Pitrou
217f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturns True if the IO object can be read.
218f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
2191d857453b7065dafdc34a72c1bbb2a993782b383Antoine Pitrou
220f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakastatic PyObject *
221f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_readable_impl(bytesio *self)
222f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
223f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka{
224f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    CHECK_CLOSED(self);
225f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    Py_RETURN_TRUE;
226f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka}
227f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
228f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
229f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.writable
230f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
231f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturns True if the IO object can be written.
232f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
2331d857453b7065dafdc34a72c1bbb2a993782b383Antoine Pitrou
23477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
235f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_writable_impl(bytesio *self)
236f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
23777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
23887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
23977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_RETURN_TRUE;
24077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
24177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
242f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
243f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.seekable
244f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
245f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturns True if the IO object can be seeked.
246f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
247f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
248f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakastatic PyObject *
249f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_seekable_impl(bytesio *self)
250f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
251f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka{
252f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    CHECK_CLOSED(self);
253f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    Py_RETURN_TRUE;
254f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka}
255f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
256f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
257f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.flush
258f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
259f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaDoes nothing.
260f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
26177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
26277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
263f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_flush_impl(bytesio *self)
264f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
26577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
26687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
26777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_RETURN_NONE;
26877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
26977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
270f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
271f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.getbuffer
272f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
273f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaGet a read-write view over the contents of the BytesIO object.
274f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
275972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
276972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroustatic PyObject *
277f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_getbuffer_impl(bytesio *self)
278f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
279972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou{
280972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    PyTypeObject *type = &_PyBytesIOBuffer_Type;
281972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    bytesiobuf *buf;
282972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    PyObject *view;
283972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
28487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
285972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
286972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    buf = (bytesiobuf *) type->tp_alloc(type, 0);
287972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    if (buf == NULL)
288972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou        return NULL;
289972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_INCREF(self);
290972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    buf->source = self;
291972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    view = PyMemoryView_FromObject((PyObject *) buf);
292972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_DECREF(buf);
293972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    return view;
294972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou}
295972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
296f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
297f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.getvalue
298f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
299f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaRetrieve the entire contents of the BytesIO object.
300f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
30177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
30277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
303f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_getvalue_impl(bytesio *self)
304f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
30577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
30687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
30787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (self->string_size <= 1 || self->exports > 0)
30887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
30987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka                                         self->string_size);
31087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
31187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
31287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        if (SHARED_BUF(self)) {
31387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            if (unshare_buffer(self, self->string_size) < 0)
31487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka                return NULL;
31587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        }
31687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        else {
31787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
31887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka                return NULL;
31987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        }
32087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
32187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    Py_INCREF(self->buf);
32287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return self->buf;
32377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
32477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
325f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
326f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.isatty
327f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
328f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaAlways returns False.
329f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
330f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaBytesIO objects are not connected to a TTY-like device.
331f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
33277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
33377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
334f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_isatty_impl(bytesio *self)
335f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
33677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
33787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
33877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_RETURN_FALSE;
33977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
34077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
341f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
342f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.tell
343f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
344f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaCurrent file position, an integer.
345f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
34677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
34777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
348f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_tell_impl(bytesio *self)
349f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
35077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
35187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
35277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return PyLong_FromSsize_t(self->pos);
35377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
35477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
35587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchakastatic PyObject *
35687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchakaread_bytes(bytesio *self, Py_ssize_t size)
35787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka{
35887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    char *output;
35987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
36087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    assert(self->buf != NULL);
361b9765eec5cbc149120acb50646256cffde94d74fSerhiy Storchaka    assert(size <= self->string_size);
36287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (size > 1 &&
36387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
36487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        self->exports == 0) {
36587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        self->pos += size;
36687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        Py_INCREF(self->buf);
36787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        return self->buf;
36887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
36987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
37087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    output = PyBytes_AS_STRING(self->buf) + self->pos;
37187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    self->pos += size;
37287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return PyBytes_FromStringAndSize(output, size);
37387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka}
37487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
375f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
376f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.read
377f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    size as arg: object = None
378f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
379f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
380f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaRead at most size bytes, returned as a bytes object.
381f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
382f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaIf the size argument is negative, read until EOF is reached.
383f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturn an empty bytes object at EOF.
384f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
38577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
38677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
387f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_read_impl(bytesio *self, PyObject *arg)
388f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
38977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
39077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t size, n;
39177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
39287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
39377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
39477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (PyLong_Check(arg)) {
39577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = PyLong_AsSsize_t(arg);
396a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson        if (size == -1 && PyErr_Occurred())
397a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson            return NULL;
39877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
39977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else if (arg == Py_None) {
40077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* Read until EOF is reached, by default. */
40177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = -1;
40277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
40377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else {
40477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
40577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                     Py_TYPE(arg)->tp_name);
40677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
40777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
40877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
40977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* adjust invalid sizes */
41077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    n = self->string_size - self->pos;
41177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (size < 0 || size > n) {
41277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = n;
41377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (size < 0)
41477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            size = 0;
41577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
41677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
41787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return read_bytes(self, size);
41877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
41977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
42077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
421f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
422f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.read1
423f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    size: object
424f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
425f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
426f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaRead at most size bytes, returned as a bytes object.
427f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
428f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaIf the size argument is negative or omitted, read until EOF is reached.
429f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturn an empty bytes object at EOF.
430f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
43177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
43277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
433f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_read1(bytesio *self, PyObject *size)
434f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/
43577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
436f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    return _io_BytesIO_read_impl(self, size);
43777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
43877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
439f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
440f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.readline
441f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    size as arg: object = None
442f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
443f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
444f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaNext line from the file, as a bytes object.
445f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
446f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaRetain newline.  A non-negative size argument limits the maximum
447f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakanumber of bytes to return (an incomplete line may be returned then).
448f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturn an empty bytes object at EOF.
449f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
45077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
45177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
452f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
453f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
45477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
45577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t size, n;
45677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
45787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
45877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
45977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (PyLong_Check(arg)) {
46077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = PyLong_AsSsize_t(arg);
461a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson        if (size == -1 && PyErr_Occurred())
462a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson            return NULL;
46377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
46477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else if (arg == Py_None) {
46577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* No size limit, by default. */
46677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = -1;
46777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
46877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else {
46977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
47077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                     Py_TYPE(arg)->tp_name);
47177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
47277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
47377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
474d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    n = scan_eol(self, size);
47577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
47687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return read_bytes(self, n);
47777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
47877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
479f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
480f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.readlines
481f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    size as arg: object = None
482f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
483f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
484f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaList of bytes objects, each a line from the file.
485f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
486f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaCall readline() repeatedly and return a list of the lines so read.
487f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaThe optional size argument, if given, is an approximate bound on the
488f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakatotal number of bytes in the lines returned.
489f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
49077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
49177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
492f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
493f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
49477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
49577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t maxsize, size, n;
49677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyObject *result, *line;
49777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    char *output;
49877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
49987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
50077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
50177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (PyLong_Check(arg)) {
50277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        maxsize = PyLong_AsSsize_t(arg);
503a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson        if (maxsize == -1 && PyErr_Occurred())
504a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson            return NULL;
50577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
50677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else if (arg == Py_None) {
50777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* No size limit, by default. */
50877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        maxsize = -1;
50977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
51077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else {
51177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
51277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                     Py_TYPE(arg)->tp_name);
51377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
51477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
51577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
51677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    size = 0;
51777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    result = PyList_New(0);
51877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (!result)
51977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
52077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
52187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    output = PyBytes_AS_STRING(self->buf) + self->pos;
522d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    while ((n = scan_eol(self, -1)) != 0) {
523d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka        self->pos += n;
52472b710a59617ebe6dd1c41613d2c7eb81702efd9Christian Heimes        line = PyBytes_FromStringAndSize(output, n);
52577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (!line)
52677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            goto on_error;
52777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (PyList_Append(result, line) == -1) {
52877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            Py_DECREF(line);
52977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            goto on_error;
53077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        }
53177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        Py_DECREF(line);
53277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size += n;
53377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (maxsize > 0 && size >= maxsize)
53477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            break;
535d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka        output += n;
53677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
53777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return result;
53877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
53977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti  on_error:
54077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_DECREF(result);
54177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return NULL;
54277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
54377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
544f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
545f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.readinto
546dbfdc380df615fe7e85107ff3954b8fff3ce7741Larry Hastings    buffer: Py_buffer(accept={rwbuffer})
547f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
548f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
5496bb91f3b6e51352f91bcf785d3f6fe160ed2cd85Martin PanterRead bytes into buffer.
550f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
551f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturns number of bytes read (0 for EOF), or None if the object
552119e502277d104286620806ef130e3c0d4f439f0Martin Panteris set not to block and has no data to read.
553f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
55477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
55577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
556f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
5576bb91f3b6e51352f91bcf785d3f6fe160ed2cd85Martin Panter/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
55877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
559fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson    Py_ssize_t len, n;
56077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
56187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
56277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
563fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson    /* adjust invalid sizes */
564f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    len = buffer->len;
565fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson    n = self->string_size - self->pos;
566fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson    if (len > n) {
567fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson        len = n;
568fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson        if (len < 0)
569fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson            len = 0;
570fa73555cfc414baff62ed41e0c8c2c85b167495aBenjamin Peterson    }
57177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
572f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
57377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(self->pos + len < PY_SSIZE_T_MAX);
57477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(len >= 0);
57577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    self->pos += len;
57677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
57777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return PyLong_FromSsize_t(len);
57877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
57977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
580f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
581f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.truncate
582f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    size as arg: object = None
583f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
584f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
585f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaTruncate the file to at most size bytes.
586f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
587f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaSize defaults to the current file position, as returned by tell().
588f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaThe current file position is unchanged.  Returns the new size.
589f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
59077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
59177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
592f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
593f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
59477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
59577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t size;
59677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
59787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
598972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    CHECK_EXPORTS(self);
59977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
60077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (PyLong_Check(arg)) {
60177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = PyLong_AsSsize_t(arg);
602a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson        if (size == -1 && PyErr_Occurred())
603a8a93042dcfb6673da1a67726e5028c7582099eaBenjamin Peterson            return NULL;
60477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
60577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else if (arg == Py_None) {
60677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        /* Truncate to current position if no argument is passed. */
60777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        size = self->pos;
60877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
60977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    else {
61077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
61177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                     Py_TYPE(arg)->tp_name);
61277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
61377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
61477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
61577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (size < 0) {
61677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_ValueError,
61777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                     "negative size value %zd", size);
61877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
61977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
62077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
62177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (size < self->string_size) {
62277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        self->string_size = size;
62377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (resize_buffer(self, size) < 0)
62477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            return NULL;
62577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
62677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
62777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return PyLong_FromSsize_t(size);
62877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
62977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
63077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
631680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonbytesio_iternext(bytesio *self)
63277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
63377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t n;
63477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
63587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
63677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
637d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    n = scan_eol(self, -1);
63877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
639d7728cafc585b554d347250afd923740432dac5aSerhiy Storchaka    if (n == 0)
64077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
64177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
64287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return read_bytes(self, n);
64377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
64477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
645f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
646f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.seek
647f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    pos: Py_ssize_t
648f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    whence: int = 0
649f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
650f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
651f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaChange stream position.
652f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
653f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaSeek to byte offset pos relative to position indicated by whence:
654f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka     0  Start of stream (the default).  pos should be >= 0;
655f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka     1  Current position - pos may be negative;
656f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka     2  End of stream - pos usually negative.
657f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturns the new absolute position.
658f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
65977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
66077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
661f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
662f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
66377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
66487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
66577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
666f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    if (pos < 0 && whence == 0) {
66777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_ValueError,
66877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                     "negative seek value %zd", pos);
66977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
67077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
67177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
672f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /* whence = 0: offset relative to beginning of the string.
673f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka       whence = 1: offset relative to current position.
674f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka       whence = 2: offset relative the end of the string. */
675f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    if (whence == 1) {
67677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (pos > PY_SSIZE_T_MAX - self->pos) {
67777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            PyErr_SetString(PyExc_OverflowError,
67877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                            "new position too large");
67977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            return NULL;
68077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        }
68177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        pos += self->pos;
68277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
683f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    else if (whence == 2) {
68477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (pos > PY_SSIZE_T_MAX - self->string_size) {
68577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            PyErr_SetString(PyExc_OverflowError,
68677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti                            "new position too large");
68777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            return NULL;
68877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        }
68977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        pos += self->string_size;
69077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
691f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    else if (whence != 0) {
69277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        PyErr_Format(PyExc_ValueError,
693f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka                     "invalid whence (%i, should be 0, 1 or 2)", whence);
69477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
69577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
69677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
69777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (pos < 0)
69877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        pos = 0;
69977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    self->pos = pos;
70077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
70177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return PyLong_FromSsize_t(self->pos);
70277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
70377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
704f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
705f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.write
706f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    b: object
707f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
708f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
709f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaWrite bytes to file.
710f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
711f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaReturn the number of bytes written.
712f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
71377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
71477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
715f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_write(bytesio *self, PyObject *b)
716f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
71777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
71877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_ssize_t n = 0;
7194fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    Py_buffer buf;
72077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
72187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
722972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    CHECK_EXPORTS(self);
72377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
724f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
72577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
72677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
7274fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    if (buf.len != 0)
7284fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson        n = write_bytes(self, buf.buf, buf.len);
72977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
7304fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    PyBuffer_Release(&buf);
731f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
73277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
73377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
734f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
735f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.writelines
736f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    lines: object
737f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    /
738f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
739f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaWrite lines to the file.
740f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
741f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaNote that newlines are not added.  lines can be any iterable object
742f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakaproducing bytes-like objects. This is equivalent to calling write() for
743f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakaeach element.
744f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
74577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
74677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
747f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_writelines(bytesio *self, PyObject *lines)
748f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
74977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
75077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyObject *it, *item;
75177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyObject *ret;
75277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
75387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_CLOSED(self);
75477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
755f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    it = PyObject_GetIter(lines);
75677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (it == NULL)
75777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
75877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
75977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    while ((item = PyIter_Next(it)) != NULL) {
760f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka        ret = _io_BytesIO_write(self, item);
76177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        Py_DECREF(item);
76277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        if (ret == NULL) {
76377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            Py_DECREF(it);
76477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti            return NULL;
76577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        }
76677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        Py_DECREF(ret);
76777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
76877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_DECREF(it);
76977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
77077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    /* See if PyIter_Next failed */
77177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (PyErr_Occurred())
77277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
77377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
77477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_RETURN_NONE;
77577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
77677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
777f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
778f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.close
779f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
780f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaDisable all I/O operations.
781f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
78277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
78377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
784f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO_close_impl(bytesio *self)
785f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
78677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
787c057c3859c68f2e86c7a492ae8f8b4b3a3b136c8Serhiy Storchaka    CHECK_EXPORTS(self);
78887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    Py_CLEAR(self->buf);
78977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_RETURN_NONE;
79077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
79177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
792cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti/* Pickling support.
793cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
794cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   Note that only pickle protocol 2 and onward are supported since we use
795cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
796cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
797cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   Providing support for protocol < 2 would require the __reduce_ex__ method
798cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   which is notably long-winded when defined properly.
799cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
800cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   For BytesIO, the implementation would similar to one coded for
801cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   object.__reduce_ex__, but slightly less general. To be more specific, we
802cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   could call bytesio_getstate directly and avoid checking for the presence of
803cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   a fallback __reduce__ method. However, we would still need a __newobj__
804cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti   function to use the efficient instance representation of PEP 307.
805cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti */
806cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
807cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalottistatic PyObject *
808cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalottibytesio_getstate(bytesio *self)
809cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti{
810f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
811cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    PyObject *dict;
812cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    PyObject *state;
813cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
814cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (initvalue == NULL)
815cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        return NULL;
816cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (self->dict == NULL) {
817cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        Py_INCREF(Py_None);
818cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        dict = Py_None;
819cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    }
820cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    else {
821cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        dict = PyDict_Copy(self->dict);
82296efdd422cef75f70770107847b1a97e7e524e4cStefan Krah        if (dict == NULL) {
82396efdd422cef75f70770107847b1a97e7e524e4cStefan Krah            Py_DECREF(initvalue);
824cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            return NULL;
82596efdd422cef75f70770107847b1a97e7e524e4cStefan Krah        }
826cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    }
827cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
828cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
829cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    Py_DECREF(initvalue);
830cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    return state;
831cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti}
832cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
833cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalottistatic PyObject *
834cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalottibytesio_setstate(bytesio *self, PyObject *state)
835cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti{
83687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    PyObject *result;
837cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    PyObject *position_obj;
838cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    PyObject *dict;
839cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    Py_ssize_t pos;
840cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
841cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    assert(state != NULL);
842cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
843cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    /* We allow the state tuple to be longer than 3, because we may need
844cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti       someday to extend the object's state without breaking
845cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti       backward-compatibility. */
846cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
847cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        PyErr_Format(PyExc_TypeError,
848cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                     "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
849cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                     Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
850cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        return NULL;
851cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    }
85287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    CHECK_EXPORTS(self);
85387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    /* Reset the object to its default state. This is only needed to handle
85487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka       the case of repeated calls to __setstate__. */
85587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    self->string_size = 0;
85687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    self->pos = 0;
857cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
85887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    /* Set the value of the internal buffer. If state[0] does not support the
85987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka       buffer protocol, bytesio_write will raise the appropriate TypeError. */
860f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
86187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (result == NULL)
862cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        return NULL;
86387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    Py_DECREF(result);
864cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
865cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    /* Set carefully the position value. Alternatively, we could use the seek
866cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti       method instead of modifying self->pos directly to better protect the
867cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti       object internal state against errneous (or malicious) inputs. */
868cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    position_obj = PyTuple_GET_ITEM(state, 1);
869cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (!PyLong_Check(position_obj)) {
870cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        PyErr_Format(PyExc_TypeError,
871cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                     "second item of state must be an integer, not %.200s",
872cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                     Py_TYPE(position_obj)->tp_name);
873cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        return NULL;
874cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    }
875cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    pos = PyLong_AsSsize_t(position_obj);
876cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (pos == -1 && PyErr_Occurred())
877cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        return NULL;
878cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (pos < 0) {
879cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        PyErr_SetString(PyExc_ValueError,
880cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                        "position value cannot be negative");
881cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        return NULL;
882cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    }
883cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    self->pos = pos;
884cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
885cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    /* Set the dictionary of the instance variables. */
886cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    dict = PyTuple_GET_ITEM(state, 2);
887cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    if (dict != Py_None) {
888cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        if (!PyDict_Check(dict)) {
889cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            PyErr_Format(PyExc_TypeError,
890cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                         "third item of state should be a dict, got a %.200s",
891cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                         Py_TYPE(dict)->tp_name);
892cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            return NULL;
893cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        }
894cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        if (self->dict) {
895cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            /* Alternatively, we could replace the internal dictionary
896cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti               completely. However, it seems more practical to just update it. */
897cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            if (PyDict_Update(self->dict, dict) < 0)
898cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti                return NULL;
899cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        }
900cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        else {
901cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            Py_INCREF(dict);
902cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti            self->dict = dict;
903cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti        }
904cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    }
905cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
906cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    Py_RETURN_NONE;
907cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti}
908cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
90977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic void
910680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonbytesio_dealloc(bytesio *self)
91177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
912fc477048e1dee78a1b4376584cac052be1b4752dAlexandre Vassalotti    _PyObject_GC_UNTRACK(self);
913972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    if (self->exports > 0) {
914972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou        PyErr_SetString(PyExc_SystemError,
915972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou                        "deallocated BytesIO object has exported buffers");
916972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou        PyErr_Print();
917972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    }
91887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    Py_CLEAR(self->buf);
919fc477048e1dee78a1b4376584cac052be1b4752dAlexandre Vassalotti    Py_CLEAR(self->dict);
920fc477048e1dee78a1b4376584cac052be1b4752dAlexandre Vassalotti    if (self->weakreflist != NULL)
921fc477048e1dee78a1b4376584cac052be1b4752dAlexandre Vassalotti        PyObject_ClearWeakRefs((PyObject *) self);
92277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    Py_TYPE(self)->tp_free(self);
92377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
92477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
92577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyObject *
92677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottibytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
92777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti{
928680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Peterson    bytesio *self;
92977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
93077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    assert(type != NULL && type->tp_alloc != NULL);
931680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Peterson    self = (bytesio *)type->tp_alloc(type, 0);
93277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (self == NULL)
93377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return NULL;
93477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
935cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    /* tp_alloc initializes all the fields to zero. So we don't have to
936cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti       initialize them here. */
937cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti
93887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    self->buf = PyBytes_FromStringAndSize(NULL, 0);
93977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    if (self->buf == NULL) {
94077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        Py_DECREF(self);
94177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti        return PyErr_NoMemory();
94277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    }
94377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
94477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    return (PyObject *)self;
94577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
94677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
947f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic input]
948f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io.BytesIO.__init__
949f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    initial_bytes as initvalue: object(c_default="NULL") = b''
95077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
951f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy StorchakaBuffered I/O implementation using an in-memory bytes buffer.
952f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka[clinic start generated code]*/
95377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
954f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchakastatic int
955f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
956f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
957f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka{
95887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    /* In case, __init__ is called multiple times. */
95987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    self->string_size = 0;
96087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    self->pos = 0;
96187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
96287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (self->exports > 0) {
96387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        PyErr_SetString(PyExc_BufferError,
96487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka                        "Existing exports of data: object cannot be re-sized");
96587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        return -1;
96687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
96787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (initvalue && initvalue != Py_None) {
96887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        if (PyBytes_CheckExact(initvalue)) {
96987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            Py_INCREF(initvalue);
97048842714b948fa239392ddd7e207151d5fcb8bc7Serhiy Storchaka            Py_XSETREF(self->buf, initvalue);
97187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            self->string_size = PyBytes_GET_SIZE(initvalue);
97287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        }
97387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        else {
97487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            PyObject *res;
975f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka            res = _io_BytesIO_write(self, initvalue);
97687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            if (res == NULL)
97787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka                return -1;
97887d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            Py_DECREF(res);
97987d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            self->pos = 0;
98087d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        }
98187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
98287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka
98387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    return 0;
98477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti}
98577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
9868f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitroustatic PyObject *
9878f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitroubytesio_sizeof(bytesio *self, void *unused)
9888f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou{
9898f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou    Py_ssize_t res;
9908f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou
9915c4064e8bd199d70eefd7ec24766957c22f1b8e8Serhiy Storchaka    res = _PyObject_SIZE(Py_TYPE(self));
99287d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (self->buf && !SHARED_BUF(self))
99387d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        res += _PySys_GetSizeOf(self->buf);
9948f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou    return PyLong_FromSsize_t(res);
9958f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou}
9968f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou
9974fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Petersonstatic int
998680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonbytesio_traverse(bytesio *self, visitproc visit, void *arg)
9994fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson{
10004fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    Py_VISIT(self->dict);
10014fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    return 0;
10024fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson}
10034fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson
10044fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Petersonstatic int
1005680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Petersonbytesio_clear(bytesio *self)
10064fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson{
10074fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    Py_CLEAR(self->dict);
10084fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    return 0;
10094fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson}
10104fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson
10114fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson
1012f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka#include "clinic/bytesio.c.h"
1013f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka
101477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic PyGetSetDef bytesio_getsetlist[] = {
101577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    {"closed",  (getter)bytesio_get_closed, NULL,
101677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti     "True if the file is closed."},
10171fea321502631184f8c3f1580159e3f2bcc5ee4bBenjamin Peterson    {NULL},            /* sentinel */
101877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti};
101977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
102077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalottistatic struct PyMethodDef bytesio_methods[] = {
1021f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_READABLE_METHODDEF
1022f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_SEEKABLE_METHODDEF
1023f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_WRITABLE_METHODDEF
1024f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_CLOSE_METHODDEF
1025f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_FLUSH_METHODDEF
1026f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_ISATTY_METHODDEF
1027f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_TELL_METHODDEF
1028f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_WRITE_METHODDEF
1029f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_WRITELINES_METHODDEF
1030f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_READ1_METHODDEF
1031f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_READINTO_METHODDEF
1032f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_READLINE_METHODDEF
1033f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_READLINES_METHODDEF
1034f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_READ_METHODDEF
1035f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_GETBUFFER_METHODDEF
1036f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_GETVALUE_METHODDEF
1037f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_SEEK_METHODDEF
1038f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _IO_BYTESIO_TRUNCATE_METHODDEF
1039cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
1040cf76e1ac927cdc14ee321a363e161be24bfff059Alexandre Vassalotti    {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
10418f328d0c1d86096b3d4e5f1c1ac497663e197a0dAntoine Pitrou    {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
104277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    {NULL, NULL}        /* sentinel */
104377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti};
104477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti
10454fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin PetersonPyTypeObject PyBytesIO_Type = {
104677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyVarObject_HEAD_INIT(NULL, 0)
10474fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    "_io.BytesIO",                             /*tp_name*/
1048680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Peterson    sizeof(bytesio),                     /*tp_basicsize*/
104977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_itemsize*/
105077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    (destructor)bytesio_dealloc,               /*tp_dealloc*/
105177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_print*/
105277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_getattr*/
105377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_setattr*/
1054e94c679df0b632bc929936ca54f0de006e1a6dc2Mark Dickinson    0,                                         /*tp_reserved*/
105577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_repr*/
105677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_as_number*/
105777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_as_sequence*/
105877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_as_mapping*/
105977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_hash*/
106077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_call*/
106177250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_str*/
106277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_getattro*/
106377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_setattro*/
106477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_as_buffer*/
10654fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
10664fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    Py_TPFLAGS_HAVE_GC,                        /*tp_flags*/
1067f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _io_BytesIO___init____doc__,               /*tp_doc*/
10684fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    (traverseproc)bytesio_traverse,            /*tp_traverse*/
10694fa88fa0ba35e25ad9be66ebbdaba9aca553dc8bBenjamin Peterson    (inquiry)bytesio_clear,                    /*tp_clear*/
107077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_richcompare*/
1071680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Peterson    offsetof(bytesio, weakreflist),      /*tp_weaklistoffset*/
107277250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    PyObject_SelfIter,                         /*tp_iter*/
107377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    (iternextfunc)bytesio_iternext,            /*tp_iternext*/
107477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    bytesio_methods,                           /*tp_methods*/
107577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_members*/
107677250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    bytesio_getsetlist,                        /*tp_getset*/
107777250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_base*/
107877250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_dict*/
107977250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_descr_get*/
108077250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_descr_set*/
1081680bf1afe89c864d6cf04a37ce1b3b2c1d60072fBenjamin Peterson    offsetof(bytesio, dict),             /*tp_dictoffset*/
1082f24131ff3125e59ca779d0e2fcec4967d50f950cSerhiy Storchaka    _io_BytesIO___init__,                      /*tp_init*/
108377250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    0,                                         /*tp_alloc*/
108477250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti    bytesio_new,                               /*tp_new*/
108577250f4df7a73a5c87d12d781a562747a855cd95Alexandre Vassalotti};
1086972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1087972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1088972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou/*
1089972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou * Implementation of the small intermediate object used by getbuffer().
1090972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou * getbuffer() returns a memoryview over this object, which should make it
1091972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou * invisible from Python code.
1092972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou */
1093972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1094972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroustatic int
1095972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroubytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1096972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou{
1097972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    bytesio *b = (bytesio *) obj->source;
1098650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah
1099650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah    if (view == NULL) {
1100650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah        PyErr_SetString(PyExc_BufferError,
1101650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah            "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1102650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah        return -1;
1103650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah    }
110487d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    if (SHARED_BUF(b)) {
110587d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka        if (unshare_buffer(b, b->string_size) < 0)
110687d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka            return -1;
110787d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka    }
1108650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah
1109650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah    /* cannot fail if view != NULL and readonly == 0 */
1110650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah    (void)PyBuffer_FillInfo(view, (PyObject*)obj,
111187d0b45485e1042b0eae8aedf98fa3ebb29846b8Serhiy Storchaka                            PyBytes_AS_STRING(b->buf), b->string_size,
1112972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou                            0, flags);
1113650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah    b->exports++;
1114650c1e818d7bbb5d51501051fca773b3b8ea6bf3Stefan Krah    return 0;
1115972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou}
1116972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1117972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroustatic void
1118972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroubytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1119972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou{
1120972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    bytesio *b = (bytesio *) obj->source;
1121972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    b->exports--;
1122972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou}
1123972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1124972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroustatic int
1125972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroubytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1126972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou{
1127972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_VISIT(self->source);
1128972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    return 0;
1129972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou}
1130972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1131972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroustatic void
1132972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroubytesiobuf_dealloc(bytesiobuf *self)
1133972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou{
1134972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_CLEAR(self->source);
1135972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_TYPE(self)->tp_free(self);
1136972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou}
1137972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1138972ee13e037432497fa003d4a786b2342a38db94Antoine Pitroustatic PyBufferProcs bytesiobuf_as_buffer = {
1139972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    (getbufferproc) bytesiobuf_getbuffer,
1140972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    (releasebufferproc) bytesiobuf_releasebuffer,
1141972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou};
1142972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou
1143972ee13e037432497fa003d4a786b2342a38db94Antoine PitrouPyTypeObject _PyBytesIOBuffer_Type = {
1144972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    PyVarObject_HEAD_INIT(NULL, 0)
1145972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    "_io._BytesIOBuffer",                      /*tp_name*/
1146972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    sizeof(bytesiobuf),                        /*tp_basicsize*/
1147972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_itemsize*/
1148972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    (destructor)bytesiobuf_dealloc,            /*tp_dealloc*/
1149972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_print*/
1150972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_getattr*/
1151972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_setattr*/
1152972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_reserved*/
1153972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_repr*/
1154972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_as_number*/
1155972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_as_sequence*/
1156972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_as_mapping*/
1157972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_hash*/
1158972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_call*/
1159972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_str*/
1160972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_getattro*/
1161972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_setattro*/
1162972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    &bytesiobuf_as_buffer,                     /*tp_as_buffer*/
1163972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
1164972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_doc*/
1165972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    (traverseproc)bytesiobuf_traverse,         /*tp_traverse*/
1166972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_clear*/
1167972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_richcompare*/
1168972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_weaklistoffset*/
1169972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_iter*/
1170972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_iternext*/
1171972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_methods*/
1172972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_members*/
1173972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_getset*/
1174972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_base*/
1175972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_dict*/
1176972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_descr_get*/
1177972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_descr_set*/
1178972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_dictoffset*/
1179972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_init*/
1180972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_alloc*/
1181972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou    0,                                         /*tp_new*/
1182972ee13e037432497fa003d4a786b2342a38db94Antoine Pitrou};
1183