blob: a1ba121e2622ff8d2f85f8f3a56ca9a55f907b15 [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
377 size as arg: object = None
378 /
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 *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300387_io_BytesIO_read_impl(bytesio *self, PyObject *arg)
388/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000389{
390 Py_ssize_t size, 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 if (PyLong_Check(arg)) {
395 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000396 if (size == -1 && PyErr_Occurred())
397 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000398 }
399 else if (arg == Py_None) {
400 /* Read until EOF is reached, by default. */
401 size = -1;
402 }
403 else {
404 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
405 Py_TYPE(arg)->tp_name);
406 return NULL;
407 }
408
409 /* adjust invalid sizes */
410 n = self->string_size - self->pos;
411 if (size < 0 || size > n) {
412 size = n;
413 if (size < 0)
414 size = 0;
415 }
416
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200417 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000418}
419
420
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300421/*[clinic input]
422_io.BytesIO.read1
423 size: object
424 /
425
426Read at most size bytes, returned as a bytes object.
427
428If the size argument is negative or omitted, read until EOF is reached.
429Return an empty bytes object at EOF.
430[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000431
432static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300433_io_BytesIO_read1(bytesio *self, PyObject *size)
434/*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000435{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300436 return _io_BytesIO_read_impl(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000437}
438
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300439/*[clinic input]
440_io.BytesIO.readline
441 size as arg: object = None
442 /
443
444Next line from the file, as a bytes object.
445
446Retain newline. A non-negative size argument limits the maximum
447number of bytes to return (an incomplete line may be returned then).
448Return an empty bytes object at EOF.
449[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000450
451static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300452_io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
453/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000454{
455 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000456
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200457 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000458
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000459 if (PyLong_Check(arg)) {
460 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000461 if (size == -1 && PyErr_Occurred())
462 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000463 }
464 else if (arg == Py_None) {
465 /* No size limit, by default. */
466 size = -1;
467 }
468 else {
469 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
470 Py_TYPE(arg)->tp_name);
471 return NULL;
472 }
473
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300474 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000475
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200476 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000477}
478
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300479/*[clinic input]
480_io.BytesIO.readlines
481 size as arg: object = None
482 /
483
484List of bytes objects, each a line from the file.
485
486Call readline() repeatedly and return a list of the lines so read.
487The optional size argument, if given, is an approximate bound on the
488total number of bytes in the lines returned.
489[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000490
491static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300492_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
493/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000494{
495 Py_ssize_t maxsize, size, n;
496 PyObject *result, *line;
497 char *output;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000498
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200499 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000500
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000501 if (PyLong_Check(arg)) {
502 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000503 if (maxsize == -1 && PyErr_Occurred())
504 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000505 }
506 else if (arg == Py_None) {
507 /* No size limit, by default. */
508 maxsize = -1;
509 }
510 else {
511 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
512 Py_TYPE(arg)->tp_name);
513 return NULL;
514 }
515
516 size = 0;
517 result = PyList_New(0);
518 if (!result)
519 return NULL;
520
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200521 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300522 while ((n = scan_eol(self, -1)) != 0) {
523 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000524 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000525 if (!line)
526 goto on_error;
527 if (PyList_Append(result, line) == -1) {
528 Py_DECREF(line);
529 goto on_error;
530 }
531 Py_DECREF(line);
532 size += n;
533 if (maxsize > 0 && size >= maxsize)
534 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300535 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000536 }
537 return result;
538
539 on_error:
540 Py_DECREF(result);
541 return NULL;
542}
543
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300544/*[clinic input]
545_io.BytesIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700546 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300547 /
548
Martin Panter6bb91f32016-05-28 00:41:57 +0000549Read bytes into buffer.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300550
551Returns number of bytes read (0 for EOF), or None if the object
Martin Panter119e5022016-04-16 09:28:57 +0000552is set not to block and has no data to read.
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300553[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000554
555static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300556_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
Martin Panter6bb91f32016-05-28 00:41:57 +0000557/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000558{
Benjamin Petersonfa735552010-11-20 17:24:04 +0000559 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000560
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200561 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000562
Benjamin Petersonfa735552010-11-20 17:24:04 +0000563 /* adjust invalid sizes */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300564 len = buffer->len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000565 n = self->string_size - self->pos;
566 if (len > n) {
567 len = n;
568 if (len < 0)
569 len = 0;
570 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000571
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300572 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000573 assert(self->pos + len < PY_SSIZE_T_MAX);
574 assert(len >= 0);
575 self->pos += len;
576
577 return PyLong_FromSsize_t(len);
578}
579
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300580/*[clinic input]
581_io.BytesIO.truncate
582 size as arg: object = None
583 /
584
585Truncate the file to at most size bytes.
586
587Size defaults to the current file position, as returned by tell().
588The current file position is unchanged. Returns the new size.
589[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000590
591static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300592_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
593/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000594{
595 Py_ssize_t size;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000596
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200597 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000598 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000599
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000600 if (PyLong_Check(arg)) {
601 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000602 if (size == -1 && PyErr_Occurred())
603 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000604 }
605 else if (arg == Py_None) {
606 /* Truncate to current position if no argument is passed. */
607 size = self->pos;
608 }
609 else {
610 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
611 Py_TYPE(arg)->tp_name);
612 return NULL;
613 }
614
615 if (size < 0) {
616 PyErr_Format(PyExc_ValueError,
617 "negative size value %zd", size);
618 return NULL;
619 }
620
621 if (size < self->string_size) {
622 self->string_size = size;
623 if (resize_buffer(self, size) < 0)
624 return NULL;
625 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000626
627 return PyLong_FromSsize_t(size);
628}
629
630static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000631bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000632{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000633 Py_ssize_t n;
634
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200635 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000636
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300637 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000638
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300639 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000640 return NULL;
641
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200642 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000643}
644
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300645/*[clinic input]
646_io.BytesIO.seek
647 pos: Py_ssize_t
648 whence: int = 0
649 /
650
651Change stream position.
652
653Seek to byte offset pos relative to position indicated by whence:
654 0 Start of stream (the default). pos should be >= 0;
655 1 Current position - pos may be negative;
656 2 End of stream - pos usually negative.
657Returns the new absolute position.
658[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000659
660static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300661_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
662/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000663{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200664 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000665
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300666 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000667 PyErr_Format(PyExc_ValueError,
668 "negative seek value %zd", pos);
669 return NULL;
670 }
671
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300672 /* whence = 0: offset relative to beginning of the string.
673 whence = 1: offset relative to current position.
674 whence = 2: offset relative the end of the string. */
675 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000676 if (pos > PY_SSIZE_T_MAX - self->pos) {
677 PyErr_SetString(PyExc_OverflowError,
678 "new position too large");
679 return NULL;
680 }
681 pos += self->pos;
682 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300683 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000684 if (pos > PY_SSIZE_T_MAX - self->string_size) {
685 PyErr_SetString(PyExc_OverflowError,
686 "new position too large");
687 return NULL;
688 }
689 pos += self->string_size;
690 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300691 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000692 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300693 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000694 return NULL;
695 }
696
697 if (pos < 0)
698 pos = 0;
699 self->pos = pos;
700
701 return PyLong_FromSsize_t(self->pos);
702}
703
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300704/*[clinic input]
705_io.BytesIO.write
706 b: object
707 /
708
709Write bytes to file.
710
711Return the number of bytes written.
712[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000713
714static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300715_io_BytesIO_write(bytesio *self, PyObject *b)
716/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000717{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000718 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000719 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000720
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200721 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000722 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000723
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300724 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000725 return NULL;
726
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000727 if (buf.len != 0)
728 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000729
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000730 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300731 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000732}
733
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300734/*[clinic input]
735_io.BytesIO.writelines
736 lines: object
737 /
738
739Write lines to the file.
740
741Note that newlines are not added. lines can be any iterable object
742producing bytes-like objects. This is equivalent to calling write() for
743each element.
744[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000745
746static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300747_io_BytesIO_writelines(bytesio *self, PyObject *lines)
748/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000749{
750 PyObject *it, *item;
751 PyObject *ret;
752
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200753 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000754
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300755 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000756 if (it == NULL)
757 return NULL;
758
759 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300760 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000761 Py_DECREF(item);
762 if (ret == NULL) {
763 Py_DECREF(it);
764 return NULL;
765 }
766 Py_DECREF(ret);
767 }
768 Py_DECREF(it);
769
770 /* See if PyIter_Next failed */
771 if (PyErr_Occurred())
772 return NULL;
773
774 Py_RETURN_NONE;
775}
776
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300777/*[clinic input]
778_io.BytesIO.close
779
780Disable all I/O operations.
781[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000782
783static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300784_io_BytesIO_close_impl(bytesio *self)
785/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000786{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200787 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200788 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000789 Py_RETURN_NONE;
790}
791
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000792/* Pickling support.
793
794 Note that only pickle protocol 2 and onward are supported since we use
795 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
796
797 Providing support for protocol < 2 would require the __reduce_ex__ method
798 which is notably long-winded when defined properly.
799
800 For BytesIO, the implementation would similar to one coded for
801 object.__reduce_ex__, but slightly less general. To be more specific, we
802 could call bytesio_getstate directly and avoid checking for the presence of
803 a fallback __reduce__ method. However, we would still need a __newobj__
804 function to use the efficient instance representation of PEP 307.
805 */
806
807static PyObject *
808bytesio_getstate(bytesio *self)
809{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300810 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000811 PyObject *dict;
812 PyObject *state;
813
814 if (initvalue == NULL)
815 return NULL;
816 if (self->dict == NULL) {
817 Py_INCREF(Py_None);
818 dict = Py_None;
819 }
820 else {
821 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200822 if (dict == NULL) {
823 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000824 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200825 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000826 }
827
828 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
829 Py_DECREF(initvalue);
830 return state;
831}
832
833static PyObject *
834bytesio_setstate(bytesio *self, PyObject *state)
835{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200836 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000837 PyObject *position_obj;
838 PyObject *dict;
839 Py_ssize_t pos;
840
841 assert(state != NULL);
842
843 /* We allow the state tuple to be longer than 3, because we may need
844 someday to extend the object's state without breaking
845 backward-compatibility. */
846 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
847 PyErr_Format(PyExc_TypeError,
848 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
849 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
850 return NULL;
851 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200852 CHECK_EXPORTS(self);
853 /* Reset the object to its default state. This is only needed to handle
854 the case of repeated calls to __setstate__. */
855 self->string_size = 0;
856 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000857
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200858 /* Set the value of the internal buffer. If state[0] does not support the
859 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300860 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200861 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000862 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200863 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000864
865 /* Set carefully the position value. Alternatively, we could use the seek
866 method instead of modifying self->pos directly to better protect the
867 object internal state against errneous (or malicious) inputs. */
868 position_obj = PyTuple_GET_ITEM(state, 1);
869 if (!PyLong_Check(position_obj)) {
870 PyErr_Format(PyExc_TypeError,
871 "second item of state must be an integer, not %.200s",
872 Py_TYPE(position_obj)->tp_name);
873 return NULL;
874 }
875 pos = PyLong_AsSsize_t(position_obj);
876 if (pos == -1 && PyErr_Occurred())
877 return NULL;
878 if (pos < 0) {
879 PyErr_SetString(PyExc_ValueError,
880 "position value cannot be negative");
881 return NULL;
882 }
883 self->pos = pos;
884
885 /* Set the dictionary of the instance variables. */
886 dict = PyTuple_GET_ITEM(state, 2);
887 if (dict != Py_None) {
888 if (!PyDict_Check(dict)) {
889 PyErr_Format(PyExc_TypeError,
890 "third item of state should be a dict, got a %.200s",
891 Py_TYPE(dict)->tp_name);
892 return NULL;
893 }
894 if (self->dict) {
895 /* Alternatively, we could replace the internal dictionary
896 completely. However, it seems more practical to just update it. */
897 if (PyDict_Update(self->dict, dict) < 0)
898 return NULL;
899 }
900 else {
901 Py_INCREF(dict);
902 self->dict = dict;
903 }
904 }
905
906 Py_RETURN_NONE;
907}
908
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000909static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000910bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000911{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000912 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000913 if (self->exports > 0) {
914 PyErr_SetString(PyExc_SystemError,
915 "deallocated BytesIO object has exported buffers");
916 PyErr_Print();
917 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200918 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000919 Py_CLEAR(self->dict);
920 if (self->weakreflist != NULL)
921 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000922 Py_TYPE(self)->tp_free(self);
923}
924
925static PyObject *
926bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
927{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000928 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000929
930 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000931 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000932 if (self == NULL)
933 return NULL;
934
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000935 /* tp_alloc initializes all the fields to zero. So we don't have to
936 initialize them here. */
937
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200938 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000939 if (self->buf == NULL) {
940 Py_DECREF(self);
941 return PyErr_NoMemory();
942 }
943
944 return (PyObject *)self;
945}
946
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300947/*[clinic input]
948_io.BytesIO.__init__
949 initial_bytes as initvalue: object(c_default="NULL") = b''
950
951Buffered I/O implementation using an in-memory bytes buffer.
952[clinic start generated code]*/
953
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000954static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300955_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
956/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000957{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200958 /* In case, __init__ is called multiple times. */
959 self->string_size = 0;
960 self->pos = 0;
961
962 if (self->exports > 0) {
963 PyErr_SetString(PyExc_BufferError,
964 "Existing exports of data: object cannot be re-sized");
965 return -1;
966 }
967 if (initvalue && initvalue != Py_None) {
968 if (PyBytes_CheckExact(initvalue)) {
969 Py_INCREF(initvalue);
Serhiy Storchaka48842712016-04-06 09:45:48 +0300970 Py_XSETREF(self->buf, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200971 self->string_size = PyBytes_GET_SIZE(initvalue);
972 }
973 else {
974 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300975 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200976 if (res == NULL)
977 return -1;
978 Py_DECREF(res);
979 self->pos = 0;
980 }
981 }
982
983 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000984}
985
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200986static PyObject *
987bytesio_sizeof(bytesio *self, void *unused)
988{
989 Py_ssize_t res;
990
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200991 res = _PyObject_SIZE(Py_TYPE(self));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200992 if (self->buf && !SHARED_BUF(self))
993 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200994 return PyLong_FromSsize_t(res);
995}
996
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000998bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000999{
1000 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001001 return 0;
1002}
1003
1004static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001005bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001006{
1007 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001008 return 0;
1009}
1010
1011
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001012#include "clinic/bytesio.c.h"
1013
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001014static PyGetSetDef bytesio_getsetlist[] = {
1015 {"closed", (getter)bytesio_get_closed, NULL,
1016 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001017 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001018};
1019
1020static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001021 _IO_BYTESIO_READABLE_METHODDEF
1022 _IO_BYTESIO_SEEKABLE_METHODDEF
1023 _IO_BYTESIO_WRITABLE_METHODDEF
1024 _IO_BYTESIO_CLOSE_METHODDEF
1025 _IO_BYTESIO_FLUSH_METHODDEF
1026 _IO_BYTESIO_ISATTY_METHODDEF
1027 _IO_BYTESIO_TELL_METHODDEF
1028 _IO_BYTESIO_WRITE_METHODDEF
1029 _IO_BYTESIO_WRITELINES_METHODDEF
1030 _IO_BYTESIO_READ1_METHODDEF
1031 _IO_BYTESIO_READINTO_METHODDEF
1032 _IO_BYTESIO_READLINE_METHODDEF
1033 _IO_BYTESIO_READLINES_METHODDEF
1034 _IO_BYTESIO_READ_METHODDEF
1035 _IO_BYTESIO_GETBUFFER_METHODDEF
1036 _IO_BYTESIO_GETVALUE_METHODDEF
1037 _IO_BYTESIO_SEEK_METHODDEF
1038 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001039 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
1040 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +02001041 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001042 {NULL, NULL} /* sentinel */
1043};
1044
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001045PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001046 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001048 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001049 0, /*tp_itemsize*/
1050 (destructor)bytesio_dealloc, /*tp_dealloc*/
1051 0, /*tp_print*/
1052 0, /*tp_getattr*/
1053 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001054 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001055 0, /*tp_repr*/
1056 0, /*tp_as_number*/
1057 0, /*tp_as_sequence*/
1058 0, /*tp_as_mapping*/
1059 0, /*tp_hash*/
1060 0, /*tp_call*/
1061 0, /*tp_str*/
1062 0, /*tp_getattro*/
1063 0, /*tp_setattro*/
1064 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1066 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001067 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001068 (traverseproc)bytesio_traverse, /*tp_traverse*/
1069 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001070 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001071 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001072 PyObject_SelfIter, /*tp_iter*/
1073 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1074 bytesio_methods, /*tp_methods*/
1075 0, /*tp_members*/
1076 bytesio_getsetlist, /*tp_getset*/
1077 0, /*tp_base*/
1078 0, /*tp_dict*/
1079 0, /*tp_descr_get*/
1080 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001081 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001082 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001083 0, /*tp_alloc*/
1084 bytesio_new, /*tp_new*/
1085};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001086
1087
1088/*
1089 * Implementation of the small intermediate object used by getbuffer().
1090 * getbuffer() returns a memoryview over this object, which should make it
1091 * invisible from Python code.
1092 */
1093
1094static int
1095bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1096{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001097 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001098
1099 if (view == NULL) {
1100 PyErr_SetString(PyExc_BufferError,
1101 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1102 return -1;
1103 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001104 if (SHARED_BUF(b)) {
1105 if (unshare_buffer(b, b->string_size) < 0)
1106 return -1;
1107 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001108
1109 /* cannot fail if view != NULL and readonly == 0 */
1110 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001111 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001112 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001113 b->exports++;
1114 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001115}
1116
1117static void
1118bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1119{
1120 bytesio *b = (bytesio *) obj->source;
1121 b->exports--;
1122}
1123
1124static int
1125bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1126{
1127 Py_VISIT(self->source);
1128 return 0;
1129}
1130
1131static void
1132bytesiobuf_dealloc(bytesiobuf *self)
1133{
1134 Py_CLEAR(self->source);
1135 Py_TYPE(self)->tp_free(self);
1136}
1137
1138static PyBufferProcs bytesiobuf_as_buffer = {
1139 (getbufferproc) bytesiobuf_getbuffer,
1140 (releasebufferproc) bytesiobuf_releasebuffer,
1141};
1142
1143PyTypeObject _PyBytesIOBuffer_Type = {
1144 PyVarObject_HEAD_INIT(NULL, 0)
1145 "_io._BytesIOBuffer", /*tp_name*/
1146 sizeof(bytesiobuf), /*tp_basicsize*/
1147 0, /*tp_itemsize*/
1148 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1149 0, /*tp_print*/
1150 0, /*tp_getattr*/
1151 0, /*tp_setattr*/
1152 0, /*tp_reserved*/
1153 0, /*tp_repr*/
1154 0, /*tp_as_number*/
1155 0, /*tp_as_sequence*/
1156 0, /*tp_as_mapping*/
1157 0, /*tp_hash*/
1158 0, /*tp_call*/
1159 0, /*tp_str*/
1160 0, /*tp_getattro*/
1161 0, /*tp_setattro*/
1162 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1163 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1164 0, /*tp_doc*/
1165 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1166 0, /*tp_clear*/
1167 0, /*tp_richcompare*/
1168 0, /*tp_weaklistoffset*/
1169 0, /*tp_iter*/
1170 0, /*tp_iternext*/
1171 0, /*tp_methods*/
1172 0, /*tp_members*/
1173 0, /*tp_getset*/
1174 0, /*tp_base*/
1175 0, /*tp_dict*/
1176 0, /*tp_descr_get*/
1177 0, /*tp_descr_set*/
1178 0, /*tp_dictoffset*/
1179 0, /*tp_init*/
1180 0, /*tp_alloc*/
1181 0, /*tp_new*/
1182};