blob: 59b917d0bdaaa16469c3aa1c3cc77bfe9fdb911c [file] [log] [blame]
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001#include "Python.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002#include "structmember.h" /* for offsetof() */
3#include "_iomodule.h"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00004
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03005/*[clinic input]
6module _io
7class _io.BytesIO "bytesio *" "&PyBytesIO_Type"
8[clinic start generated code]*/
9/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
10
orenmn74002542017-03-11 00:52:01 +020011/*[python input]
12class io_ssize_t_converter(CConverter):
13 type = 'Py_ssize_t'
14 converter = '_PyIO_ConvertSsize_t'
15[python start generated code]*/
16/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
17
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000018typedef struct {
19 PyObject_HEAD
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020020 PyObject *buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000021 Py_ssize_t pos;
22 Py_ssize_t string_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000023 PyObject *dict;
24 PyObject *weakreflist;
Antoine Pitrou972ee132010-09-06 18:48:21 +000025 Py_ssize_t exports;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000026} bytesio;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000027
Antoine Pitrou972ee132010-09-06 18:48:21 +000028typedef struct {
29 PyObject_HEAD
30 bytesio *source;
31} bytesiobuf;
32
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020033/* The bytesio object can be in three states:
34 * Py_REFCNT(buf) == 1, exports == 0.
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020035 * Py_REFCNT(buf) > 1. exports == 0,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020036 first modification or export causes the internal buffer copying.
37 * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden.
38*/
Antoine Pitrou972ee132010-09-06 18:48:21 +000039
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020040#define CHECK_CLOSED(self) \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000041 if ((self)->buf == NULL) { \
42 PyErr_SetString(PyExc_ValueError, \
43 "I/O operation on closed file."); \
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020044 return NULL; \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000045 }
46
Antoine Pitrou972ee132010-09-06 18:48:21 +000047#define CHECK_EXPORTS(self) \
48 if ((self)->exports > 0) { \
49 PyErr_SetString(PyExc_BufferError, \
50 "Existing exports of data: object cannot be re-sized"); \
51 return NULL; \
52 }
53
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020054#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
Antoine Pitroucc66a732014-07-29 19:41:11 -040055
Antoine Pitrou972ee132010-09-06 18:48:21 +000056
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000057/* Internal routine to get a line from the buffer of a BytesIO
58 object. Returns the length between the current position to the
59 next newline character. */
60static Py_ssize_t
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030061scan_eol(bytesio *self, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000062{
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030063 const char *start, *n;
64 Py_ssize_t maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000065
66 assert(self->buf != NULL);
Serhiy Storchaka4e63f7a2015-09-04 07:48:19 +030067 assert(self->pos >= 0);
68
69 if (self->pos >= self->string_size)
70 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000071
72 /* Move to the end of the line, up to the end of the string, s. */
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030073 maxlen = self->string_size - self->pos;
74 if (len < 0 || len > maxlen)
75 len = maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000076
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030077 if (len) {
Serhiy Storchaka4e63f7a2015-09-04 07:48:19 +030078 start = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030079 n = memchr(start, '\n', len);
80 if (n)
81 /* Get the length from the current position to the end of
82 the line. */
83 len = n - start + 1;
84 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000085 assert(len >= 0);
86 assert(self->pos < PY_SSIZE_T_MAX - len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000087
88 return len;
89}
90
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020091/* Internal routine for detaching the shared buffer of BytesIO objects.
92 The caller should ensure that the 'size' argument is non-negative and
93 not lesser than self->string_size. Returns 0 on success, -1 otherwise. */
94static int
95unshare_buffer(bytesio *self, size_t size)
96{
Serhiy Storchaka1ed017a2015-12-27 15:51:32 +020097 PyObject *new_buf;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020098 assert(SHARED_BUF(self));
99 assert(self->exports == 0);
100 assert(size >= (size_t)self->string_size);
101 new_buf = PyBytes_FromStringAndSize(NULL, size);
102 if (new_buf == NULL)
103 return -1;
104 memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
105 self->string_size);
Serhiy Storchakaf01e4082016-04-10 18:12:01 +0300106 Py_SETREF(self->buf, new_buf);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200107 return 0;
108}
109
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000110/* Internal routine for changing the size of the buffer of BytesIO objects.
111 The caller should ensure that the 'size' argument is non-negative. Returns
112 0 on success, -1 otherwise. */
113static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000114resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000115{
116 /* Here, unsigned types are used to avoid dealing with signed integer
117 overflow, which is undefined in C. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200118 size_t alloc = PyBytes_GET_SIZE(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000119
120 assert(self->buf != NULL);
121
122 /* For simplicity, stay in the range of the signed type. Anyway, Python
123 doesn't allow strings to be longer than this. */
124 if (size > PY_SSIZE_T_MAX)
125 goto overflow;
126
127 if (size < alloc / 2) {
128 /* Major downsize; resize down to exact size. */
129 alloc = size + 1;
130 }
131 else if (size < alloc) {
132 /* Within allocated size; quick exit */
133 return 0;
134 }
135 else if (size <= alloc * 1.125) {
136 /* Moderate upsize; overallocate similar to list_resize() */
137 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
138 }
139 else {
140 /* Major upsize; resize up to exact size */
141 alloc = size + 1;
142 }
143
144 if (alloc > ((size_t)-1) / sizeof(char))
145 goto overflow;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200146
147 if (SHARED_BUF(self)) {
148 if (unshare_buffer(self, alloc) < 0)
149 return -1;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000150 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200151 else {
152 if (_PyBytes_Resize(&self->buf, alloc) < 0)
153 return -1;
154 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000155
156 return 0;
157
158 overflow:
159 PyErr_SetString(PyExc_OverflowError,
160 "new buffer size too large");
161 return -1;
162}
163
164/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200165 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000166static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000168{
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200169 size_t endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000170 assert(self->buf != NULL);
171 assert(self->pos >= 0);
172 assert(len >= 0);
173
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200174 endpos = (size_t)self->pos + len;
175 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
176 if (resize_buffer(self, endpos) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000177 return -1;
178 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200179 else if (SHARED_BUF(self)) {
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200180 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200181 return -1;
182 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000183
184 if (self->pos > self->string_size) {
185 /* In case of overseek, pad with null bytes the buffer region between
186 the end of stream and the current position.
187
188 0 lo string_size hi
189 | |<---used--->|<----------available----------->|
190 | | <--to pad-->|<---to write---> |
191 0 buf position
192 */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200193 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000194 (self->pos - self->string_size) * sizeof(char));
195 }
196
197 /* Copy the data to the internal buffer, overwriting some of the existing
198 data if self->pos < self->string_size. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200199 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200200 self->pos = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000201
202 /* Set the new length of the internal string if it has changed. */
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200203 if ((size_t)self->string_size < endpos) {
204 self->string_size = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000205 }
206
207 return len;
208}
209
210static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000211bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000212{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000214 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000215 }
216 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000217 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000218 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000219}
220
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300221/*[clinic input]
222_io.BytesIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200223
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300224Returns True if the IO object can be read.
225[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200226
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000227static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300228_io_BytesIO_readable_impl(bytesio *self)
229/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000230{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200231 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000232 Py_RETURN_TRUE;
233}
234
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300235/*[clinic input]
236_io.BytesIO.writable
237
238Returns True if the IO object can be written.
239[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000240
241static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300242_io_BytesIO_writable_impl(bytesio *self)
243/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
244{
245 CHECK_CLOSED(self);
246 Py_RETURN_TRUE;
247}
248
249/*[clinic input]
250_io.BytesIO.seekable
251
252Returns True if the IO object can be seeked.
253[clinic start generated code]*/
254
255static PyObject *
256_io_BytesIO_seekable_impl(bytesio *self)
257/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
258{
259 CHECK_CLOSED(self);
260 Py_RETURN_TRUE;
261}
262
263/*[clinic input]
264_io.BytesIO.flush
265
266Does nothing.
267[clinic start generated code]*/
268
269static PyObject *
270_io_BytesIO_flush_impl(bytesio *self)
271/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000272{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200273 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000274 Py_RETURN_NONE;
275}
276
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300277/*[clinic input]
278_io.BytesIO.getbuffer
279
280Get a read-write view over the contents of the BytesIO object.
281[clinic start generated code]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000282
283static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300284_io_BytesIO_getbuffer_impl(bytesio *self)
285/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000286{
287 PyTypeObject *type = &_PyBytesIOBuffer_Type;
288 bytesiobuf *buf;
289 PyObject *view;
290
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200291 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000292
293 buf = (bytesiobuf *) type->tp_alloc(type, 0);
294 if (buf == NULL)
295 return NULL;
296 Py_INCREF(self);
297 buf->source = self;
298 view = PyMemoryView_FromObject((PyObject *) buf);
299 Py_DECREF(buf);
300 return view;
301}
302
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300303/*[clinic input]
304_io.BytesIO.getvalue
305
306Retrieve the entire contents of the BytesIO object.
307[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000308
309static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300310_io_BytesIO_getvalue_impl(bytesio *self)
311/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000312{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200313 CHECK_CLOSED(self);
314 if (self->string_size <= 1 || self->exports > 0)
315 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
316 self->string_size);
317
318 if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
319 if (SHARED_BUF(self)) {
320 if (unshare_buffer(self, self->string_size) < 0)
321 return NULL;
322 }
323 else {
324 if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
325 return NULL;
326 }
327 }
328 Py_INCREF(self->buf);
329 return self->buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000330}
331
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300332/*[clinic input]
333_io.BytesIO.isatty
334
335Always returns False.
336
337BytesIO objects are not connected to a TTY-like device.
338[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000339
340static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300341_io_BytesIO_isatty_impl(bytesio *self)
342/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000343{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200344 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000345 Py_RETURN_FALSE;
346}
347
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300348/*[clinic input]
349_io.BytesIO.tell
350
351Current file position, an integer.
352[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000353
354static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300355_io_BytesIO_tell_impl(bytesio *self)
356/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000357{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200358 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000359 return PyLong_FromSsize_t(self->pos);
360}
361
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200362static PyObject *
363read_bytes(bytesio *self, Py_ssize_t size)
364{
365 char *output;
366
367 assert(self->buf != NULL);
Serhiy Storchakab9765ee2015-02-03 14:57:49 +0200368 assert(size <= self->string_size);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200369 if (size > 1 &&
370 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
371 self->exports == 0) {
372 self->pos += size;
373 Py_INCREF(self->buf);
374 return self->buf;
375 }
376
377 output = PyBytes_AS_STRING(self->buf) + self->pos;
378 self->pos += size;
379 return PyBytes_FromStringAndSize(output, size);
380}
381
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300382/*[clinic input]
383_io.BytesIO.read
orenmn74002542017-03-11 00:52:01 +0200384 size: io_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300385 /
386
387Read at most size bytes, returned as a bytes object.
388
389If the size argument is negative, read until EOF is reached.
390Return an empty bytes object at EOF.
391[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000392
393static PyObject *
orenmn74002542017-03-11 00:52:01 +0200394_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)
395/*[clinic end generated code: output=9cc025f21c75bdd2 input=c81ec53b8f2cc3cf]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000396{
orenmn74002542017-03-11 00:52:01 +0200397 Py_ssize_t n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000398
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200399 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000400
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000401 /* adjust invalid sizes */
402 n = self->string_size - self->pos;
403 if (size < 0 || size > n) {
404 size = n;
405 if (size < 0)
406 size = 0;
407 }
408
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200409 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000410}
411
412
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300413/*[clinic input]
414_io.BytesIO.read1
orenmn74002542017-03-11 00:52:01 +0200415 size: io_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300416 /
417
418Read at most size bytes, returned as a bytes object.
419
420If the size argument is negative or omitted, read until EOF is reached.
421Return an empty bytes object at EOF.
422[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000423
424static PyObject *
orenmn74002542017-03-11 00:52:01 +0200425_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
426/*[clinic end generated code: output=d0f843285aa95f1c input=67cf18b142111664]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000427{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300428 return _io_BytesIO_read_impl(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000429}
430
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300431/*[clinic input]
432_io.BytesIO.readline
orenmn74002542017-03-11 00:52:01 +0200433 size: io_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300434 /
435
436Next line from the file, as a bytes object.
437
438Retain newline. A non-negative size argument limits the maximum
439number of bytes to return (an incomplete line may be returned then).
440Return an empty bytes object at EOF.
441[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000442
443static PyObject *
orenmn74002542017-03-11 00:52:01 +0200444_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
445/*[clinic end generated code: output=4bff3c251df8ffcd input=7c95bd3f9e9d1646]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000446{
orenmn74002542017-03-11 00:52:01 +0200447 Py_ssize_t n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000448
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200449 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000450
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300451 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000452
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200453 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000454}
455
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300456/*[clinic input]
457_io.BytesIO.readlines
458 size as arg: object = None
459 /
460
461List of bytes objects, each a line from the file.
462
463Call readline() repeatedly and return a list of the lines so read.
464The optional size argument, if given, is an approximate bound on the
465total number of bytes in the lines returned.
466[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000467
468static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300469_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
470/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000471{
472 Py_ssize_t maxsize, size, n;
473 PyObject *result, *line;
474 char *output;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000475
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200476 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000477
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000478 if (PyLong_Check(arg)) {
479 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000480 if (maxsize == -1 && PyErr_Occurred())
481 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000482 }
483 else if (arg == Py_None) {
484 /* No size limit, by default. */
485 maxsize = -1;
486 }
487 else {
488 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
489 Py_TYPE(arg)->tp_name);
490 return NULL;
491 }
492
493 size = 0;
494 result = PyList_New(0);
495 if (!result)
496 return NULL;
497
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200498 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300499 while ((n = scan_eol(self, -1)) != 0) {
500 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000501 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000502 if (!line)
503 goto on_error;
504 if (PyList_Append(result, line) == -1) {
505 Py_DECREF(line);
506 goto on_error;
507 }
508 Py_DECREF(line);
509 size += n;
510 if (maxsize > 0 && size >= maxsize)
511 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300512 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000513 }
514 return result;
515
516 on_error:
517 Py_DECREF(result);
518 return NULL;
519}
520
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300521/*[clinic input]
522_io.BytesIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700523 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300524 /
525
Martin Panter6bb91f32016-05-28 00:41:57 +0000526Read bytes into buffer.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300527
528Returns number of bytes read (0 for EOF), or None if the object
Martin Panter119e5022016-04-16 09:28:57 +0000529is set not to block and has no data to read.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300530[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000531
532static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300533_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
Martin Panter6bb91f32016-05-28 00:41:57 +0000534/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000535{
Benjamin Petersonfa735552010-11-20 17:24:04 +0000536 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000537
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200538 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000539
Benjamin Petersonfa735552010-11-20 17:24:04 +0000540 /* adjust invalid sizes */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300541 len = buffer->len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000542 n = self->string_size - self->pos;
543 if (len > n) {
544 len = n;
545 if (len < 0)
546 len = 0;
547 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000548
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300549 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000550 assert(self->pos + len < PY_SSIZE_T_MAX);
551 assert(len >= 0);
552 self->pos += len;
553
554 return PyLong_FromSsize_t(len);
555}
556
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300557/*[clinic input]
558_io.BytesIO.truncate
559 size as arg: object = None
560 /
561
562Truncate the file to at most size bytes.
563
564Size defaults to the current file position, as returned by tell().
565The current file position is unchanged. Returns the new size.
566[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000567
568static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300569_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
570/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000571{
572 Py_ssize_t size;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000573
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200574 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000575 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000576
orenmn74002542017-03-11 00:52:01 +0200577 if (arg == Py_None) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000578 /* Truncate to current position if no argument is passed. */
579 size = self->pos;
580 }
Oren Milman00425102017-03-13 00:37:05 +0200581 else if (PyIndex_Check(arg)) {
orenmn74002542017-03-11 00:52:01 +0200582 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
583 if (size == -1 && PyErr_Occurred()) {
584 return NULL;
585 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000586 }
Oren Milman00425102017-03-13 00:37:05 +0200587 else {
588 PyErr_Format(PyExc_TypeError,
589 "argument should be integer or None, not '%.200s'",
590 Py_TYPE(arg)->tp_name);
591 return NULL;
592 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000593
594 if (size < 0) {
595 PyErr_Format(PyExc_ValueError,
596 "negative size value %zd", size);
597 return NULL;
598 }
599
600 if (size < self->string_size) {
601 self->string_size = size;
602 if (resize_buffer(self, size) < 0)
603 return NULL;
604 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000605
606 return PyLong_FromSsize_t(size);
607}
608
609static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000610bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000611{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000612 Py_ssize_t n;
613
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200614 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000615
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300616 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000617
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300618 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000619 return NULL;
620
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200621 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000622}
623
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300624/*[clinic input]
625_io.BytesIO.seek
626 pos: Py_ssize_t
627 whence: int = 0
628 /
629
630Change stream position.
631
632Seek to byte offset pos relative to position indicated by whence:
633 0 Start of stream (the default). pos should be >= 0;
634 1 Current position - pos may be negative;
635 2 End of stream - pos usually negative.
636Returns the new absolute position.
637[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000638
639static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300640_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
641/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000642{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200643 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000644
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300645 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000646 PyErr_Format(PyExc_ValueError,
647 "negative seek value %zd", pos);
648 return NULL;
649 }
650
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300651 /* whence = 0: offset relative to beginning of the string.
652 whence = 1: offset relative to current position.
653 whence = 2: offset relative the end of the string. */
654 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000655 if (pos > PY_SSIZE_T_MAX - self->pos) {
656 PyErr_SetString(PyExc_OverflowError,
657 "new position too large");
658 return NULL;
659 }
660 pos += self->pos;
661 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300662 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000663 if (pos > PY_SSIZE_T_MAX - self->string_size) {
664 PyErr_SetString(PyExc_OverflowError,
665 "new position too large");
666 return NULL;
667 }
668 pos += self->string_size;
669 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300670 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000671 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300672 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000673 return NULL;
674 }
675
676 if (pos < 0)
677 pos = 0;
678 self->pos = pos;
679
680 return PyLong_FromSsize_t(self->pos);
681}
682
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300683/*[clinic input]
684_io.BytesIO.write
685 b: object
686 /
687
688Write bytes to file.
689
690Return the number of bytes written.
691[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000692
693static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300694_io_BytesIO_write(bytesio *self, PyObject *b)
695/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000696{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000697 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000699
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200700 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000701 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000702
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300703 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000704 return NULL;
705
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000706 if (buf.len != 0)
707 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000708
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300710 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000711}
712
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300713/*[clinic input]
714_io.BytesIO.writelines
715 lines: object
716 /
717
718Write lines to the file.
719
720Note that newlines are not added. lines can be any iterable object
721producing bytes-like objects. This is equivalent to calling write() for
722each element.
723[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000724
725static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300726_io_BytesIO_writelines(bytesio *self, PyObject *lines)
727/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000728{
729 PyObject *it, *item;
730 PyObject *ret;
731
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200732 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000733
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300734 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000735 if (it == NULL)
736 return NULL;
737
738 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300739 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000740 Py_DECREF(item);
741 if (ret == NULL) {
742 Py_DECREF(it);
743 return NULL;
744 }
745 Py_DECREF(ret);
746 }
747 Py_DECREF(it);
748
749 /* See if PyIter_Next failed */
750 if (PyErr_Occurred())
751 return NULL;
752
753 Py_RETURN_NONE;
754}
755
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300756/*[clinic input]
757_io.BytesIO.close
758
759Disable all I/O operations.
760[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000761
762static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300763_io_BytesIO_close_impl(bytesio *self)
764/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000765{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200766 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200767 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000768 Py_RETURN_NONE;
769}
770
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000771/* Pickling support.
772
773 Note that only pickle protocol 2 and onward are supported since we use
774 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
775
776 Providing support for protocol < 2 would require the __reduce_ex__ method
777 which is notably long-winded when defined properly.
778
779 For BytesIO, the implementation would similar to one coded for
780 object.__reduce_ex__, but slightly less general. To be more specific, we
781 could call bytesio_getstate directly and avoid checking for the presence of
782 a fallback __reduce__ method. However, we would still need a __newobj__
783 function to use the efficient instance representation of PEP 307.
784 */
785
786static PyObject *
787bytesio_getstate(bytesio *self)
788{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300789 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000790 PyObject *dict;
791 PyObject *state;
792
793 if (initvalue == NULL)
794 return NULL;
795 if (self->dict == NULL) {
796 Py_INCREF(Py_None);
797 dict = Py_None;
798 }
799 else {
800 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200801 if (dict == NULL) {
802 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000803 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200804 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000805 }
806
807 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
808 Py_DECREF(initvalue);
809 return state;
810}
811
812static PyObject *
813bytesio_setstate(bytesio *self, PyObject *state)
814{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200815 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000816 PyObject *position_obj;
817 PyObject *dict;
818 Py_ssize_t pos;
819
820 assert(state != NULL);
821
822 /* We allow the state tuple to be longer than 3, because we may need
823 someday to extend the object's state without breaking
824 backward-compatibility. */
825 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
826 PyErr_Format(PyExc_TypeError,
827 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
828 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
829 return NULL;
830 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200831 CHECK_EXPORTS(self);
832 /* Reset the object to its default state. This is only needed to handle
833 the case of repeated calls to __setstate__. */
834 self->string_size = 0;
835 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000836
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200837 /* Set the value of the internal buffer. If state[0] does not support the
838 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300839 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200840 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000841 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200842 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000843
844 /* Set carefully the position value. Alternatively, we could use the seek
845 method instead of modifying self->pos directly to better protect the
846 object internal state against errneous (or malicious) inputs. */
847 position_obj = PyTuple_GET_ITEM(state, 1);
848 if (!PyLong_Check(position_obj)) {
849 PyErr_Format(PyExc_TypeError,
850 "second item of state must be an integer, not %.200s",
851 Py_TYPE(position_obj)->tp_name);
852 return NULL;
853 }
854 pos = PyLong_AsSsize_t(position_obj);
855 if (pos == -1 && PyErr_Occurred())
856 return NULL;
857 if (pos < 0) {
858 PyErr_SetString(PyExc_ValueError,
859 "position value cannot be negative");
860 return NULL;
861 }
862 self->pos = pos;
863
864 /* Set the dictionary of the instance variables. */
865 dict = PyTuple_GET_ITEM(state, 2);
866 if (dict != Py_None) {
867 if (!PyDict_Check(dict)) {
868 PyErr_Format(PyExc_TypeError,
869 "third item of state should be a dict, got a %.200s",
870 Py_TYPE(dict)->tp_name);
871 return NULL;
872 }
873 if (self->dict) {
874 /* Alternatively, we could replace the internal dictionary
875 completely. However, it seems more practical to just update it. */
876 if (PyDict_Update(self->dict, dict) < 0)
877 return NULL;
878 }
879 else {
880 Py_INCREF(dict);
881 self->dict = dict;
882 }
883 }
884
885 Py_RETURN_NONE;
886}
887
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000888static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000889bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000890{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000891 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000892 if (self->exports > 0) {
893 PyErr_SetString(PyExc_SystemError,
894 "deallocated BytesIO object has exported buffers");
895 PyErr_Print();
896 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200897 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000898 Py_CLEAR(self->dict);
899 if (self->weakreflist != NULL)
900 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000901 Py_TYPE(self)->tp_free(self);
902}
903
904static PyObject *
905bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
906{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000907 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000908
909 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000910 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000911 if (self == NULL)
912 return NULL;
913
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000914 /* tp_alloc initializes all the fields to zero. So we don't have to
915 initialize them here. */
916
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200917 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000918 if (self->buf == NULL) {
919 Py_DECREF(self);
920 return PyErr_NoMemory();
921 }
922
923 return (PyObject *)self;
924}
925
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300926/*[clinic input]
927_io.BytesIO.__init__
928 initial_bytes as initvalue: object(c_default="NULL") = b''
929
930Buffered I/O implementation using an in-memory bytes buffer.
931[clinic start generated code]*/
932
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000933static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300934_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
935/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000936{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200937 /* In case, __init__ is called multiple times. */
938 self->string_size = 0;
939 self->pos = 0;
940
941 if (self->exports > 0) {
942 PyErr_SetString(PyExc_BufferError,
943 "Existing exports of data: object cannot be re-sized");
944 return -1;
945 }
946 if (initvalue && initvalue != Py_None) {
947 if (PyBytes_CheckExact(initvalue)) {
948 Py_INCREF(initvalue);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300949 Py_XSETREF(self->buf, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200950 self->string_size = PyBytes_GET_SIZE(initvalue);
951 }
952 else {
953 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300954 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200955 if (res == NULL)
956 return -1;
957 Py_DECREF(res);
958 self->pos = 0;
959 }
960 }
961
962 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000963}
964
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200965static PyObject *
966bytesio_sizeof(bytesio *self, void *unused)
967{
968 Py_ssize_t res;
969
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200970 res = _PyObject_SIZE(Py_TYPE(self));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200971 if (self->buf && !SHARED_BUF(self))
972 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200973 return PyLong_FromSsize_t(res);
974}
975
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000976static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000977bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000978{
979 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 return 0;
981}
982
983static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000984bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985{
986 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987 return 0;
988}
989
990
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991#include "clinic/bytesio.c.h"
992
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000993static PyGetSetDef bytesio_getsetlist[] = {
994 {"closed", (getter)bytesio_get_closed, NULL,
995 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000996 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000997};
998
999static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001000 _IO_BYTESIO_READABLE_METHODDEF
1001 _IO_BYTESIO_SEEKABLE_METHODDEF
1002 _IO_BYTESIO_WRITABLE_METHODDEF
1003 _IO_BYTESIO_CLOSE_METHODDEF
1004 _IO_BYTESIO_FLUSH_METHODDEF
1005 _IO_BYTESIO_ISATTY_METHODDEF
1006 _IO_BYTESIO_TELL_METHODDEF
1007 _IO_BYTESIO_WRITE_METHODDEF
1008 _IO_BYTESIO_WRITELINES_METHODDEF
1009 _IO_BYTESIO_READ1_METHODDEF
1010 _IO_BYTESIO_READINTO_METHODDEF
1011 _IO_BYTESIO_READLINE_METHODDEF
1012 _IO_BYTESIO_READLINES_METHODDEF
1013 _IO_BYTESIO_READ_METHODDEF
1014 _IO_BYTESIO_GETBUFFER_METHODDEF
1015 _IO_BYTESIO_GETVALUE_METHODDEF
1016 _IO_BYTESIO_SEEK_METHODDEF
1017 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001018 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
1019 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +02001020 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001021 {NULL, NULL} /* sentinel */
1022};
1023
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001024PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001025 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001026 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001027 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001028 0, /*tp_itemsize*/
1029 (destructor)bytesio_dealloc, /*tp_dealloc*/
1030 0, /*tp_print*/
1031 0, /*tp_getattr*/
1032 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001033 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001034 0, /*tp_repr*/
1035 0, /*tp_as_number*/
1036 0, /*tp_as_sequence*/
1037 0, /*tp_as_mapping*/
1038 0, /*tp_hash*/
1039 0, /*tp_call*/
1040 0, /*tp_str*/
1041 0, /*tp_getattro*/
1042 0, /*tp_setattro*/
1043 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1045 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001046 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 (traverseproc)bytesio_traverse, /*tp_traverse*/
1048 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001049 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001050 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001051 PyObject_SelfIter, /*tp_iter*/
1052 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1053 bytesio_methods, /*tp_methods*/
1054 0, /*tp_members*/
1055 bytesio_getsetlist, /*tp_getset*/
1056 0, /*tp_base*/
1057 0, /*tp_dict*/
1058 0, /*tp_descr_get*/
1059 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001060 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001061 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001062 0, /*tp_alloc*/
1063 bytesio_new, /*tp_new*/
1064};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001065
1066
1067/*
1068 * Implementation of the small intermediate object used by getbuffer().
1069 * getbuffer() returns a memoryview over this object, which should make it
1070 * invisible from Python code.
1071 */
1072
1073static int
1074bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1075{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001076 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001077
1078 if (view == NULL) {
1079 PyErr_SetString(PyExc_BufferError,
1080 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1081 return -1;
1082 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001083 if (SHARED_BUF(b)) {
1084 if (unshare_buffer(b, b->string_size) < 0)
1085 return -1;
1086 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001087
1088 /* cannot fail if view != NULL and readonly == 0 */
1089 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001090 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001091 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001092 b->exports++;
1093 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001094}
1095
1096static void
1097bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1098{
1099 bytesio *b = (bytesio *) obj->source;
1100 b->exports--;
1101}
1102
1103static int
1104bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1105{
1106 Py_VISIT(self->source);
1107 return 0;
1108}
1109
1110static void
1111bytesiobuf_dealloc(bytesiobuf *self)
1112{
1113 Py_CLEAR(self->source);
1114 Py_TYPE(self)->tp_free(self);
1115}
1116
1117static PyBufferProcs bytesiobuf_as_buffer = {
1118 (getbufferproc) bytesiobuf_getbuffer,
1119 (releasebufferproc) bytesiobuf_releasebuffer,
1120};
1121
1122PyTypeObject _PyBytesIOBuffer_Type = {
1123 PyVarObject_HEAD_INIT(NULL, 0)
1124 "_io._BytesIOBuffer", /*tp_name*/
1125 sizeof(bytesiobuf), /*tp_basicsize*/
1126 0, /*tp_itemsize*/
1127 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1128 0, /*tp_print*/
1129 0, /*tp_getattr*/
1130 0, /*tp_setattr*/
1131 0, /*tp_reserved*/
1132 0, /*tp_repr*/
1133 0, /*tp_as_number*/
1134 0, /*tp_as_sequence*/
1135 0, /*tp_as_mapping*/
1136 0, /*tp_hash*/
1137 0, /*tp_call*/
1138 0, /*tp_str*/
1139 0, /*tp_getattro*/
1140 0, /*tp_setattro*/
1141 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1142 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1143 0, /*tp_doc*/
1144 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1145 0, /*tp_clear*/
1146 0, /*tp_richcompare*/
1147 0, /*tp_weaklistoffset*/
1148 0, /*tp_iter*/
1149 0, /*tp_iternext*/
1150 0, /*tp_methods*/
1151 0, /*tp_members*/
1152 0, /*tp_getset*/
1153 0, /*tp_base*/
1154 0, /*tp_dict*/
1155 0, /*tp_descr_get*/
1156 0, /*tp_descr_set*/
1157 0, /*tp_dictoffset*/
1158 0, /*tp_init*/
1159 0, /*tp_alloc*/
1160 0, /*tp_new*/
1161};