blob: 8e54ec8e99c3894f160d3b771fb541816f6e60e1 [file] [log] [blame]
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01002#include "pycore_object.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003#include "structmember.h" /* for offsetof() */
4#include "_iomodule.h"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00005
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03006/*[clinic input]
7module _io
8class _io.BytesIO "bytesio *" "&PyBytesIO_Type"
9[clinic start generated code]*/
10/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
11
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000012typedef struct {
13 PyObject_HEAD
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020014 PyObject *buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000015 Py_ssize_t pos;
16 Py_ssize_t string_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000017 PyObject *dict;
18 PyObject *weakreflist;
Antoine Pitrou972ee132010-09-06 18:48:21 +000019 Py_ssize_t exports;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000020} bytesio;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000021
Antoine Pitrou972ee132010-09-06 18:48:21 +000022typedef struct {
23 PyObject_HEAD
24 bytesio *source;
25} bytesiobuf;
26
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020027/* The bytesio object can be in three states:
28 * Py_REFCNT(buf) == 1, exports == 0.
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020029 * Py_REFCNT(buf) > 1. exports == 0,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020030 first modification or export causes the internal buffer copying.
31 * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden.
32*/
Antoine Pitrou972ee132010-09-06 18:48:21 +000033
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020034#define CHECK_CLOSED(self) \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000035 if ((self)->buf == NULL) { \
36 PyErr_SetString(PyExc_ValueError, \
37 "I/O operation on closed file."); \
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020038 return NULL; \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000039 }
40
Antoine Pitrou972ee132010-09-06 18:48:21 +000041#define CHECK_EXPORTS(self) \
42 if ((self)->exports > 0) { \
43 PyErr_SetString(PyExc_BufferError, \
44 "Existing exports of data: object cannot be re-sized"); \
45 return NULL; \
46 }
47
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020048#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
Antoine Pitroucc66a732014-07-29 19:41:11 -040049
Antoine Pitrou972ee132010-09-06 18:48:21 +000050
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000051/* Internal routine to get a line from the buffer of a BytesIO
52 object. Returns the length between the current position to the
53 next newline character. */
54static Py_ssize_t
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030055scan_eol(bytesio *self, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000056{
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030057 const char *start, *n;
58 Py_ssize_t maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000059
60 assert(self->buf != NULL);
Serhiy Storchaka4e63f7a2015-09-04 07:48:19 +030061 assert(self->pos >= 0);
62
63 if (self->pos >= self->string_size)
64 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000065
66 /* Move to the end of the line, up to the end of the string, s. */
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030067 maxlen = self->string_size - self->pos;
68 if (len < 0 || len > maxlen)
69 len = maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000070
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030071 if (len) {
Serhiy Storchaka4e63f7a2015-09-04 07:48:19 +030072 start = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030073 n = memchr(start, '\n', len);
74 if (n)
75 /* Get the length from the current position to the end of
76 the line. */
77 len = n - start + 1;
78 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000079 assert(len >= 0);
80 assert(self->pos < PY_SSIZE_T_MAX - len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000081
82 return len;
83}
84
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020085/* Internal routine for detaching the shared buffer of BytesIO objects.
86 The caller should ensure that the 'size' argument is non-negative and
87 not lesser than self->string_size. Returns 0 on success, -1 otherwise. */
88static int
89unshare_buffer(bytesio *self, size_t size)
90{
Serhiy Storchaka1ed017a2015-12-27 15:51:32 +020091 PyObject *new_buf;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020092 assert(SHARED_BUF(self));
93 assert(self->exports == 0);
94 assert(size >= (size_t)self->string_size);
95 new_buf = PyBytes_FromStringAndSize(NULL, size);
96 if (new_buf == NULL)
97 return -1;
98 memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
99 self->string_size);
Serhiy Storchakaf01e4082016-04-10 18:12:01 +0300100 Py_SETREF(self->buf, new_buf);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200101 return 0;
102}
103
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000104/* Internal routine for changing the size of the buffer of BytesIO objects.
105 The caller should ensure that the 'size' argument is non-negative. Returns
106 0 on success, -1 otherwise. */
107static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000109{
110 /* Here, unsigned types are used to avoid dealing with signed integer
111 overflow, which is undefined in C. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200112 size_t alloc = PyBytes_GET_SIZE(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000113
114 assert(self->buf != NULL);
115
116 /* For simplicity, stay in the range of the signed type. Anyway, Python
117 doesn't allow strings to be longer than this. */
118 if (size > PY_SSIZE_T_MAX)
119 goto overflow;
120
121 if (size < alloc / 2) {
122 /* Major downsize; resize down to exact size. */
123 alloc = size + 1;
124 }
125 else if (size < alloc) {
126 /* Within allocated size; quick exit */
127 return 0;
128 }
129 else if (size <= alloc * 1.125) {
130 /* Moderate upsize; overallocate similar to list_resize() */
131 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
132 }
133 else {
134 /* Major upsize; resize up to exact size */
135 alloc = size + 1;
136 }
137
138 if (alloc > ((size_t)-1) / sizeof(char))
139 goto overflow;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200140
141 if (SHARED_BUF(self)) {
142 if (unshare_buffer(self, alloc) < 0)
143 return -1;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000144 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200145 else {
146 if (_PyBytes_Resize(&self->buf, alloc) < 0)
147 return -1;
148 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000149
150 return 0;
151
152 overflow:
153 PyErr_SetString(PyExc_OverflowError,
154 "new buffer size too large");
155 return -1;
156}
157
158/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200159 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000160static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000161write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000162{
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200163 size_t endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000164 assert(self->buf != NULL);
165 assert(self->pos >= 0);
166 assert(len >= 0);
167
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200168 endpos = (size_t)self->pos + len;
169 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
170 if (resize_buffer(self, endpos) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000171 return -1;
172 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200173 else if (SHARED_BUF(self)) {
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200174 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200175 return -1;
176 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000177
178 if (self->pos > self->string_size) {
179 /* In case of overseek, pad with null bytes the buffer region between
180 the end of stream and the current position.
181
182 0 lo string_size hi
183 | |<---used--->|<----------available----------->|
184 | | <--to pad-->|<---to write---> |
185 0 buf position
186 */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200187 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000188 (self->pos - self->string_size) * sizeof(char));
189 }
190
191 /* Copy the data to the internal buffer, overwriting some of the existing
192 data if self->pos < self->string_size. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200193 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200194 self->pos = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000195
196 /* Set the new length of the internal string if it has changed. */
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200197 if ((size_t)self->string_size < endpos) {
198 self->string_size = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000199 }
200
201 return len;
202}
203
204static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000205bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000206{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000207 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000208 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000209 }
210 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000211 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000213}
214
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300215/*[clinic input]
216_io.BytesIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200217
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300218Returns True if the IO object can be read.
219[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200220
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000221static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300222_io_BytesIO_readable_impl(bytesio *self)
223/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000224{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200225 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000226 Py_RETURN_TRUE;
227}
228
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300229/*[clinic input]
230_io.BytesIO.writable
231
232Returns True if the IO object can be written.
233[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000234
235static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300236_io_BytesIO_writable_impl(bytesio *self)
237/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
238{
239 CHECK_CLOSED(self);
240 Py_RETURN_TRUE;
241}
242
243/*[clinic input]
244_io.BytesIO.seekable
245
246Returns True if the IO object can be seeked.
247[clinic start generated code]*/
248
249static PyObject *
250_io_BytesIO_seekable_impl(bytesio *self)
251/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
252{
253 CHECK_CLOSED(self);
254 Py_RETURN_TRUE;
255}
256
257/*[clinic input]
258_io.BytesIO.flush
259
260Does nothing.
261[clinic start generated code]*/
262
263static PyObject *
264_io_BytesIO_flush_impl(bytesio *self)
265/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000266{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200267 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000268 Py_RETURN_NONE;
269}
270
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300271/*[clinic input]
272_io.BytesIO.getbuffer
273
274Get a read-write view over the contents of the BytesIO object.
275[clinic start generated code]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000276
277static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300278_io_BytesIO_getbuffer_impl(bytesio *self)
279/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000280{
281 PyTypeObject *type = &_PyBytesIOBuffer_Type;
282 bytesiobuf *buf;
283 PyObject *view;
284
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200285 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000286
287 buf = (bytesiobuf *) type->tp_alloc(type, 0);
288 if (buf == NULL)
289 return NULL;
290 Py_INCREF(self);
291 buf->source = self;
292 view = PyMemoryView_FromObject((PyObject *) buf);
293 Py_DECREF(buf);
294 return view;
295}
296
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300297/*[clinic input]
298_io.BytesIO.getvalue
299
300Retrieve the entire contents of the BytesIO object.
301[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000302
303static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300304_io_BytesIO_getvalue_impl(bytesio *self)
305/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000306{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200307 CHECK_CLOSED(self);
308 if (self->string_size <= 1 || self->exports > 0)
309 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
310 self->string_size);
311
312 if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
313 if (SHARED_BUF(self)) {
314 if (unshare_buffer(self, self->string_size) < 0)
315 return NULL;
316 }
317 else {
318 if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
319 return NULL;
320 }
321 }
322 Py_INCREF(self->buf);
323 return self->buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000324}
325
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300326/*[clinic input]
327_io.BytesIO.isatty
328
329Always returns False.
330
331BytesIO objects are not connected to a TTY-like device.
332[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000333
334static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300335_io_BytesIO_isatty_impl(bytesio *self)
336/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000337{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200338 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000339 Py_RETURN_FALSE;
340}
341
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300342/*[clinic input]
343_io.BytesIO.tell
344
345Current file position, an integer.
346[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000347
348static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300349_io_BytesIO_tell_impl(bytesio *self)
350/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000351{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200352 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000353 return PyLong_FromSsize_t(self->pos);
354}
355
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200356static PyObject *
357read_bytes(bytesio *self, Py_ssize_t size)
358{
359 char *output;
360
361 assert(self->buf != NULL);
Serhiy Storchakab9765ee2015-02-03 14:57:49 +0200362 assert(size <= self->string_size);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200363 if (size > 1 &&
364 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
365 self->exports == 0) {
366 self->pos += size;
367 Py_INCREF(self->buf);
368 return self->buf;
369 }
370
371 output = PyBytes_AS_STRING(self->buf) + self->pos;
372 self->pos += size;
373 return PyBytes_FromStringAndSize(output, size);
374}
375
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300376/*[clinic input]
377_io.BytesIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300378 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300379 /
380
381Read at most size bytes, returned as a bytes object.
382
383If the size argument is negative, read until EOF is reached.
384Return an empty bytes object at EOF.
385[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000386
387static PyObject *
orenmn74002542017-03-11 00:52:01 +0200388_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300389/*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000390{
orenmn74002542017-03-11 00:52:01 +0200391 Py_ssize_t n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000392
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200393 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000394
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000395 /* adjust invalid sizes */
396 n = self->string_size - self->pos;
397 if (size < 0 || size > n) {
398 size = n;
399 if (size < 0)
400 size = 0;
401 }
402
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200403 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000404}
405
406
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300407/*[clinic input]
408_io.BytesIO.read1
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300409 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300410 /
411
412Read at most size bytes, returned as a bytes object.
413
414If the size argument is negative or omitted, read until EOF is reached.
415Return an empty bytes object at EOF.
416[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000417
418static PyObject *
orenmn74002542017-03-11 00:52:01 +0200419_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300420/*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000421{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300422 return _io_BytesIO_read_impl(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000423}
424
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300425/*[clinic input]
426_io.BytesIO.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300427 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300428 /
429
430Next line from the file, as a bytes object.
431
432Retain newline. A non-negative size argument limits the maximum
433number of bytes to return (an incomplete line may be returned then).
434Return an empty bytes object at EOF.
435[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000436
437static PyObject *
orenmn74002542017-03-11 00:52:01 +0200438_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300439/*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000440{
orenmn74002542017-03-11 00:52:01 +0200441 Py_ssize_t n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000442
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200443 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000444
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300445 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000446
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200447 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000448}
449
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300450/*[clinic input]
451_io.BytesIO.readlines
452 size as arg: object = None
453 /
454
455List of bytes objects, each a line from the file.
456
457Call readline() repeatedly and return a list of the lines so read.
458The optional size argument, if given, is an approximate bound on the
459total number of bytes in the lines returned.
460[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000461
462static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300463_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
464/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000465{
466 Py_ssize_t maxsize, size, n;
467 PyObject *result, *line;
468 char *output;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000469
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200470 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000471
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000472 if (PyLong_Check(arg)) {
473 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000474 if (maxsize == -1 && PyErr_Occurred())
475 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000476 }
477 else if (arg == Py_None) {
478 /* No size limit, by default. */
479 maxsize = -1;
480 }
481 else {
482 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
483 Py_TYPE(arg)->tp_name);
484 return NULL;
485 }
486
487 size = 0;
488 result = PyList_New(0);
489 if (!result)
490 return NULL;
491
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200492 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300493 while ((n = scan_eol(self, -1)) != 0) {
494 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000495 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000496 if (!line)
497 goto on_error;
498 if (PyList_Append(result, line) == -1) {
499 Py_DECREF(line);
500 goto on_error;
501 }
502 Py_DECREF(line);
503 size += n;
504 if (maxsize > 0 && size >= maxsize)
505 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300506 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000507 }
508 return result;
509
510 on_error:
511 Py_DECREF(result);
512 return NULL;
513}
514
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300515/*[clinic input]
516_io.BytesIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700517 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300518 /
519
Martin Panter6bb91f32016-05-28 00:41:57 +0000520Read bytes into buffer.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300521
522Returns number of bytes read (0 for EOF), or None if the object
Martin Panter119e5022016-04-16 09:28:57 +0000523is set not to block and has no data to read.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300524[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000525
526static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300527_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
Martin Panter6bb91f32016-05-28 00:41:57 +0000528/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000529{
Benjamin Petersonfa735552010-11-20 17:24:04 +0000530 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000531
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200532 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000533
Benjamin Petersonfa735552010-11-20 17:24:04 +0000534 /* adjust invalid sizes */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300535 len = buffer->len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000536 n = self->string_size - self->pos;
537 if (len > n) {
538 len = n;
539 if (len < 0)
540 len = 0;
541 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000542
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300543 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000544 assert(self->pos + len < PY_SSIZE_T_MAX);
545 assert(len >= 0);
546 self->pos += len;
547
548 return PyLong_FromSsize_t(len);
549}
550
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300551/*[clinic input]
552_io.BytesIO.truncate
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300553 size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300554 /
555
556Truncate the file to at most size bytes.
557
558Size defaults to the current file position, as returned by tell().
559The current file position is unchanged. Returns the new size.
560[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000561
562static PyObject *
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300563_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size)
564/*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000565{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200566 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000567 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000568
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000569 if (size < 0) {
570 PyErr_Format(PyExc_ValueError,
571 "negative size value %zd", size);
572 return NULL;
573 }
574
575 if (size < self->string_size) {
576 self->string_size = size;
577 if (resize_buffer(self, size) < 0)
578 return NULL;
579 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000580
581 return PyLong_FromSsize_t(size);
582}
583
584static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000585bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000586{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000587 Py_ssize_t n;
588
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200589 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000590
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300591 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000592
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300593 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000594 return NULL;
595
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200596 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000597}
598
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300599/*[clinic input]
600_io.BytesIO.seek
601 pos: Py_ssize_t
602 whence: int = 0
603 /
604
605Change stream position.
606
607Seek to byte offset pos relative to position indicated by whence:
608 0 Start of stream (the default). pos should be >= 0;
609 1 Current position - pos may be negative;
610 2 End of stream - pos usually negative.
611Returns the new absolute position.
612[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000613
614static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300615_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
616/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000617{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200618 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000619
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300620 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000621 PyErr_Format(PyExc_ValueError,
622 "negative seek value %zd", pos);
623 return NULL;
624 }
625
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300626 /* whence = 0: offset relative to beginning of the string.
627 whence = 1: offset relative to current position.
628 whence = 2: offset relative the end of the string. */
629 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000630 if (pos > PY_SSIZE_T_MAX - self->pos) {
631 PyErr_SetString(PyExc_OverflowError,
632 "new position too large");
633 return NULL;
634 }
635 pos += self->pos;
636 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300637 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000638 if (pos > PY_SSIZE_T_MAX - self->string_size) {
639 PyErr_SetString(PyExc_OverflowError,
640 "new position too large");
641 return NULL;
642 }
643 pos += self->string_size;
644 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300645 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000646 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300647 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000648 return NULL;
649 }
650
651 if (pos < 0)
652 pos = 0;
653 self->pos = pos;
654
655 return PyLong_FromSsize_t(self->pos);
656}
657
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300658/*[clinic input]
659_io.BytesIO.write
660 b: object
661 /
662
663Write bytes to file.
664
665Return the number of bytes written.
666[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000667
668static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300669_io_BytesIO_write(bytesio *self, PyObject *b)
670/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000671{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000672 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000674
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200675 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000676 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000677
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300678 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000679 return NULL;
680
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681 if (buf.len != 0)
682 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000683
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300685 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000686}
687
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300688/*[clinic input]
689_io.BytesIO.writelines
690 lines: object
691 /
692
693Write lines to the file.
694
695Note that newlines are not added. lines can be any iterable object
696producing bytes-like objects. This is equivalent to calling write() for
697each element.
698[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000699
700static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300701_io_BytesIO_writelines(bytesio *self, PyObject *lines)
702/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000703{
704 PyObject *it, *item;
705 PyObject *ret;
706
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200707 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000708
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300709 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000710 if (it == NULL)
711 return NULL;
712
713 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300714 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000715 Py_DECREF(item);
716 if (ret == NULL) {
717 Py_DECREF(it);
718 return NULL;
719 }
720 Py_DECREF(ret);
721 }
722 Py_DECREF(it);
723
724 /* See if PyIter_Next failed */
725 if (PyErr_Occurred())
726 return NULL;
727
728 Py_RETURN_NONE;
729}
730
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300731/*[clinic input]
732_io.BytesIO.close
733
734Disable all I/O operations.
735[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000736
737static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300738_io_BytesIO_close_impl(bytesio *self)
739/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000740{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200741 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200742 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000743 Py_RETURN_NONE;
744}
745
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000746/* Pickling support.
747
748 Note that only pickle protocol 2 and onward are supported since we use
749 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
750
751 Providing support for protocol < 2 would require the __reduce_ex__ method
752 which is notably long-winded when defined properly.
753
754 For BytesIO, the implementation would similar to one coded for
755 object.__reduce_ex__, but slightly less general. To be more specific, we
756 could call bytesio_getstate directly and avoid checking for the presence of
757 a fallback __reduce__ method. However, we would still need a __newobj__
758 function to use the efficient instance representation of PEP 307.
759 */
760
761static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530762bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored))
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000763{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300764 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000765 PyObject *dict;
766 PyObject *state;
767
768 if (initvalue == NULL)
769 return NULL;
770 if (self->dict == NULL) {
771 Py_INCREF(Py_None);
772 dict = Py_None;
773 }
774 else {
775 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200776 if (dict == NULL) {
777 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000778 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200779 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000780 }
781
782 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
783 Py_DECREF(initvalue);
784 return state;
785}
786
787static PyObject *
788bytesio_setstate(bytesio *self, PyObject *state)
789{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200790 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000791 PyObject *position_obj;
792 PyObject *dict;
793 Py_ssize_t pos;
794
795 assert(state != NULL);
796
797 /* We allow the state tuple to be longer than 3, because we may need
798 someday to extend the object's state without breaking
799 backward-compatibility. */
Serhiy Storchakafff9a312017-03-21 08:53:25 +0200800 if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 3) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000801 PyErr_Format(PyExc_TypeError,
802 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
803 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
804 return NULL;
805 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200806 CHECK_EXPORTS(self);
807 /* Reset the object to its default state. This is only needed to handle
808 the case of repeated calls to __setstate__. */
809 self->string_size = 0;
810 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000811
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200812 /* Set the value of the internal buffer. If state[0] does not support the
813 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300814 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200815 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000816 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200817 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000818
819 /* Set carefully the position value. Alternatively, we could use the seek
820 method instead of modifying self->pos directly to better protect the
821 object internal state against errneous (or malicious) inputs. */
822 position_obj = PyTuple_GET_ITEM(state, 1);
823 if (!PyLong_Check(position_obj)) {
824 PyErr_Format(PyExc_TypeError,
825 "second item of state must be an integer, not %.200s",
826 Py_TYPE(position_obj)->tp_name);
827 return NULL;
828 }
829 pos = PyLong_AsSsize_t(position_obj);
830 if (pos == -1 && PyErr_Occurred())
831 return NULL;
832 if (pos < 0) {
833 PyErr_SetString(PyExc_ValueError,
834 "position value cannot be negative");
835 return NULL;
836 }
837 self->pos = pos;
838
839 /* Set the dictionary of the instance variables. */
840 dict = PyTuple_GET_ITEM(state, 2);
841 if (dict != Py_None) {
842 if (!PyDict_Check(dict)) {
843 PyErr_Format(PyExc_TypeError,
844 "third item of state should be a dict, got a %.200s",
845 Py_TYPE(dict)->tp_name);
846 return NULL;
847 }
848 if (self->dict) {
849 /* Alternatively, we could replace the internal dictionary
850 completely. However, it seems more practical to just update it. */
851 if (PyDict_Update(self->dict, dict) < 0)
852 return NULL;
853 }
854 else {
855 Py_INCREF(dict);
856 self->dict = dict;
857 }
858 }
859
860 Py_RETURN_NONE;
861}
862
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000863static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000864bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000865{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000866 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000867 if (self->exports > 0) {
868 PyErr_SetString(PyExc_SystemError,
869 "deallocated BytesIO object has exported buffers");
870 PyErr_Print();
871 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200872 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000873 Py_CLEAR(self->dict);
874 if (self->weakreflist != NULL)
875 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000876 Py_TYPE(self)->tp_free(self);
877}
878
879static PyObject *
880bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
881{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000882 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000883
884 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000885 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000886 if (self == NULL)
887 return NULL;
888
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000889 /* tp_alloc initializes all the fields to zero. So we don't have to
890 initialize them here. */
891
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200892 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000893 if (self->buf == NULL) {
894 Py_DECREF(self);
895 return PyErr_NoMemory();
896 }
897
898 return (PyObject *)self;
899}
900
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300901/*[clinic input]
902_io.BytesIO.__init__
903 initial_bytes as initvalue: object(c_default="NULL") = b''
904
905Buffered I/O implementation using an in-memory bytes buffer.
906[clinic start generated code]*/
907
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000908static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300909_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
910/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000911{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200912 /* In case, __init__ is called multiple times. */
913 self->string_size = 0;
914 self->pos = 0;
915
916 if (self->exports > 0) {
917 PyErr_SetString(PyExc_BufferError,
918 "Existing exports of data: object cannot be re-sized");
919 return -1;
920 }
921 if (initvalue && initvalue != Py_None) {
922 if (PyBytes_CheckExact(initvalue)) {
923 Py_INCREF(initvalue);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300924 Py_XSETREF(self->buf, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200925 self->string_size = PyBytes_GET_SIZE(initvalue);
926 }
927 else {
928 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300929 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200930 if (res == NULL)
931 return -1;
932 Py_DECREF(res);
933 self->pos = 0;
934 }
935 }
936
937 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000938}
939
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200940static PyObject *
941bytesio_sizeof(bytesio *self, void *unused)
942{
943 Py_ssize_t res;
944
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200945 res = _PyObject_SIZE(Py_TYPE(self));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200946 if (self->buf && !SHARED_BUF(self))
947 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200948 return PyLong_FromSsize_t(res);
949}
950
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000951static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000952bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953{
954 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000955 return 0;
956}
957
958static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000959bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960{
961 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 return 0;
963}
964
965
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300966#include "clinic/bytesio.c.h"
967
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000968static PyGetSetDef bytesio_getsetlist[] = {
969 {"closed", (getter)bytesio_get_closed, NULL,
970 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000971 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000972};
973
974static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300975 _IO_BYTESIO_READABLE_METHODDEF
976 _IO_BYTESIO_SEEKABLE_METHODDEF
977 _IO_BYTESIO_WRITABLE_METHODDEF
978 _IO_BYTESIO_CLOSE_METHODDEF
979 _IO_BYTESIO_FLUSH_METHODDEF
980 _IO_BYTESIO_ISATTY_METHODDEF
981 _IO_BYTESIO_TELL_METHODDEF
982 _IO_BYTESIO_WRITE_METHODDEF
983 _IO_BYTESIO_WRITELINES_METHODDEF
984 _IO_BYTESIO_READ1_METHODDEF
985 _IO_BYTESIO_READINTO_METHODDEF
986 _IO_BYTESIO_READLINE_METHODDEF
987 _IO_BYTESIO_READLINES_METHODDEF
988 _IO_BYTESIO_READ_METHODDEF
989 _IO_BYTESIO_GETBUFFER_METHODDEF
990 _IO_BYTESIO_GETVALUE_METHODDEF
991 _IO_BYTESIO_SEEK_METHODDEF
992 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000993 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
994 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200995 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000996 {NULL, NULL} /* sentinel */
997};
998
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000999PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001000 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001001 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001002 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001003 0, /*tp_itemsize*/
1004 (destructor)bytesio_dealloc, /*tp_dealloc*/
1005 0, /*tp_print*/
1006 0, /*tp_getattr*/
1007 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001008 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001009 0, /*tp_repr*/
1010 0, /*tp_as_number*/
1011 0, /*tp_as_sequence*/
1012 0, /*tp_as_mapping*/
1013 0, /*tp_hash*/
1014 0, /*tp_call*/
1015 0, /*tp_str*/
1016 0, /*tp_getattro*/
1017 0, /*tp_setattro*/
1018 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001019 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1020 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001021 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001022 (traverseproc)bytesio_traverse, /*tp_traverse*/
1023 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001024 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001025 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001026 PyObject_SelfIter, /*tp_iter*/
1027 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1028 bytesio_methods, /*tp_methods*/
1029 0, /*tp_members*/
1030 bytesio_getsetlist, /*tp_getset*/
1031 0, /*tp_base*/
1032 0, /*tp_dict*/
1033 0, /*tp_descr_get*/
1034 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001035 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001036 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001037 0, /*tp_alloc*/
1038 bytesio_new, /*tp_new*/
1039};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001040
1041
1042/*
1043 * Implementation of the small intermediate object used by getbuffer().
1044 * getbuffer() returns a memoryview over this object, which should make it
1045 * invisible from Python code.
1046 */
1047
1048static int
1049bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1050{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001051 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001052
1053 if (view == NULL) {
1054 PyErr_SetString(PyExc_BufferError,
1055 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1056 return -1;
1057 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001058 if (SHARED_BUF(b)) {
1059 if (unshare_buffer(b, b->string_size) < 0)
1060 return -1;
1061 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001062
1063 /* cannot fail if view != NULL and readonly == 0 */
1064 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001065 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001066 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001067 b->exports++;
1068 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001069}
1070
1071static void
1072bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1073{
1074 bytesio *b = (bytesio *) obj->source;
1075 b->exports--;
1076}
1077
1078static int
1079bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1080{
1081 Py_VISIT(self->source);
1082 return 0;
1083}
1084
1085static void
1086bytesiobuf_dealloc(bytesiobuf *self)
1087{
INADA Naokia6296d32017-08-24 14:55:17 +09001088 /* bpo-31095: UnTrack is needed before calling any callbacks */
1089 PyObject_GC_UnTrack(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +00001090 Py_CLEAR(self->source);
1091 Py_TYPE(self)->tp_free(self);
1092}
1093
1094static PyBufferProcs bytesiobuf_as_buffer = {
1095 (getbufferproc) bytesiobuf_getbuffer,
1096 (releasebufferproc) bytesiobuf_releasebuffer,
1097};
1098
1099PyTypeObject _PyBytesIOBuffer_Type = {
1100 PyVarObject_HEAD_INIT(NULL, 0)
1101 "_io._BytesIOBuffer", /*tp_name*/
1102 sizeof(bytesiobuf), /*tp_basicsize*/
1103 0, /*tp_itemsize*/
1104 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1105 0, /*tp_print*/
1106 0, /*tp_getattr*/
1107 0, /*tp_setattr*/
1108 0, /*tp_reserved*/
1109 0, /*tp_repr*/
1110 0, /*tp_as_number*/
1111 0, /*tp_as_sequence*/
1112 0, /*tp_as_mapping*/
1113 0, /*tp_hash*/
1114 0, /*tp_call*/
1115 0, /*tp_str*/
1116 0, /*tp_getattro*/
1117 0, /*tp_setattro*/
1118 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1119 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1120 0, /*tp_doc*/
1121 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1122 0, /*tp_clear*/
1123 0, /*tp_richcompare*/
1124 0, /*tp_weaklistoffset*/
1125 0, /*tp_iter*/
1126 0, /*tp_iternext*/
1127 0, /*tp_methods*/
1128 0, /*tp_members*/
1129 0, /*tp_getset*/
1130 0, /*tp_base*/
1131 0, /*tp_dict*/
1132 0, /*tp_descr_get*/
1133 0, /*tp_descr_set*/
1134 0, /*tp_dictoffset*/
1135 0, /*tp_init*/
1136 0, /*tp_alloc*/
1137 0, /*tp_new*/
1138};