blob: 9e5d78b1662812c6d8262faa67f3763fb393d38a [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{
90 PyObject *new_buf, *old_buf;
91 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);
99 old_buf = self->buf;
100 self->buf = new_buf;
101 Py_DECREF(old_buf);
102 return 0;
103}
104
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000105/* Internal routine for changing the size of the buffer of BytesIO objects.
106 The caller should ensure that the 'size' argument is non-negative. Returns
107 0 on success, -1 otherwise. */
108static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000109resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000110{
111 /* Here, unsigned types are used to avoid dealing with signed integer
112 overflow, which is undefined in C. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200113 size_t alloc = PyBytes_GET_SIZE(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000114
115 assert(self->buf != NULL);
116
117 /* For simplicity, stay in the range of the signed type. Anyway, Python
118 doesn't allow strings to be longer than this. */
119 if (size > PY_SSIZE_T_MAX)
120 goto overflow;
121
122 if (size < alloc / 2) {
123 /* Major downsize; resize down to exact size. */
124 alloc = size + 1;
125 }
126 else if (size < alloc) {
127 /* Within allocated size; quick exit */
128 return 0;
129 }
130 else if (size <= alloc * 1.125) {
131 /* Moderate upsize; overallocate similar to list_resize() */
132 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
133 }
134 else {
135 /* Major upsize; resize up to exact size */
136 alloc = size + 1;
137 }
138
139 if (alloc > ((size_t)-1) / sizeof(char))
140 goto overflow;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200141
142 if (SHARED_BUF(self)) {
143 if (unshare_buffer(self, alloc) < 0)
144 return -1;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000145 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200146 else {
147 if (_PyBytes_Resize(&self->buf, alloc) < 0)
148 return -1;
149 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000150
151 return 0;
152
153 overflow:
154 PyErr_SetString(PyExc_OverflowError,
155 "new buffer size too large");
156 return -1;
157}
158
159/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200160 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000161static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000162write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000163{
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200164 size_t endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000165 assert(self->buf != NULL);
166 assert(self->pos >= 0);
167 assert(len >= 0);
168
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200169 endpos = (size_t)self->pos + len;
170 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
171 if (resize_buffer(self, endpos) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000172 return -1;
173 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200174 else if (SHARED_BUF(self)) {
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200175 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200176 return -1;
177 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000178
179 if (self->pos > self->string_size) {
180 /* In case of overseek, pad with null bytes the buffer region between
181 the end of stream and the current position.
182
183 0 lo string_size hi
184 | |<---used--->|<----------available----------->|
185 | | <--to pad-->|<---to write---> |
186 0 buf position
187 */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200188 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000189 (self->pos - self->string_size) * sizeof(char));
190 }
191
192 /* Copy the data to the internal buffer, overwriting some of the existing
193 data if self->pos < self->string_size. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200194 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200195 self->pos = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000196
197 /* Set the new length of the internal string if it has changed. */
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200198 if ((size_t)self->string_size < endpos) {
199 self->string_size = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000200 }
201
202 return len;
203}
204
205static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000206bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000207{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000208 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000209 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000210 }
211 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000212 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000214}
215
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300216/*[clinic input]
217_io.BytesIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200218
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300219Returns True if the IO object can be read.
220[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200221
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000222static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300223_io_BytesIO_readable_impl(bytesio *self)
224/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000225{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200226 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000227 Py_RETURN_TRUE;
228}
229
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300230/*[clinic input]
231_io.BytesIO.writable
232
233Returns True if the IO object can be written.
234[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000235
236static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300237_io_BytesIO_writable_impl(bytesio *self)
238/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
239{
240 CHECK_CLOSED(self);
241 Py_RETURN_TRUE;
242}
243
244/*[clinic input]
245_io.BytesIO.seekable
246
247Returns True if the IO object can be seeked.
248[clinic start generated code]*/
249
250static PyObject *
251_io_BytesIO_seekable_impl(bytesio *self)
252/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
253{
254 CHECK_CLOSED(self);
255 Py_RETURN_TRUE;
256}
257
258/*[clinic input]
259_io.BytesIO.flush
260
261Does nothing.
262[clinic start generated code]*/
263
264static PyObject *
265_io_BytesIO_flush_impl(bytesio *self)
266/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000267{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200268 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000269 Py_RETURN_NONE;
270}
271
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300272/*[clinic input]
273_io.BytesIO.getbuffer
274
275Get a read-write view over the contents of the BytesIO object.
276[clinic start generated code]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000277
278static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300279_io_BytesIO_getbuffer_impl(bytesio *self)
280/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000281{
282 PyTypeObject *type = &_PyBytesIOBuffer_Type;
283 bytesiobuf *buf;
284 PyObject *view;
285
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200286 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000287
288 buf = (bytesiobuf *) type->tp_alloc(type, 0);
289 if (buf == NULL)
290 return NULL;
291 Py_INCREF(self);
292 buf->source = self;
293 view = PyMemoryView_FromObject((PyObject *) buf);
294 Py_DECREF(buf);
295 return view;
296}
297
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300298/*[clinic input]
299_io.BytesIO.getvalue
300
301Retrieve the entire contents of the BytesIO object.
302[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000303
304static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300305_io_BytesIO_getvalue_impl(bytesio *self)
306/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000307{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200308 CHECK_CLOSED(self);
309 if (self->string_size <= 1 || self->exports > 0)
310 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
311 self->string_size);
312
313 if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
314 if (SHARED_BUF(self)) {
315 if (unshare_buffer(self, self->string_size) < 0)
316 return NULL;
317 }
318 else {
319 if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
320 return NULL;
321 }
322 }
323 Py_INCREF(self->buf);
324 return self->buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000325}
326
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300327/*[clinic input]
328_io.BytesIO.isatty
329
330Always returns False.
331
332BytesIO objects are not connected to a TTY-like device.
333[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000334
335static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300336_io_BytesIO_isatty_impl(bytesio *self)
337/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000338{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200339 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000340 Py_RETURN_FALSE;
341}
342
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300343/*[clinic input]
344_io.BytesIO.tell
345
346Current file position, an integer.
347[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000348
349static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300350_io_BytesIO_tell_impl(bytesio *self)
351/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000352{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200353 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000354 return PyLong_FromSsize_t(self->pos);
355}
356
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200357static PyObject *
358read_bytes(bytesio *self, Py_ssize_t size)
359{
360 char *output;
361
362 assert(self->buf != NULL);
Serhiy Storchakab9765ee2015-02-03 14:57:49 +0200363 assert(size <= self->string_size);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200364 if (size > 1 &&
365 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
366 self->exports == 0) {
367 self->pos += size;
368 Py_INCREF(self->buf);
369 return self->buf;
370 }
371
372 output = PyBytes_AS_STRING(self->buf) + self->pos;
373 self->pos += size;
374 return PyBytes_FromStringAndSize(output, size);
375}
376
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300377/*[clinic input]
378_io.BytesIO.read
379 size as arg: object = None
380 /
381
382Read at most size bytes, returned as a bytes object.
383
384If the size argument is negative, read until EOF is reached.
385Return an empty bytes object at EOF.
386[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000387
388static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300389_io_BytesIO_read_impl(bytesio *self, PyObject *arg)
390/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000391{
392 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000393
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200394 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000395
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000396 if (PyLong_Check(arg)) {
397 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000398 if (size == -1 && PyErr_Occurred())
399 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000400 }
401 else if (arg == Py_None) {
402 /* Read until EOF is reached, by default. */
403 size = -1;
404 }
405 else {
406 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
407 Py_TYPE(arg)->tp_name);
408 return NULL;
409 }
410
411 /* adjust invalid sizes */
412 n = self->string_size - self->pos;
413 if (size < 0 || size > n) {
414 size = n;
415 if (size < 0)
416 size = 0;
417 }
418
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200419 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000420}
421
422
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300423/*[clinic input]
424_io.BytesIO.read1
425 size: object
426 /
427
428Read at most size bytes, returned as a bytes object.
429
430If the size argument is negative or omitted, read until EOF is reached.
431Return an empty bytes object at EOF.
432[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000433
434static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300435_io_BytesIO_read1(bytesio *self, PyObject *size)
436/*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000437{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300438 return _io_BytesIO_read_impl(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000439}
440
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300441/*[clinic input]
442_io.BytesIO.readline
443 size as arg: object = None
444 /
445
446Next line from the file, as a bytes object.
447
448Retain newline. A non-negative size argument limits the maximum
449number of bytes to return (an incomplete line may be returned then).
450Return an empty bytes object at EOF.
451[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000452
453static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300454_io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
455/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000456{
457 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000458
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200459 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000460
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000461 if (PyLong_Check(arg)) {
462 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000463 if (size == -1 && PyErr_Occurred())
464 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000465 }
466 else if (arg == Py_None) {
467 /* No size limit, by default. */
468 size = -1;
469 }
470 else {
471 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
472 Py_TYPE(arg)->tp_name);
473 return NULL;
474 }
475
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300476 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000477
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200478 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000479}
480
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300481/*[clinic input]
482_io.BytesIO.readlines
483 size as arg: object = None
484 /
485
486List of bytes objects, each a line from the file.
487
488Call readline() repeatedly and return a list of the lines so read.
489The optional size argument, if given, is an approximate bound on the
490total number of bytes in the lines returned.
491[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000492
493static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300494_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
495/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000496{
497 Py_ssize_t maxsize, size, n;
498 PyObject *result, *line;
499 char *output;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000500
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200501 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000502
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000503 if (PyLong_Check(arg)) {
504 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000505 if (maxsize == -1 && PyErr_Occurred())
506 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000507 }
508 else if (arg == Py_None) {
509 /* No size limit, by default. */
510 maxsize = -1;
511 }
512 else {
513 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
514 Py_TYPE(arg)->tp_name);
515 return NULL;
516 }
517
518 size = 0;
519 result = PyList_New(0);
520 if (!result)
521 return NULL;
522
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200523 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300524 while ((n = scan_eol(self, -1)) != 0) {
525 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000526 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000527 if (!line)
528 goto on_error;
529 if (PyList_Append(result, line) == -1) {
530 Py_DECREF(line);
531 goto on_error;
532 }
533 Py_DECREF(line);
534 size += n;
535 if (maxsize > 0 && size >= maxsize)
536 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300537 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000538 }
539 return result;
540
541 on_error:
542 Py_DECREF(result);
543 return NULL;
544}
545
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300546/*[clinic input]
547_io.BytesIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700548 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300549 /
550
Martin Panter6bb91f32016-05-28 00:41:57 +0000551Read bytes into buffer.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300552
553Returns number of bytes read (0 for EOF), or None if the object
Martin Panter119e5022016-04-16 09:28:57 +0000554is set not to block and has no data to read.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300555[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000556
557static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300558_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
Martin Panter6bb91f32016-05-28 00:41:57 +0000559/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000560{
Benjamin Petersonfa735552010-11-20 17:24:04 +0000561 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000562
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200563 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000564
Benjamin Petersonfa735552010-11-20 17:24:04 +0000565 /* adjust invalid sizes */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300566 len = buffer->len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000567 n = self->string_size - self->pos;
568 if (len > n) {
569 len = n;
570 if (len < 0)
571 len = 0;
572 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000573
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300574 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000575 assert(self->pos + len < PY_SSIZE_T_MAX);
576 assert(len >= 0);
577 self->pos += len;
578
579 return PyLong_FromSsize_t(len);
580}
581
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300582/*[clinic input]
583_io.BytesIO.truncate
584 size as arg: object = None
585 /
586
587Truncate the file to at most size bytes.
588
589Size defaults to the current file position, as returned by tell().
590The current file position is unchanged. Returns the new size.
591[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000592
593static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300594_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
595/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000596{
597 Py_ssize_t size;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000598
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200599 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000600 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000601
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000602 if (PyLong_Check(arg)) {
603 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000604 if (size == -1 && PyErr_Occurred())
605 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000606 }
607 else if (arg == Py_None) {
608 /* Truncate to current position if no argument is passed. */
609 size = self->pos;
610 }
611 else {
612 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
613 Py_TYPE(arg)->tp_name);
614 return NULL;
615 }
616
617 if (size < 0) {
618 PyErr_Format(PyExc_ValueError,
619 "negative size value %zd", size);
620 return NULL;
621 }
622
623 if (size < self->string_size) {
624 self->string_size = size;
625 if (resize_buffer(self, size) < 0)
626 return NULL;
627 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000628
629 return PyLong_FromSsize_t(size);
630}
631
632static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000633bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000634{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000635 Py_ssize_t n;
636
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200637 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000638
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300639 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000640
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300641 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000642 return NULL;
643
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200644 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000645}
646
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300647/*[clinic input]
648_io.BytesIO.seek
649 pos: Py_ssize_t
650 whence: int = 0
651 /
652
653Change stream position.
654
655Seek to byte offset pos relative to position indicated by whence:
656 0 Start of stream (the default). pos should be >= 0;
657 1 Current position - pos may be negative;
658 2 End of stream - pos usually negative.
659Returns the new absolute position.
660[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000661
662static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300663_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
664/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000665{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200666 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000667
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300668 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000669 PyErr_Format(PyExc_ValueError,
670 "negative seek value %zd", pos);
671 return NULL;
672 }
673
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300674 /* whence = 0: offset relative to beginning of the string.
675 whence = 1: offset relative to current position.
676 whence = 2: offset relative the end of the string. */
677 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000678 if (pos > PY_SSIZE_T_MAX - self->pos) {
679 PyErr_SetString(PyExc_OverflowError,
680 "new position too large");
681 return NULL;
682 }
683 pos += self->pos;
684 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300685 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000686 if (pos > PY_SSIZE_T_MAX - self->string_size) {
687 PyErr_SetString(PyExc_OverflowError,
688 "new position too large");
689 return NULL;
690 }
691 pos += self->string_size;
692 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300693 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000694 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300695 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000696 return NULL;
697 }
698
699 if (pos < 0)
700 pos = 0;
701 self->pos = pos;
702
703 return PyLong_FromSsize_t(self->pos);
704}
705
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300706/*[clinic input]
707_io.BytesIO.write
708 b: object
709 /
710
711Write bytes to file.
712
713Return the number of bytes written.
714[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000715
716static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300717_io_BytesIO_write(bytesio *self, PyObject *b)
718/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000719{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000720 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000721 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000722
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200723 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000724 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000725
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300726 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000727 return NULL;
728
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000729 if (buf.len != 0)
730 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000731
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300733 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000734}
735
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300736/*[clinic input]
737_io.BytesIO.writelines
738 lines: object
739 /
740
741Write lines to the file.
742
743Note that newlines are not added. lines can be any iterable object
744producing bytes-like objects. This is equivalent to calling write() for
745each element.
746[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000747
748static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300749_io_BytesIO_writelines(bytesio *self, PyObject *lines)
750/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000751{
752 PyObject *it, *item;
753 PyObject *ret;
754
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200755 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000756
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300757 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000758 if (it == NULL)
759 return NULL;
760
761 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300762 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000763 Py_DECREF(item);
764 if (ret == NULL) {
765 Py_DECREF(it);
766 return NULL;
767 }
768 Py_DECREF(ret);
769 }
770 Py_DECREF(it);
771
772 /* See if PyIter_Next failed */
773 if (PyErr_Occurred())
774 return NULL;
775
776 Py_RETURN_NONE;
777}
778
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300779/*[clinic input]
780_io.BytesIO.close
781
782Disable all I/O operations.
783[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000784
785static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300786_io_BytesIO_close_impl(bytesio *self)
787/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000788{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200789 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200790 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000791 Py_RETURN_NONE;
792}
793
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000794/* Pickling support.
795
796 Note that only pickle protocol 2 and onward are supported since we use
797 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
798
799 Providing support for protocol < 2 would require the __reduce_ex__ method
800 which is notably long-winded when defined properly.
801
802 For BytesIO, the implementation would similar to one coded for
803 object.__reduce_ex__, but slightly less general. To be more specific, we
804 could call bytesio_getstate directly and avoid checking for the presence of
805 a fallback __reduce__ method. However, we would still need a __newobj__
806 function to use the efficient instance representation of PEP 307.
807 */
808
809static PyObject *
810bytesio_getstate(bytesio *self)
811{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300812 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000813 PyObject *dict;
814 PyObject *state;
815
816 if (initvalue == NULL)
817 return NULL;
818 if (self->dict == NULL) {
819 Py_INCREF(Py_None);
820 dict = Py_None;
821 }
822 else {
823 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200824 if (dict == NULL) {
825 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000826 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200827 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000828 }
829
830 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
831 Py_DECREF(initvalue);
832 return state;
833}
834
835static PyObject *
836bytesio_setstate(bytesio *self, PyObject *state)
837{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200838 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000839 PyObject *position_obj;
840 PyObject *dict;
841 Py_ssize_t pos;
842
843 assert(state != NULL);
844
845 /* We allow the state tuple to be longer than 3, because we may need
846 someday to extend the object's state without breaking
847 backward-compatibility. */
848 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
849 PyErr_Format(PyExc_TypeError,
850 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
851 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
852 return NULL;
853 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200854 CHECK_EXPORTS(self);
855 /* Reset the object to its default state. This is only needed to handle
856 the case of repeated calls to __setstate__. */
857 self->string_size = 0;
858 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000859
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200860 /* Set the value of the internal buffer. If state[0] does not support the
861 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300862 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200863 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000864 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200865 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000866
867 /* Set carefully the position value. Alternatively, we could use the seek
868 method instead of modifying self->pos directly to better protect the
869 object internal state against errneous (or malicious) inputs. */
870 position_obj = PyTuple_GET_ITEM(state, 1);
871 if (!PyLong_Check(position_obj)) {
872 PyErr_Format(PyExc_TypeError,
873 "second item of state must be an integer, not %.200s",
874 Py_TYPE(position_obj)->tp_name);
875 return NULL;
876 }
877 pos = PyLong_AsSsize_t(position_obj);
878 if (pos == -1 && PyErr_Occurred())
879 return NULL;
880 if (pos < 0) {
881 PyErr_SetString(PyExc_ValueError,
882 "position value cannot be negative");
883 return NULL;
884 }
885 self->pos = pos;
886
887 /* Set the dictionary of the instance variables. */
888 dict = PyTuple_GET_ITEM(state, 2);
889 if (dict != Py_None) {
890 if (!PyDict_Check(dict)) {
891 PyErr_Format(PyExc_TypeError,
892 "third item of state should be a dict, got a %.200s",
893 Py_TYPE(dict)->tp_name);
894 return NULL;
895 }
896 if (self->dict) {
897 /* Alternatively, we could replace the internal dictionary
898 completely. However, it seems more practical to just update it. */
899 if (PyDict_Update(self->dict, dict) < 0)
900 return NULL;
901 }
902 else {
903 Py_INCREF(dict);
904 self->dict = dict;
905 }
906 }
907
908 Py_RETURN_NONE;
909}
910
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000911static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000912bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000913{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000914 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000915 if (self->exports > 0) {
916 PyErr_SetString(PyExc_SystemError,
917 "deallocated BytesIO object has exported buffers");
918 PyErr_Print();
919 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200920 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000921 Py_CLEAR(self->dict);
922 if (self->weakreflist != NULL)
923 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000924 Py_TYPE(self)->tp_free(self);
925}
926
927static PyObject *
928bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
929{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000930 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000931
932 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000933 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000934 if (self == NULL)
935 return NULL;
936
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000937 /* tp_alloc initializes all the fields to zero. So we don't have to
938 initialize them here. */
939
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200940 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000941 if (self->buf == NULL) {
942 Py_DECREF(self);
943 return PyErr_NoMemory();
944 }
945
946 return (PyObject *)self;
947}
948
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300949/*[clinic input]
950_io.BytesIO.__init__
951 initial_bytes as initvalue: object(c_default="NULL") = b''
952
953Buffered I/O implementation using an in-memory bytes buffer.
954[clinic start generated code]*/
955
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000956static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300957_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
958/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000959{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200960 /* In case, __init__ is called multiple times. */
961 self->string_size = 0;
962 self->pos = 0;
963
964 if (self->exports > 0) {
965 PyErr_SetString(PyExc_BufferError,
966 "Existing exports of data: object cannot be re-sized");
967 return -1;
968 }
969 if (initvalue && initvalue != Py_None) {
970 if (PyBytes_CheckExact(initvalue)) {
971 Py_INCREF(initvalue);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300972 Py_XSETREF(self->buf, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200973 self->string_size = PyBytes_GET_SIZE(initvalue);
974 }
975 else {
976 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300977 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200978 if (res == NULL)
979 return -1;
980 Py_DECREF(res);
981 self->pos = 0;
982 }
983 }
984
985 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000986}
987
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200988static PyObject *
989bytesio_sizeof(bytesio *self, void *unused)
990{
991 Py_ssize_t res;
992
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200993 res = _PyObject_SIZE(Py_TYPE(self));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200994 if (self->buf && !SHARED_BUF(self))
995 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200996 return PyLong_FromSsize_t(res);
997}
998
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000999static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001000bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001001{
1002 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003 return 0;
1004}
1005
1006static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001007bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001008{
1009 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001010 return 0;
1011}
1012
1013
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001014#include "clinic/bytesio.c.h"
1015
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001016static PyGetSetDef bytesio_getsetlist[] = {
1017 {"closed", (getter)bytesio_get_closed, NULL,
1018 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001019 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001020};
1021
1022static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001023 _IO_BYTESIO_READABLE_METHODDEF
1024 _IO_BYTESIO_SEEKABLE_METHODDEF
1025 _IO_BYTESIO_WRITABLE_METHODDEF
1026 _IO_BYTESIO_CLOSE_METHODDEF
1027 _IO_BYTESIO_FLUSH_METHODDEF
1028 _IO_BYTESIO_ISATTY_METHODDEF
1029 _IO_BYTESIO_TELL_METHODDEF
1030 _IO_BYTESIO_WRITE_METHODDEF
1031 _IO_BYTESIO_WRITELINES_METHODDEF
1032 _IO_BYTESIO_READ1_METHODDEF
1033 _IO_BYTESIO_READINTO_METHODDEF
1034 _IO_BYTESIO_READLINE_METHODDEF
1035 _IO_BYTESIO_READLINES_METHODDEF
1036 _IO_BYTESIO_READ_METHODDEF
1037 _IO_BYTESIO_GETBUFFER_METHODDEF
1038 _IO_BYTESIO_GETVALUE_METHODDEF
1039 _IO_BYTESIO_SEEK_METHODDEF
1040 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001041 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
1042 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +02001043 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001044 {NULL, NULL} /* sentinel */
1045};
1046
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001048 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001050 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001051 0, /*tp_itemsize*/
1052 (destructor)bytesio_dealloc, /*tp_dealloc*/
1053 0, /*tp_print*/
1054 0, /*tp_getattr*/
1055 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001056 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001057 0, /*tp_repr*/
1058 0, /*tp_as_number*/
1059 0, /*tp_as_sequence*/
1060 0, /*tp_as_mapping*/
1061 0, /*tp_hash*/
1062 0, /*tp_call*/
1063 0, /*tp_str*/
1064 0, /*tp_getattro*/
1065 0, /*tp_setattro*/
1066 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1068 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001069 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070 (traverseproc)bytesio_traverse, /*tp_traverse*/
1071 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001072 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001073 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001074 PyObject_SelfIter, /*tp_iter*/
1075 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1076 bytesio_methods, /*tp_methods*/
1077 0, /*tp_members*/
1078 bytesio_getsetlist, /*tp_getset*/
1079 0, /*tp_base*/
1080 0, /*tp_dict*/
1081 0, /*tp_descr_get*/
1082 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001083 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001084 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001085 0, /*tp_alloc*/
1086 bytesio_new, /*tp_new*/
1087};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001088
1089
1090/*
1091 * Implementation of the small intermediate object used by getbuffer().
1092 * getbuffer() returns a memoryview over this object, which should make it
1093 * invisible from Python code.
1094 */
1095
1096static int
1097bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1098{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001099 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001100
1101 if (view == NULL) {
1102 PyErr_SetString(PyExc_BufferError,
1103 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1104 return -1;
1105 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001106 if (SHARED_BUF(b)) {
1107 if (unshare_buffer(b, b->string_size) < 0)
1108 return -1;
1109 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001110
1111 /* cannot fail if view != NULL and readonly == 0 */
1112 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001113 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001114 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001115 b->exports++;
1116 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001117}
1118
1119static void
1120bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1121{
1122 bytesio *b = (bytesio *) obj->source;
1123 b->exports--;
1124}
1125
1126static int
1127bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1128{
1129 Py_VISIT(self->source);
1130 return 0;
1131}
1132
1133static void
1134bytesiobuf_dealloc(bytesiobuf *self)
1135{
1136 Py_CLEAR(self->source);
1137 Py_TYPE(self)->tp_free(self);
1138}
1139
1140static PyBufferProcs bytesiobuf_as_buffer = {
1141 (getbufferproc) bytesiobuf_getbuffer,
1142 (releasebufferproc) bytesiobuf_releasebuffer,
1143};
1144
1145PyTypeObject _PyBytesIOBuffer_Type = {
1146 PyVarObject_HEAD_INIT(NULL, 0)
1147 "_io._BytesIOBuffer", /*tp_name*/
1148 sizeof(bytesiobuf), /*tp_basicsize*/
1149 0, /*tp_itemsize*/
1150 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1151 0, /*tp_print*/
1152 0, /*tp_getattr*/
1153 0, /*tp_setattr*/
1154 0, /*tp_reserved*/
1155 0, /*tp_repr*/
1156 0, /*tp_as_number*/
1157 0, /*tp_as_sequence*/
1158 0, /*tp_as_mapping*/
1159 0, /*tp_hash*/
1160 0, /*tp_call*/
1161 0, /*tp_str*/
1162 0, /*tp_getattro*/
1163 0, /*tp_setattro*/
1164 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1165 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1166 0, /*tp_doc*/
1167 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1168 0, /*tp_clear*/
1169 0, /*tp_richcompare*/
1170 0, /*tp_weaklistoffset*/
1171 0, /*tp_iter*/
1172 0, /*tp_iternext*/
1173 0, /*tp_methods*/
1174 0, /*tp_members*/
1175 0, /*tp_getset*/
1176 0, /*tp_base*/
1177 0, /*tp_dict*/
1178 0, /*tp_descr_get*/
1179 0, /*tp_descr_set*/
1180 0, /*tp_dictoffset*/
1181 0, /*tp_init*/
1182 0, /*tp_alloc*/
1183 0, /*tp_new*/
1184};