blob: 0a0e5e72d7e4d92db226e5a0ad4210e00a51b17a [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 }
581 else {
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 }
587
588 if (size < 0) {
589 PyErr_Format(PyExc_ValueError,
590 "negative size value %zd", size);
591 return NULL;
592 }
593
594 if (size < self->string_size) {
595 self->string_size = size;
596 if (resize_buffer(self, size) < 0)
597 return NULL;
598 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000599
600 return PyLong_FromSsize_t(size);
601}
602
603static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000604bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000605{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000606 Py_ssize_t n;
607
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200608 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000609
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300610 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000611
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300612 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000613 return NULL;
614
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200615 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000616}
617
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300618/*[clinic input]
619_io.BytesIO.seek
620 pos: Py_ssize_t
621 whence: int = 0
622 /
623
624Change stream position.
625
626Seek to byte offset pos relative to position indicated by whence:
627 0 Start of stream (the default). pos should be >= 0;
628 1 Current position - pos may be negative;
629 2 End of stream - pos usually negative.
630Returns the new absolute position.
631[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000632
633static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300634_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
635/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000636{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200637 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000638
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300639 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000640 PyErr_Format(PyExc_ValueError,
641 "negative seek value %zd", pos);
642 return NULL;
643 }
644
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300645 /* whence = 0: offset relative to beginning of the string.
646 whence = 1: offset relative to current position.
647 whence = 2: offset relative the end of the string. */
648 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000649 if (pos > PY_SSIZE_T_MAX - self->pos) {
650 PyErr_SetString(PyExc_OverflowError,
651 "new position too large");
652 return NULL;
653 }
654 pos += self->pos;
655 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300656 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000657 if (pos > PY_SSIZE_T_MAX - self->string_size) {
658 PyErr_SetString(PyExc_OverflowError,
659 "new position too large");
660 return NULL;
661 }
662 pos += self->string_size;
663 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300664 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000665 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300666 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000667 return NULL;
668 }
669
670 if (pos < 0)
671 pos = 0;
672 self->pos = pos;
673
674 return PyLong_FromSsize_t(self->pos);
675}
676
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300677/*[clinic input]
678_io.BytesIO.write
679 b: object
680 /
681
682Write bytes to file.
683
684Return the number of bytes written.
685[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000686
687static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300688_io_BytesIO_write(bytesio *self, PyObject *b)
689/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000690{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000691 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000693
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200694 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000695 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000696
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300697 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000698 return NULL;
699
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700 if (buf.len != 0)
701 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000702
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000703 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300704 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000705}
706
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300707/*[clinic input]
708_io.BytesIO.writelines
709 lines: object
710 /
711
712Write lines to the file.
713
714Note that newlines are not added. lines can be any iterable object
715producing bytes-like objects. This is equivalent to calling write() for
716each element.
717[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000718
719static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300720_io_BytesIO_writelines(bytesio *self, PyObject *lines)
721/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000722{
723 PyObject *it, *item;
724 PyObject *ret;
725
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200726 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000727
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300728 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000729 if (it == NULL)
730 return NULL;
731
732 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300733 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000734 Py_DECREF(item);
735 if (ret == NULL) {
736 Py_DECREF(it);
737 return NULL;
738 }
739 Py_DECREF(ret);
740 }
741 Py_DECREF(it);
742
743 /* See if PyIter_Next failed */
744 if (PyErr_Occurred())
745 return NULL;
746
747 Py_RETURN_NONE;
748}
749
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300750/*[clinic input]
751_io.BytesIO.close
752
753Disable all I/O operations.
754[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000755
756static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300757_io_BytesIO_close_impl(bytesio *self)
758/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000759{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200760 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200761 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000762 Py_RETURN_NONE;
763}
764
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000765/* Pickling support.
766
767 Note that only pickle protocol 2 and onward are supported since we use
768 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
769
770 Providing support for protocol < 2 would require the __reduce_ex__ method
771 which is notably long-winded when defined properly.
772
773 For BytesIO, the implementation would similar to one coded for
774 object.__reduce_ex__, but slightly less general. To be more specific, we
775 could call bytesio_getstate directly and avoid checking for the presence of
776 a fallback __reduce__ method. However, we would still need a __newobj__
777 function to use the efficient instance representation of PEP 307.
778 */
779
780static PyObject *
781bytesio_getstate(bytesio *self)
782{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300783 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000784 PyObject *dict;
785 PyObject *state;
786
787 if (initvalue == NULL)
788 return NULL;
789 if (self->dict == NULL) {
790 Py_INCREF(Py_None);
791 dict = Py_None;
792 }
793 else {
794 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200795 if (dict == NULL) {
796 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000797 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200798 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000799 }
800
801 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
802 Py_DECREF(initvalue);
803 return state;
804}
805
806static PyObject *
807bytesio_setstate(bytesio *self, PyObject *state)
808{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200809 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000810 PyObject *position_obj;
811 PyObject *dict;
812 Py_ssize_t pos;
813
814 assert(state != NULL);
815
816 /* We allow the state tuple to be longer than 3, because we may need
817 someday to extend the object's state without breaking
818 backward-compatibility. */
819 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
820 PyErr_Format(PyExc_TypeError,
821 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
822 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
823 return NULL;
824 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200825 CHECK_EXPORTS(self);
826 /* Reset the object to its default state. This is only needed to handle
827 the case of repeated calls to __setstate__. */
828 self->string_size = 0;
829 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000830
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200831 /* Set the value of the internal buffer. If state[0] does not support the
832 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300833 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200834 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000835 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200836 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000837
838 /* Set carefully the position value. Alternatively, we could use the seek
839 method instead of modifying self->pos directly to better protect the
840 object internal state against errneous (or malicious) inputs. */
841 position_obj = PyTuple_GET_ITEM(state, 1);
842 if (!PyLong_Check(position_obj)) {
843 PyErr_Format(PyExc_TypeError,
844 "second item of state must be an integer, not %.200s",
845 Py_TYPE(position_obj)->tp_name);
846 return NULL;
847 }
848 pos = PyLong_AsSsize_t(position_obj);
849 if (pos == -1 && PyErr_Occurred())
850 return NULL;
851 if (pos < 0) {
852 PyErr_SetString(PyExc_ValueError,
853 "position value cannot be negative");
854 return NULL;
855 }
856 self->pos = pos;
857
858 /* Set the dictionary of the instance variables. */
859 dict = PyTuple_GET_ITEM(state, 2);
860 if (dict != Py_None) {
861 if (!PyDict_Check(dict)) {
862 PyErr_Format(PyExc_TypeError,
863 "third item of state should be a dict, got a %.200s",
864 Py_TYPE(dict)->tp_name);
865 return NULL;
866 }
867 if (self->dict) {
868 /* Alternatively, we could replace the internal dictionary
869 completely. However, it seems more practical to just update it. */
870 if (PyDict_Update(self->dict, dict) < 0)
871 return NULL;
872 }
873 else {
874 Py_INCREF(dict);
875 self->dict = dict;
876 }
877 }
878
879 Py_RETURN_NONE;
880}
881
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000882static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000883bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000884{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000885 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000886 if (self->exports > 0) {
887 PyErr_SetString(PyExc_SystemError,
888 "deallocated BytesIO object has exported buffers");
889 PyErr_Print();
890 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200891 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000892 Py_CLEAR(self->dict);
893 if (self->weakreflist != NULL)
894 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000895 Py_TYPE(self)->tp_free(self);
896}
897
898static PyObject *
899bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
900{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000901 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000902
903 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000904 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000905 if (self == NULL)
906 return NULL;
907
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000908 /* tp_alloc initializes all the fields to zero. So we don't have to
909 initialize them here. */
910
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200911 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000912 if (self->buf == NULL) {
913 Py_DECREF(self);
914 return PyErr_NoMemory();
915 }
916
917 return (PyObject *)self;
918}
919
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300920/*[clinic input]
921_io.BytesIO.__init__
922 initial_bytes as initvalue: object(c_default="NULL") = b''
923
924Buffered I/O implementation using an in-memory bytes buffer.
925[clinic start generated code]*/
926
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000927static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300928_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
929/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000930{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200931 /* In case, __init__ is called multiple times. */
932 self->string_size = 0;
933 self->pos = 0;
934
935 if (self->exports > 0) {
936 PyErr_SetString(PyExc_BufferError,
937 "Existing exports of data: object cannot be re-sized");
938 return -1;
939 }
940 if (initvalue && initvalue != Py_None) {
941 if (PyBytes_CheckExact(initvalue)) {
942 Py_INCREF(initvalue);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300943 Py_XSETREF(self->buf, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200944 self->string_size = PyBytes_GET_SIZE(initvalue);
945 }
946 else {
947 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300948 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200949 if (res == NULL)
950 return -1;
951 Py_DECREF(res);
952 self->pos = 0;
953 }
954 }
955
956 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000957}
958
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200959static PyObject *
960bytesio_sizeof(bytesio *self, void *unused)
961{
962 Py_ssize_t res;
963
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200964 res = _PyObject_SIZE(Py_TYPE(self));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200965 if (self->buf && !SHARED_BUF(self))
966 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200967 return PyLong_FromSsize_t(res);
968}
969
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000970static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000971bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972{
973 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000974 return 0;
975}
976
977static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000978bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000979{
980 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981 return 0;
982}
983
984
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300985#include "clinic/bytesio.c.h"
986
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000987static PyGetSetDef bytesio_getsetlist[] = {
988 {"closed", (getter)bytesio_get_closed, NULL,
989 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000990 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000991};
992
993static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300994 _IO_BYTESIO_READABLE_METHODDEF
995 _IO_BYTESIO_SEEKABLE_METHODDEF
996 _IO_BYTESIO_WRITABLE_METHODDEF
997 _IO_BYTESIO_CLOSE_METHODDEF
998 _IO_BYTESIO_FLUSH_METHODDEF
999 _IO_BYTESIO_ISATTY_METHODDEF
1000 _IO_BYTESIO_TELL_METHODDEF
1001 _IO_BYTESIO_WRITE_METHODDEF
1002 _IO_BYTESIO_WRITELINES_METHODDEF
1003 _IO_BYTESIO_READ1_METHODDEF
1004 _IO_BYTESIO_READINTO_METHODDEF
1005 _IO_BYTESIO_READLINE_METHODDEF
1006 _IO_BYTESIO_READLINES_METHODDEF
1007 _IO_BYTESIO_READ_METHODDEF
1008 _IO_BYTESIO_GETBUFFER_METHODDEF
1009 _IO_BYTESIO_GETVALUE_METHODDEF
1010 _IO_BYTESIO_SEEK_METHODDEF
1011 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001012 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
1013 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +02001014 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001015 {NULL, NULL} /* sentinel */
1016};
1017
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001019 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001020 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001021 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001022 0, /*tp_itemsize*/
1023 (destructor)bytesio_dealloc, /*tp_dealloc*/
1024 0, /*tp_print*/
1025 0, /*tp_getattr*/
1026 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001027 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001028 0, /*tp_repr*/
1029 0, /*tp_as_number*/
1030 0, /*tp_as_sequence*/
1031 0, /*tp_as_mapping*/
1032 0, /*tp_hash*/
1033 0, /*tp_call*/
1034 0, /*tp_str*/
1035 0, /*tp_getattro*/
1036 0, /*tp_setattro*/
1037 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001038 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1039 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001040 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 (traverseproc)bytesio_traverse, /*tp_traverse*/
1042 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001043 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001044 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001045 PyObject_SelfIter, /*tp_iter*/
1046 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1047 bytesio_methods, /*tp_methods*/
1048 0, /*tp_members*/
1049 bytesio_getsetlist, /*tp_getset*/
1050 0, /*tp_base*/
1051 0, /*tp_dict*/
1052 0, /*tp_descr_get*/
1053 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001054 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001055 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001056 0, /*tp_alloc*/
1057 bytesio_new, /*tp_new*/
1058};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001059
1060
1061/*
1062 * Implementation of the small intermediate object used by getbuffer().
1063 * getbuffer() returns a memoryview over this object, which should make it
1064 * invisible from Python code.
1065 */
1066
1067static int
1068bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1069{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001070 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001071
1072 if (view == NULL) {
1073 PyErr_SetString(PyExc_BufferError,
1074 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1075 return -1;
1076 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001077 if (SHARED_BUF(b)) {
1078 if (unshare_buffer(b, b->string_size) < 0)
1079 return -1;
1080 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001081
1082 /* cannot fail if view != NULL and readonly == 0 */
1083 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001084 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001085 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001086 b->exports++;
1087 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001088}
1089
1090static void
1091bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1092{
1093 bytesio *b = (bytesio *) obj->source;
1094 b->exports--;
1095}
1096
1097static int
1098bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1099{
1100 Py_VISIT(self->source);
1101 return 0;
1102}
1103
1104static void
1105bytesiobuf_dealloc(bytesiobuf *self)
1106{
1107 Py_CLEAR(self->source);
1108 Py_TYPE(self)->tp_free(self);
1109}
1110
1111static PyBufferProcs bytesiobuf_as_buffer = {
1112 (getbufferproc) bytesiobuf_getbuffer,
1113 (releasebufferproc) bytesiobuf_releasebuffer,
1114};
1115
1116PyTypeObject _PyBytesIOBuffer_Type = {
1117 PyVarObject_HEAD_INIT(NULL, 0)
1118 "_io._BytesIOBuffer", /*tp_name*/
1119 sizeof(bytesiobuf), /*tp_basicsize*/
1120 0, /*tp_itemsize*/
1121 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1122 0, /*tp_print*/
1123 0, /*tp_getattr*/
1124 0, /*tp_setattr*/
1125 0, /*tp_reserved*/
1126 0, /*tp_repr*/
1127 0, /*tp_as_number*/
1128 0, /*tp_as_sequence*/
1129 0, /*tp_as_mapping*/
1130 0, /*tp_hash*/
1131 0, /*tp_call*/
1132 0, /*tp_str*/
1133 0, /*tp_getattro*/
1134 0, /*tp_setattro*/
1135 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1136 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1137 0, /*tp_doc*/
1138 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1139 0, /*tp_clear*/
1140 0, /*tp_richcompare*/
1141 0, /*tp_weaklistoffset*/
1142 0, /*tp_iter*/
1143 0, /*tp_iternext*/
1144 0, /*tp_methods*/
1145 0, /*tp_members*/
1146 0, /*tp_getset*/
1147 0, /*tp_base*/
1148 0, /*tp_dict*/
1149 0, /*tp_descr_get*/
1150 0, /*tp_descr_set*/
1151 0, /*tp_dictoffset*/
1152 0, /*tp_init*/
1153 0, /*tp_alloc*/
1154 0, /*tp_new*/
1155};