blob: ba33f8c50d6aadee2ffd3e2b5a74495003d3f763 [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
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000011typedef struct {
12 PyObject_HEAD
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020013 PyObject *buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000014 Py_ssize_t pos;
15 Py_ssize_t string_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000016 PyObject *dict;
17 PyObject *weakreflist;
Antoine Pitrou972ee132010-09-06 18:48:21 +000018 Py_ssize_t exports;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000019} bytesio;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000020
Antoine Pitrou972ee132010-09-06 18:48:21 +000021typedef struct {
22 PyObject_HEAD
23 bytesio *source;
24} bytesiobuf;
25
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020026/* The bytesio object can be in three states:
27 * Py_REFCNT(buf) == 1, exports == 0.
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020028 * Py_REFCNT(buf) > 1. exports == 0,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020029 first modification or export causes the internal buffer copying.
30 * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden.
31*/
Antoine Pitrou972ee132010-09-06 18:48:21 +000032
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020033#define CHECK_CLOSED(self) \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000034 if ((self)->buf == NULL) { \
35 PyErr_SetString(PyExc_ValueError, \
36 "I/O operation on closed file."); \
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020037 return NULL; \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000038 }
39
Antoine Pitrou972ee132010-09-06 18:48:21 +000040#define CHECK_EXPORTS(self) \
41 if ((self)->exports > 0) { \
42 PyErr_SetString(PyExc_BufferError, \
43 "Existing exports of data: object cannot be re-sized"); \
44 return NULL; \
45 }
46
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020047#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
Antoine Pitroucc66a732014-07-29 19:41:11 -040048
Antoine Pitrou972ee132010-09-06 18:48:21 +000049
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000050/* Internal routine to get a line from the buffer of a BytesIO
51 object. Returns the length between the current position to the
52 next newline character. */
53static Py_ssize_t
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030054scan_eol(bytesio *self, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000055{
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030056 const char *start, *n;
57 Py_ssize_t maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000058
59 assert(self->buf != NULL);
Serhiy Storchaka4e63f7a2015-09-04 07:48:19 +030060 assert(self->pos >= 0);
61
62 if (self->pos >= self->string_size)
63 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000064
65 /* Move to the end of the line, up to the end of the string, s. */
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030066 maxlen = self->string_size - self->pos;
67 if (len < 0 || len > maxlen)
68 len = maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000069
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030070 if (len) {
Serhiy Storchaka4e63f7a2015-09-04 07:48:19 +030071 start = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030072 n = memchr(start, '\n', len);
73 if (n)
74 /* Get the length from the current position to the end of
75 the line. */
76 len = n - start + 1;
77 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000078 assert(len >= 0);
79 assert(self->pos < PY_SSIZE_T_MAX - len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000080
81 return len;
82}
83
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020084/* Internal routine for detaching the shared buffer of BytesIO objects.
85 The caller should ensure that the 'size' argument is non-negative and
86 not lesser than self->string_size. Returns 0 on success, -1 otherwise. */
87static int
88unshare_buffer(bytesio *self, size_t size)
89{
Serhiy Storchaka1ed017a2015-12-27 15:51:32 +020090 PyObject *new_buf;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020091 assert(SHARED_BUF(self));
92 assert(self->exports == 0);
93 assert(size >= (size_t)self->string_size);
94 new_buf = PyBytes_FromStringAndSize(NULL, size);
95 if (new_buf == NULL)
96 return -1;
97 memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
98 self->string_size);
Serhiy Storchakaf01e4082016-04-10 18:12:01 +030099 Py_SETREF(self->buf, new_buf);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200100 return 0;
101}
102
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000103/* Internal routine for changing the size of the buffer of BytesIO objects.
104 The caller should ensure that the 'size' argument is non-negative. Returns
105 0 on success, -1 otherwise. */
106static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000107resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000108{
109 /* Here, unsigned types are used to avoid dealing with signed integer
110 overflow, which is undefined in C. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200111 size_t alloc = PyBytes_GET_SIZE(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000112
113 assert(self->buf != NULL);
114
115 /* For simplicity, stay in the range of the signed type. Anyway, Python
116 doesn't allow strings to be longer than this. */
117 if (size > PY_SSIZE_T_MAX)
118 goto overflow;
119
120 if (size < alloc / 2) {
121 /* Major downsize; resize down to exact size. */
122 alloc = size + 1;
123 }
124 else if (size < alloc) {
125 /* Within allocated size; quick exit */
126 return 0;
127 }
128 else if (size <= alloc * 1.125) {
129 /* Moderate upsize; overallocate similar to list_resize() */
130 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
131 }
132 else {
133 /* Major upsize; resize up to exact size */
134 alloc = size + 1;
135 }
136
137 if (alloc > ((size_t)-1) / sizeof(char))
138 goto overflow;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200139
140 if (SHARED_BUF(self)) {
141 if (unshare_buffer(self, alloc) < 0)
142 return -1;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000143 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200144 else {
145 if (_PyBytes_Resize(&self->buf, alloc) < 0)
146 return -1;
147 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000148
149 return 0;
150
151 overflow:
152 PyErr_SetString(PyExc_OverflowError,
153 "new buffer size too large");
154 return -1;
155}
156
157/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200158 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000159static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000160write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000161{
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200162 size_t endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000163 assert(self->buf != NULL);
164 assert(self->pos >= 0);
165 assert(len >= 0);
166
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200167 endpos = (size_t)self->pos + len;
168 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
169 if (resize_buffer(self, endpos) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000170 return -1;
171 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200172 else if (SHARED_BUF(self)) {
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200173 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200174 return -1;
175 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000176
177 if (self->pos > self->string_size) {
178 /* In case of overseek, pad with null bytes the buffer region between
179 the end of stream and the current position.
180
181 0 lo string_size hi
182 | |<---used--->|<----------available----------->|
183 | | <--to pad-->|<---to write---> |
184 0 buf position
185 */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200186 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000187 (self->pos - self->string_size) * sizeof(char));
188 }
189
190 /* Copy the data to the internal buffer, overwriting some of the existing
191 data if self->pos < self->string_size. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200192 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200193 self->pos = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000194
195 /* Set the new length of the internal string if it has changed. */
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200196 if ((size_t)self->string_size < endpos) {
197 self->string_size = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000198 }
199
200 return len;
201}
202
203static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000204bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000205{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000207 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000208 }
209 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000210 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000211 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000212}
213
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300214/*[clinic input]
215_io.BytesIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200216
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300217Returns True if the IO object can be read.
218[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200219
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000220static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300221_io_BytesIO_readable_impl(bytesio *self)
222/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000223{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200224 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000225 Py_RETURN_TRUE;
226}
227
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300228/*[clinic input]
229_io.BytesIO.writable
230
231Returns True if the IO object can be written.
232[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000233
234static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300235_io_BytesIO_writable_impl(bytesio *self)
236/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
237{
238 CHECK_CLOSED(self);
239 Py_RETURN_TRUE;
240}
241
242/*[clinic input]
243_io.BytesIO.seekable
244
245Returns True if the IO object can be seeked.
246[clinic start generated code]*/
247
248static PyObject *
249_io_BytesIO_seekable_impl(bytesio *self)
250/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
251{
252 CHECK_CLOSED(self);
253 Py_RETURN_TRUE;
254}
255
256/*[clinic input]
257_io.BytesIO.flush
258
259Does nothing.
260[clinic start generated code]*/
261
262static PyObject *
263_io_BytesIO_flush_impl(bytesio *self)
264/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000265{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200266 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000267 Py_RETURN_NONE;
268}
269
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300270/*[clinic input]
271_io.BytesIO.getbuffer
272
273Get a read-write view over the contents of the BytesIO object.
274[clinic start generated code]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000275
276static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300277_io_BytesIO_getbuffer_impl(bytesio *self)
278/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000279{
280 PyTypeObject *type = &_PyBytesIOBuffer_Type;
281 bytesiobuf *buf;
282 PyObject *view;
283
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200284 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000285
286 buf = (bytesiobuf *) type->tp_alloc(type, 0);
287 if (buf == NULL)
288 return NULL;
289 Py_INCREF(self);
290 buf->source = self;
291 view = PyMemoryView_FromObject((PyObject *) buf);
292 Py_DECREF(buf);
293 return view;
294}
295
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300296/*[clinic input]
297_io.BytesIO.getvalue
298
299Retrieve the entire contents of the BytesIO object.
300[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000301
302static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300303_io_BytesIO_getvalue_impl(bytesio *self)
304/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000305{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200306 CHECK_CLOSED(self);
307 if (self->string_size <= 1 || self->exports > 0)
308 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
309 self->string_size);
310
311 if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
312 if (SHARED_BUF(self)) {
313 if (unshare_buffer(self, self->string_size) < 0)
314 return NULL;
315 }
316 else {
317 if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
318 return NULL;
319 }
320 }
321 Py_INCREF(self->buf);
322 return self->buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000323}
324
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300325/*[clinic input]
326_io.BytesIO.isatty
327
328Always returns False.
329
330BytesIO objects are not connected to a TTY-like device.
331[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000332
333static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300334_io_BytesIO_isatty_impl(bytesio *self)
335/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000336{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200337 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000338 Py_RETURN_FALSE;
339}
340
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300341/*[clinic input]
342_io.BytesIO.tell
343
344Current file position, an integer.
345[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000346
347static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300348_io_BytesIO_tell_impl(bytesio *self)
349/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000350{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200351 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000352 return PyLong_FromSsize_t(self->pos);
353}
354
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200355static PyObject *
356read_bytes(bytesio *self, Py_ssize_t size)
357{
358 char *output;
359
360 assert(self->buf != NULL);
Serhiy Storchakab9765ee2015-02-03 14:57:49 +0200361 assert(size <= self->string_size);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200362 if (size > 1 &&
363 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
364 self->exports == 0) {
365 self->pos += size;
366 Py_INCREF(self->buf);
367 return self->buf;
368 }
369
370 output = PyBytes_AS_STRING(self->buf) + self->pos;
371 self->pos += size;
372 return PyBytes_FromStringAndSize(output, size);
373}
374
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300375/*[clinic input]
376_io.BytesIO.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300377 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300378 /
379
380Read at most size bytes, returned as a bytes object.
381
382If the size argument is negative, read until EOF is reached.
383Return an empty bytes object at EOF.
384[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000385
386static PyObject *
orenmn74002542017-03-11 00:52:01 +0200387_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300388/*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000389{
orenmn74002542017-03-11 00:52:01 +0200390 Py_ssize_t n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000391
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200392 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000393
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000394 /* adjust invalid sizes */
395 n = self->string_size - self->pos;
396 if (size < 0 || size > n) {
397 size = n;
398 if (size < 0)
399 size = 0;
400 }
401
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200402 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000403}
404
405
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300406/*[clinic input]
407_io.BytesIO.read1
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300408 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300409 /
410
411Read at most size bytes, returned as a bytes object.
412
413If the size argument is negative or omitted, read until EOF is reached.
414Return an empty bytes object at EOF.
415[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000416
417static PyObject *
orenmn74002542017-03-11 00:52:01 +0200418_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300419/*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000420{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300421 return _io_BytesIO_read_impl(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000422}
423
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300424/*[clinic input]
425_io.BytesIO.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300426 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300427 /
428
429Next line from the file, as a bytes object.
430
431Retain newline. A non-negative size argument limits the maximum
432number of bytes to return (an incomplete line may be returned then).
433Return an empty bytes object at EOF.
434[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000435
436static PyObject *
orenmn74002542017-03-11 00:52:01 +0200437_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300438/*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000439{
orenmn74002542017-03-11 00:52:01 +0200440 Py_ssize_t n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000441
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200442 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000443
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300444 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000445
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200446 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000447}
448
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300449/*[clinic input]
450_io.BytesIO.readlines
451 size as arg: object = None
452 /
453
454List of bytes objects, each a line from the file.
455
456Call readline() repeatedly and return a list of the lines so read.
457The optional size argument, if given, is an approximate bound on the
458total number of bytes in the lines returned.
459[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000460
461static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300462_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
463/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000464{
465 Py_ssize_t maxsize, size, n;
466 PyObject *result, *line;
467 char *output;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000468
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200469 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000470
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000471 if (PyLong_Check(arg)) {
472 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000473 if (maxsize == -1 && PyErr_Occurred())
474 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000475 }
476 else if (arg == Py_None) {
477 /* No size limit, by default. */
478 maxsize = -1;
479 }
480 else {
481 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
482 Py_TYPE(arg)->tp_name);
483 return NULL;
484 }
485
486 size = 0;
487 result = PyList_New(0);
488 if (!result)
489 return NULL;
490
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200491 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300492 while ((n = scan_eol(self, -1)) != 0) {
493 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000494 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000495 if (!line)
496 goto on_error;
497 if (PyList_Append(result, line) == -1) {
498 Py_DECREF(line);
499 goto on_error;
500 }
501 Py_DECREF(line);
502 size += n;
503 if (maxsize > 0 && size >= maxsize)
504 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300505 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000506 }
507 return result;
508
509 on_error:
510 Py_DECREF(result);
511 return NULL;
512}
513
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300514/*[clinic input]
515_io.BytesIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700516 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300517 /
518
Martin Panter6bb91f32016-05-28 00:41:57 +0000519Read bytes into buffer.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300520
521Returns number of bytes read (0 for EOF), or None if the object
Martin Panter119e5022016-04-16 09:28:57 +0000522is set not to block and has no data to read.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300523[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000524
525static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300526_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
Martin Panter6bb91f32016-05-28 00:41:57 +0000527/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000528{
Benjamin Petersonfa735552010-11-20 17:24:04 +0000529 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000530
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200531 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000532
Benjamin Petersonfa735552010-11-20 17:24:04 +0000533 /* adjust invalid sizes */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300534 len = buffer->len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000535 n = self->string_size - self->pos;
536 if (len > n) {
537 len = n;
538 if (len < 0)
539 len = 0;
540 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000541
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300542 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000543 assert(self->pos + len < PY_SSIZE_T_MAX);
544 assert(len >= 0);
545 self->pos += len;
546
547 return PyLong_FromSsize_t(len);
548}
549
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300550/*[clinic input]
551_io.BytesIO.truncate
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300552 size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300553 /
554
555Truncate the file to at most size bytes.
556
557Size defaults to the current file position, as returned by tell().
558The current file position is unchanged. Returns the new size.
559[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000560
561static PyObject *
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300562_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size)
563/*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000564{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200565 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000566 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000567
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000568 if (size < 0) {
569 PyErr_Format(PyExc_ValueError,
570 "negative size value %zd", size);
571 return NULL;
572 }
573
574 if (size < self->string_size) {
575 self->string_size = size;
576 if (resize_buffer(self, size) < 0)
577 return NULL;
578 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000579
580 return PyLong_FromSsize_t(size);
581}
582
583static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000585{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000586 Py_ssize_t n;
587
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200588 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000589
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300590 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000591
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300592 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000593 return NULL;
594
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200595 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000596}
597
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300598/*[clinic input]
599_io.BytesIO.seek
600 pos: Py_ssize_t
601 whence: int = 0
602 /
603
604Change stream position.
605
606Seek to byte offset pos relative to position indicated by whence:
607 0 Start of stream (the default). pos should be >= 0;
608 1 Current position - pos may be negative;
609 2 End of stream - pos usually negative.
610Returns the new absolute position.
611[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000612
613static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300614_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
615/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000616{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200617 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000618
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300619 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000620 PyErr_Format(PyExc_ValueError,
621 "negative seek value %zd", pos);
622 return NULL;
623 }
624
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300625 /* whence = 0: offset relative to beginning of the string.
626 whence = 1: offset relative to current position.
627 whence = 2: offset relative the end of the string. */
628 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000629 if (pos > PY_SSIZE_T_MAX - self->pos) {
630 PyErr_SetString(PyExc_OverflowError,
631 "new position too large");
632 return NULL;
633 }
634 pos += self->pos;
635 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300636 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000637 if (pos > PY_SSIZE_T_MAX - self->string_size) {
638 PyErr_SetString(PyExc_OverflowError,
639 "new position too large");
640 return NULL;
641 }
642 pos += self->string_size;
643 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300644 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000645 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300646 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000647 return NULL;
648 }
649
650 if (pos < 0)
651 pos = 0;
652 self->pos = pos;
653
654 return PyLong_FromSsize_t(self->pos);
655}
656
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300657/*[clinic input]
658_io.BytesIO.write
659 b: object
660 /
661
662Write bytes to file.
663
664Return the number of bytes written.
665[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000666
667static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300668_io_BytesIO_write(bytesio *self, PyObject *b)
669/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000670{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000671 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000673
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200674 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000675 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000676
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300677 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000678 return NULL;
679
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680 if (buf.len != 0)
681 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000682
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000683 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300684 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000685}
686
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300687/*[clinic input]
688_io.BytesIO.writelines
689 lines: object
690 /
691
692Write lines to the file.
693
694Note that newlines are not added. lines can be any iterable object
695producing bytes-like objects. This is equivalent to calling write() for
696each element.
697[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000698
699static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300700_io_BytesIO_writelines(bytesio *self, PyObject *lines)
701/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000702{
703 PyObject *it, *item;
704 PyObject *ret;
705
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200706 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000707
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300708 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000709 if (it == NULL)
710 return NULL;
711
712 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300713 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000714 Py_DECREF(item);
715 if (ret == NULL) {
716 Py_DECREF(it);
717 return NULL;
718 }
719 Py_DECREF(ret);
720 }
721 Py_DECREF(it);
722
723 /* See if PyIter_Next failed */
724 if (PyErr_Occurred())
725 return NULL;
726
727 Py_RETURN_NONE;
728}
729
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300730/*[clinic input]
731_io.BytesIO.close
732
733Disable all I/O operations.
734[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000735
736static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300737_io_BytesIO_close_impl(bytesio *self)
738/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000739{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200740 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200741 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000742 Py_RETURN_NONE;
743}
744
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000745/* Pickling support.
746
747 Note that only pickle protocol 2 and onward are supported since we use
748 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
749
750 Providing support for protocol < 2 would require the __reduce_ex__ method
751 which is notably long-winded when defined properly.
752
753 For BytesIO, the implementation would similar to one coded for
754 object.__reduce_ex__, but slightly less general. To be more specific, we
755 could call bytesio_getstate directly and avoid checking for the presence of
756 a fallback __reduce__ method. However, we would still need a __newobj__
757 function to use the efficient instance representation of PEP 307.
758 */
759
760static PyObject *
761bytesio_getstate(bytesio *self)
762{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300763 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000764 PyObject *dict;
765 PyObject *state;
766
767 if (initvalue == NULL)
768 return NULL;
769 if (self->dict == NULL) {
770 Py_INCREF(Py_None);
771 dict = Py_None;
772 }
773 else {
774 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200775 if (dict == NULL) {
776 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000777 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200778 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000779 }
780
781 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
782 Py_DECREF(initvalue);
783 return state;
784}
785
786static PyObject *
787bytesio_setstate(bytesio *self, PyObject *state)
788{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200789 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000790 PyObject *position_obj;
791 PyObject *dict;
792 Py_ssize_t pos;
793
794 assert(state != NULL);
795
796 /* We allow the state tuple to be longer than 3, because we may need
797 someday to extend the object's state without breaking
798 backward-compatibility. */
Serhiy Storchakafff9a312017-03-21 08:53:25 +0200799 if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 3) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000800 PyErr_Format(PyExc_TypeError,
801 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
802 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
803 return NULL;
804 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200805 CHECK_EXPORTS(self);
806 /* Reset the object to its default state. This is only needed to handle
807 the case of repeated calls to __setstate__. */
808 self->string_size = 0;
809 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000810
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200811 /* Set the value of the internal buffer. If state[0] does not support the
812 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300813 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200814 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000815 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200816 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000817
818 /* Set carefully the position value. Alternatively, we could use the seek
819 method instead of modifying self->pos directly to better protect the
820 object internal state against errneous (or malicious) inputs. */
821 position_obj = PyTuple_GET_ITEM(state, 1);
822 if (!PyLong_Check(position_obj)) {
823 PyErr_Format(PyExc_TypeError,
824 "second item of state must be an integer, not %.200s",
825 Py_TYPE(position_obj)->tp_name);
826 return NULL;
827 }
828 pos = PyLong_AsSsize_t(position_obj);
829 if (pos == -1 && PyErr_Occurred())
830 return NULL;
831 if (pos < 0) {
832 PyErr_SetString(PyExc_ValueError,
833 "position value cannot be negative");
834 return NULL;
835 }
836 self->pos = pos;
837
838 /* Set the dictionary of the instance variables. */
839 dict = PyTuple_GET_ITEM(state, 2);
840 if (dict != Py_None) {
841 if (!PyDict_Check(dict)) {
842 PyErr_Format(PyExc_TypeError,
843 "third item of state should be a dict, got a %.200s",
844 Py_TYPE(dict)->tp_name);
845 return NULL;
846 }
847 if (self->dict) {
848 /* Alternatively, we could replace the internal dictionary
849 completely. However, it seems more practical to just update it. */
850 if (PyDict_Update(self->dict, dict) < 0)
851 return NULL;
852 }
853 else {
854 Py_INCREF(dict);
855 self->dict = dict;
856 }
857 }
858
859 Py_RETURN_NONE;
860}
861
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000862static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000863bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000864{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000865 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000866 if (self->exports > 0) {
867 PyErr_SetString(PyExc_SystemError,
868 "deallocated BytesIO object has exported buffers");
869 PyErr_Print();
870 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200871 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000872 Py_CLEAR(self->dict);
873 if (self->weakreflist != NULL)
874 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000875 Py_TYPE(self)->tp_free(self);
876}
877
878static PyObject *
879bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
880{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000881 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000882
883 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000884 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000885 if (self == NULL)
886 return NULL;
887
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000888 /* tp_alloc initializes all the fields to zero. So we don't have to
889 initialize them here. */
890
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200891 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000892 if (self->buf == NULL) {
893 Py_DECREF(self);
894 return PyErr_NoMemory();
895 }
896
897 return (PyObject *)self;
898}
899
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300900/*[clinic input]
901_io.BytesIO.__init__
902 initial_bytes as initvalue: object(c_default="NULL") = b''
903
904Buffered I/O implementation using an in-memory bytes buffer.
905[clinic start generated code]*/
906
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000907static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300908_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
909/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000910{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200911 /* In case, __init__ is called multiple times. */
912 self->string_size = 0;
913 self->pos = 0;
914
915 if (self->exports > 0) {
916 PyErr_SetString(PyExc_BufferError,
917 "Existing exports of data: object cannot be re-sized");
918 return -1;
919 }
920 if (initvalue && initvalue != Py_None) {
921 if (PyBytes_CheckExact(initvalue)) {
922 Py_INCREF(initvalue);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300923 Py_XSETREF(self->buf, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200924 self->string_size = PyBytes_GET_SIZE(initvalue);
925 }
926 else {
927 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300928 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200929 if (res == NULL)
930 return -1;
931 Py_DECREF(res);
932 self->pos = 0;
933 }
934 }
935
936 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000937}
938
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200939static PyObject *
940bytesio_sizeof(bytesio *self, void *unused)
941{
942 Py_ssize_t res;
943
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200944 res = _PyObject_SIZE(Py_TYPE(self));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200945 if (self->buf && !SHARED_BUF(self))
946 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200947 return PyLong_FromSsize_t(res);
948}
949
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000951bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000952{
953 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954 return 0;
955}
956
957static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000958bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959{
960 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961 return 0;
962}
963
964
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300965#include "clinic/bytesio.c.h"
966
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000967static PyGetSetDef bytesio_getsetlist[] = {
968 {"closed", (getter)bytesio_get_closed, NULL,
969 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000970 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000971};
972
973static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300974 _IO_BYTESIO_READABLE_METHODDEF
975 _IO_BYTESIO_SEEKABLE_METHODDEF
976 _IO_BYTESIO_WRITABLE_METHODDEF
977 _IO_BYTESIO_CLOSE_METHODDEF
978 _IO_BYTESIO_FLUSH_METHODDEF
979 _IO_BYTESIO_ISATTY_METHODDEF
980 _IO_BYTESIO_TELL_METHODDEF
981 _IO_BYTESIO_WRITE_METHODDEF
982 _IO_BYTESIO_WRITELINES_METHODDEF
983 _IO_BYTESIO_READ1_METHODDEF
984 _IO_BYTESIO_READINTO_METHODDEF
985 _IO_BYTESIO_READLINE_METHODDEF
986 _IO_BYTESIO_READLINES_METHODDEF
987 _IO_BYTESIO_READ_METHODDEF
988 _IO_BYTESIO_GETBUFFER_METHODDEF
989 _IO_BYTESIO_GETVALUE_METHODDEF
990 _IO_BYTESIO_SEEK_METHODDEF
991 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000992 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
993 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200994 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000995 {NULL, NULL} /* sentinel */
996};
997
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000998PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000999 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001000 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001001 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001002 0, /*tp_itemsize*/
1003 (destructor)bytesio_dealloc, /*tp_dealloc*/
1004 0, /*tp_print*/
1005 0, /*tp_getattr*/
1006 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001007 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001008 0, /*tp_repr*/
1009 0, /*tp_as_number*/
1010 0, /*tp_as_sequence*/
1011 0, /*tp_as_mapping*/
1012 0, /*tp_hash*/
1013 0, /*tp_call*/
1014 0, /*tp_str*/
1015 0, /*tp_getattro*/
1016 0, /*tp_setattro*/
1017 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1019 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001020 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021 (traverseproc)bytesio_traverse, /*tp_traverse*/
1022 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001023 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001024 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001025 PyObject_SelfIter, /*tp_iter*/
1026 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1027 bytesio_methods, /*tp_methods*/
1028 0, /*tp_members*/
1029 bytesio_getsetlist, /*tp_getset*/
1030 0, /*tp_base*/
1031 0, /*tp_dict*/
1032 0, /*tp_descr_get*/
1033 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001034 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001035 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001036 0, /*tp_alloc*/
1037 bytesio_new, /*tp_new*/
1038};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001039
1040
1041/*
1042 * Implementation of the small intermediate object used by getbuffer().
1043 * getbuffer() returns a memoryview over this object, which should make it
1044 * invisible from Python code.
1045 */
1046
1047static int
1048bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1049{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001050 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001051
1052 if (view == NULL) {
1053 PyErr_SetString(PyExc_BufferError,
1054 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1055 return -1;
1056 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001057 if (SHARED_BUF(b)) {
1058 if (unshare_buffer(b, b->string_size) < 0)
1059 return -1;
1060 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001061
1062 /* cannot fail if view != NULL and readonly == 0 */
1063 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001064 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001065 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001066 b->exports++;
1067 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001068}
1069
1070static void
1071bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1072{
1073 bytesio *b = (bytesio *) obj->source;
1074 b->exports--;
1075}
1076
1077static int
1078bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1079{
1080 Py_VISIT(self->source);
1081 return 0;
1082}
1083
1084static void
1085bytesiobuf_dealloc(bytesiobuf *self)
1086{
INADA Naokia6296d32017-08-24 14:55:17 +09001087 /* bpo-31095: UnTrack is needed before calling any callbacks */
1088 PyObject_GC_UnTrack(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +00001089 Py_CLEAR(self->source);
1090 Py_TYPE(self)->tp_free(self);
1091}
1092
1093static PyBufferProcs bytesiobuf_as_buffer = {
1094 (getbufferproc) bytesiobuf_getbuffer,
1095 (releasebufferproc) bytesiobuf_releasebuffer,
1096};
1097
1098PyTypeObject _PyBytesIOBuffer_Type = {
1099 PyVarObject_HEAD_INIT(NULL, 0)
1100 "_io._BytesIOBuffer", /*tp_name*/
1101 sizeof(bytesiobuf), /*tp_basicsize*/
1102 0, /*tp_itemsize*/
1103 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1104 0, /*tp_print*/
1105 0, /*tp_getattr*/
1106 0, /*tp_setattr*/
1107 0, /*tp_reserved*/
1108 0, /*tp_repr*/
1109 0, /*tp_as_number*/
1110 0, /*tp_as_sequence*/
1111 0, /*tp_as_mapping*/
1112 0, /*tp_hash*/
1113 0, /*tp_call*/
1114 0, /*tp_str*/
1115 0, /*tp_getattro*/
1116 0, /*tp_setattro*/
1117 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1119 0, /*tp_doc*/
1120 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1121 0, /*tp_clear*/
1122 0, /*tp_richcompare*/
1123 0, /*tp_weaklistoffset*/
1124 0, /*tp_iter*/
1125 0, /*tp_iternext*/
1126 0, /*tp_methods*/
1127 0, /*tp_members*/
1128 0, /*tp_getset*/
1129 0, /*tp_base*/
1130 0, /*tp_dict*/
1131 0, /*tp_descr_get*/
1132 0, /*tp_descr_set*/
1133 0, /*tp_dictoffset*/
1134 0, /*tp_init*/
1135 0, /*tp_alloc*/
1136 0, /*tp_new*/
1137};