blob: d46430dca5dceb9e8b39f105f8514f601343a747 [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);
60
61 /* Move to the end of the line, up to the end of the string, s. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020062 start = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030063 maxlen = self->string_size - self->pos;
64 if (len < 0 || len > maxlen)
65 len = maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000066
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030067 if (len) {
68 n = memchr(start, '\n', len);
69 if (n)
70 /* Get the length from the current position to the end of
71 the line. */
72 len = n - start + 1;
73 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000074 assert(len >= 0);
75 assert(self->pos < PY_SSIZE_T_MAX - len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000076
77 return len;
78}
79
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020080/* Internal routine for detaching the shared buffer of BytesIO objects.
81 The caller should ensure that the 'size' argument is non-negative and
82 not lesser than self->string_size. Returns 0 on success, -1 otherwise. */
83static int
84unshare_buffer(bytesio *self, size_t size)
85{
86 PyObject *new_buf, *old_buf;
87 assert(SHARED_BUF(self));
88 assert(self->exports == 0);
89 assert(size >= (size_t)self->string_size);
90 new_buf = PyBytes_FromStringAndSize(NULL, size);
91 if (new_buf == NULL)
92 return -1;
93 memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
94 self->string_size);
95 old_buf = self->buf;
96 self->buf = new_buf;
97 Py_DECREF(old_buf);
98 return 0;
99}
100
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000101/* Internal routine for changing the size of the buffer of BytesIO objects.
102 The caller should ensure that the 'size' argument is non-negative. Returns
103 0 on success, -1 otherwise. */
104static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000105resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000106{
107 /* Here, unsigned types are used to avoid dealing with signed integer
108 overflow, which is undefined in C. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200109 size_t alloc = PyBytes_GET_SIZE(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000110
111 assert(self->buf != NULL);
112
113 /* For simplicity, stay in the range of the signed type. Anyway, Python
114 doesn't allow strings to be longer than this. */
115 if (size > PY_SSIZE_T_MAX)
116 goto overflow;
117
118 if (size < alloc / 2) {
119 /* Major downsize; resize down to exact size. */
120 alloc = size + 1;
121 }
122 else if (size < alloc) {
123 /* Within allocated size; quick exit */
124 return 0;
125 }
126 else if (size <= alloc * 1.125) {
127 /* Moderate upsize; overallocate similar to list_resize() */
128 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
129 }
130 else {
131 /* Major upsize; resize up to exact size */
132 alloc = size + 1;
133 }
134
135 if (alloc > ((size_t)-1) / sizeof(char))
136 goto overflow;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200137
138 if (SHARED_BUF(self)) {
139 if (unshare_buffer(self, alloc) < 0)
140 return -1;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000141 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200142 else {
143 if (_PyBytes_Resize(&self->buf, alloc) < 0)
144 return -1;
145 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000146
147 return 0;
148
149 overflow:
150 PyErr_SetString(PyExc_OverflowError,
151 "new buffer size too large");
152 return -1;
153}
154
155/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200156 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000157static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000159{
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200160 size_t endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000161 assert(self->buf != NULL);
162 assert(self->pos >= 0);
163 assert(len >= 0);
164
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200165 endpos = (size_t)self->pos + len;
166 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
167 if (resize_buffer(self, endpos) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000168 return -1;
169 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200170 else if (SHARED_BUF(self)) {
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200171 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200172 return -1;
173 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000174
175 if (self->pos > self->string_size) {
176 /* In case of overseek, pad with null bytes the buffer region between
177 the end of stream and the current position.
178
179 0 lo string_size hi
180 | |<---used--->|<----------available----------->|
181 | | <--to pad-->|<---to write---> |
182 0 buf position
183 */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200184 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000185 (self->pos - self->string_size) * sizeof(char));
186 }
187
188 /* Copy the data to the internal buffer, overwriting some of the existing
189 data if self->pos < self->string_size. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200190 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200191 self->pos = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000192
193 /* Set the new length of the internal string if it has changed. */
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200194 if ((size_t)self->string_size < endpos) {
195 self->string_size = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000196 }
197
198 return len;
199}
200
201static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000202bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000203{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000204 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000205 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206 }
207 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000208 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000209 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000210}
211
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300212/*[clinic input]
213_io.BytesIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200214
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300215Returns True if the IO object can be read.
216[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200217
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000218static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300219_io_BytesIO_readable_impl(bytesio *self)
220/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000221{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200222 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000223 Py_RETURN_TRUE;
224}
225
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300226/*[clinic input]
227_io.BytesIO.writable
228
229Returns True if the IO object can be written.
230[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000231
232static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300233_io_BytesIO_writable_impl(bytesio *self)
234/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
235{
236 CHECK_CLOSED(self);
237 Py_RETURN_TRUE;
238}
239
240/*[clinic input]
241_io.BytesIO.seekable
242
243Returns True if the IO object can be seeked.
244[clinic start generated code]*/
245
246static PyObject *
247_io_BytesIO_seekable_impl(bytesio *self)
248/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
249{
250 CHECK_CLOSED(self);
251 Py_RETURN_TRUE;
252}
253
254/*[clinic input]
255_io.BytesIO.flush
256
257Does nothing.
258[clinic start generated code]*/
259
260static PyObject *
261_io_BytesIO_flush_impl(bytesio *self)
262/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000263{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200264 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000265 Py_RETURN_NONE;
266}
267
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300268/*[clinic input]
269_io.BytesIO.getbuffer
270
271Get a read-write view over the contents of the BytesIO object.
272[clinic start generated code]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000273
274static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300275_io_BytesIO_getbuffer_impl(bytesio *self)
276/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
Antoine Pitrou972ee132010-09-06 18:48:21 +0000277{
278 PyTypeObject *type = &_PyBytesIOBuffer_Type;
279 bytesiobuf *buf;
280 PyObject *view;
281
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200282 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000283
284 buf = (bytesiobuf *) type->tp_alloc(type, 0);
285 if (buf == NULL)
286 return NULL;
287 Py_INCREF(self);
288 buf->source = self;
289 view = PyMemoryView_FromObject((PyObject *) buf);
290 Py_DECREF(buf);
291 return view;
292}
293
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300294/*[clinic input]
295_io.BytesIO.getvalue
296
297Retrieve the entire contents of the BytesIO object.
298[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000299
300static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300301_io_BytesIO_getvalue_impl(bytesio *self)
302/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000303{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200304 CHECK_CLOSED(self);
305 if (self->string_size <= 1 || self->exports > 0)
306 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
307 self->string_size);
308
309 if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
310 if (SHARED_BUF(self)) {
311 if (unshare_buffer(self, self->string_size) < 0)
312 return NULL;
313 }
314 else {
315 if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
316 return NULL;
317 }
318 }
319 Py_INCREF(self->buf);
320 return self->buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000321}
322
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300323/*[clinic input]
324_io.BytesIO.isatty
325
326Always returns False.
327
328BytesIO objects are not connected to a TTY-like device.
329[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000330
331static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300332_io_BytesIO_isatty_impl(bytesio *self)
333/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000334{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200335 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000336 Py_RETURN_FALSE;
337}
338
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300339/*[clinic input]
340_io.BytesIO.tell
341
342Current file position, an integer.
343[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000344
345static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300346_io_BytesIO_tell_impl(bytesio *self)
347/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000348{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200349 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000350 return PyLong_FromSsize_t(self->pos);
351}
352
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200353static PyObject *
354read_bytes(bytesio *self, Py_ssize_t size)
355{
356 char *output;
357
358 assert(self->buf != NULL);
Serhiy Storchakab9765ee2015-02-03 14:57:49 +0200359 assert(size <= self->string_size);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200360 if (size > 1 &&
361 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
362 self->exports == 0) {
363 self->pos += size;
364 Py_INCREF(self->buf);
365 return self->buf;
366 }
367
368 output = PyBytes_AS_STRING(self->buf) + self->pos;
369 self->pos += size;
370 return PyBytes_FromStringAndSize(output, size);
371}
372
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300373/*[clinic input]
374_io.BytesIO.read
375 size as arg: object = None
376 /
377
378Read at most size bytes, returned as a bytes object.
379
380If the size argument is negative, read until EOF is reached.
381Return an empty bytes object at EOF.
382[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000383
384static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300385_io_BytesIO_read_impl(bytesio *self, PyObject *arg)
386/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000387{
388 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000389
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200390 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000391
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000392 if (PyLong_Check(arg)) {
393 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000394 if (size == -1 && PyErr_Occurred())
395 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000396 }
397 else if (arg == Py_None) {
398 /* Read until EOF is reached, by default. */
399 size = -1;
400 }
401 else {
402 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
403 Py_TYPE(arg)->tp_name);
404 return NULL;
405 }
406
407 /* adjust invalid sizes */
408 n = self->string_size - self->pos;
409 if (size < 0 || size > n) {
410 size = n;
411 if (size < 0)
412 size = 0;
413 }
414
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200415 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000416}
417
418
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300419/*[clinic input]
420_io.BytesIO.read1
421 size: object
422 /
423
424Read at most size bytes, returned as a bytes object.
425
426If the size argument is negative or omitted, read until EOF is reached.
427Return an empty bytes object at EOF.
428[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000429
430static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300431_io_BytesIO_read1(bytesio *self, PyObject *size)
432/*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000433{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300434 return _io_BytesIO_read_impl(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000435}
436
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300437/*[clinic input]
438_io.BytesIO.readline
439 size as arg: object = None
440 /
441
442Next line from the file, as a bytes object.
443
444Retain newline. A non-negative size argument limits the maximum
445number of bytes to return (an incomplete line may be returned then).
446Return an empty bytes object at EOF.
447[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000448
449static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300450_io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
451/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000452{
453 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000454
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200455 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000456
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000457 if (PyLong_Check(arg)) {
458 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000459 if (size == -1 && PyErr_Occurred())
460 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000461 }
462 else if (arg == Py_None) {
463 /* No size limit, by default. */
464 size = -1;
465 }
466 else {
467 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
468 Py_TYPE(arg)->tp_name);
469 return NULL;
470 }
471
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300472 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000473
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200474 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000475}
476
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300477/*[clinic input]
478_io.BytesIO.readlines
479 size as arg: object = None
480 /
481
482List of bytes objects, each a line from the file.
483
484Call readline() repeatedly and return a list of the lines so read.
485The optional size argument, if given, is an approximate bound on the
486total number of bytes in the lines returned.
487[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000488
489static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300490_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
491/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000492{
493 Py_ssize_t maxsize, size, n;
494 PyObject *result, *line;
495 char *output;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000496
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200497 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000498
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000499 if (PyLong_Check(arg)) {
500 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000501 if (maxsize == -1 && PyErr_Occurred())
502 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000503 }
504 else if (arg == Py_None) {
505 /* No size limit, by default. */
506 maxsize = -1;
507 }
508 else {
509 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
510 Py_TYPE(arg)->tp_name);
511 return NULL;
512 }
513
514 size = 0;
515 result = PyList_New(0);
516 if (!result)
517 return NULL;
518
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200519 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300520 while ((n = scan_eol(self, -1)) != 0) {
521 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000522 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000523 if (!line)
524 goto on_error;
525 if (PyList_Append(result, line) == -1) {
526 Py_DECREF(line);
527 goto on_error;
528 }
529 Py_DECREF(line);
530 size += n;
531 if (maxsize > 0 && size >= maxsize)
532 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300533 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000534 }
535 return result;
536
537 on_error:
538 Py_DECREF(result);
539 return NULL;
540}
541
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300542/*[clinic input]
543_io.BytesIO.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700544 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300545 /
546
547Read up to len(buffer) bytes into buffer.
548
549Returns number of bytes read (0 for EOF), or None if the object
550is set not to block as has no data to read.
551[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000552
553static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300554_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700555/*[clinic end generated code: output=a5d407217dcf0639 input=71581f32635c3a31]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000556{
Benjamin Petersonfa735552010-11-20 17:24:04 +0000557 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000558
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200559 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000560
Benjamin Petersonfa735552010-11-20 17:24:04 +0000561 /* adjust invalid sizes */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300562 len = buffer->len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000563 n = self->string_size - self->pos;
564 if (len > n) {
565 len = n;
566 if (len < 0)
567 len = 0;
568 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000569
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300570 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000571 assert(self->pos + len < PY_SSIZE_T_MAX);
572 assert(len >= 0);
573 self->pos += len;
574
575 return PyLong_FromSsize_t(len);
576}
577
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300578/*[clinic input]
579_io.BytesIO.truncate
580 size as arg: object = None
581 /
582
583Truncate the file to at most size bytes.
584
585Size defaults to the current file position, as returned by tell().
586The current file position is unchanged. Returns the new size.
587[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000588
589static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300590_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
591/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000592{
593 Py_ssize_t size;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000594
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200595 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000596 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000597
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000598 if (PyLong_Check(arg)) {
599 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000600 if (size == -1 && PyErr_Occurred())
601 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000602 }
603 else if (arg == Py_None) {
604 /* Truncate to current position if no argument is passed. */
605 size = self->pos;
606 }
607 else {
608 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
609 Py_TYPE(arg)->tp_name);
610 return NULL;
611 }
612
613 if (size < 0) {
614 PyErr_Format(PyExc_ValueError,
615 "negative size value %zd", size);
616 return NULL;
617 }
618
619 if (size < self->string_size) {
620 self->string_size = size;
621 if (resize_buffer(self, size) < 0)
622 return NULL;
623 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000624
625 return PyLong_FromSsize_t(size);
626}
627
628static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000629bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000630{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000631 Py_ssize_t n;
632
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200633 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000634
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300635 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000636
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300637 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000638 return NULL;
639
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200640 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000641}
642
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300643/*[clinic input]
644_io.BytesIO.seek
645 pos: Py_ssize_t
646 whence: int = 0
647 /
648
649Change stream position.
650
651Seek to byte offset pos relative to position indicated by whence:
652 0 Start of stream (the default). pos should be >= 0;
653 1 Current position - pos may be negative;
654 2 End of stream - pos usually negative.
655Returns the new absolute position.
656[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000657
658static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300659_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
660/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000661{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200662 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000663
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300664 if (pos < 0 && whence == 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000665 PyErr_Format(PyExc_ValueError,
666 "negative seek value %zd", pos);
667 return NULL;
668 }
669
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300670 /* whence = 0: offset relative to beginning of the string.
671 whence = 1: offset relative to current position.
672 whence = 2: offset relative the end of the string. */
673 if (whence == 1) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000674 if (pos > PY_SSIZE_T_MAX - self->pos) {
675 PyErr_SetString(PyExc_OverflowError,
676 "new position too large");
677 return NULL;
678 }
679 pos += self->pos;
680 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300681 else if (whence == 2) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000682 if (pos > PY_SSIZE_T_MAX - self->string_size) {
683 PyErr_SetString(PyExc_OverflowError,
684 "new position too large");
685 return NULL;
686 }
687 pos += self->string_size;
688 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300689 else if (whence != 0) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000690 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300691 "invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000692 return NULL;
693 }
694
695 if (pos < 0)
696 pos = 0;
697 self->pos = pos;
698
699 return PyLong_FromSsize_t(self->pos);
700}
701
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300702/*[clinic input]
703_io.BytesIO.write
704 b: object
705 /
706
707Write bytes to file.
708
709Return the number of bytes written.
710[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000711
712static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300713_io_BytesIO_write(bytesio *self, PyObject *b)
714/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000715{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000716 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000717 Py_buffer buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000718
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200719 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000720 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000721
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300722 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000723 return NULL;
724
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000725 if (buf.len != 0)
726 n = write_bytes(self, buf.buf, buf.len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000727
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000728 PyBuffer_Release(&buf);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300729 return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000730}
731
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300732/*[clinic input]
733_io.BytesIO.writelines
734 lines: object
735 /
736
737Write lines to the file.
738
739Note that newlines are not added. lines can be any iterable object
740producing bytes-like objects. This is equivalent to calling write() for
741each element.
742[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000743
744static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300745_io_BytesIO_writelines(bytesio *self, PyObject *lines)
746/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000747{
748 PyObject *it, *item;
749 PyObject *ret;
750
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200751 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000752
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300753 it = PyObject_GetIter(lines);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000754 if (it == NULL)
755 return NULL;
756
757 while ((item = PyIter_Next(it)) != NULL) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300758 ret = _io_BytesIO_write(self, item);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000759 Py_DECREF(item);
760 if (ret == NULL) {
761 Py_DECREF(it);
762 return NULL;
763 }
764 Py_DECREF(ret);
765 }
766 Py_DECREF(it);
767
768 /* See if PyIter_Next failed */
769 if (PyErr_Occurred())
770 return NULL;
771
772 Py_RETURN_NONE;
773}
774
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300775/*[clinic input]
776_io.BytesIO.close
777
778Disable all I/O operations.
779[clinic start generated code]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000780
781static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300782_io_BytesIO_close_impl(bytesio *self)
783/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000784{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200785 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200786 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000787 Py_RETURN_NONE;
788}
789
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000790/* Pickling support.
791
792 Note that only pickle protocol 2 and onward are supported since we use
793 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
794
795 Providing support for protocol < 2 would require the __reduce_ex__ method
796 which is notably long-winded when defined properly.
797
798 For BytesIO, the implementation would similar to one coded for
799 object.__reduce_ex__, but slightly less general. To be more specific, we
800 could call bytesio_getstate directly and avoid checking for the presence of
801 a fallback __reduce__ method. However, we would still need a __newobj__
802 function to use the efficient instance representation of PEP 307.
803 */
804
805static PyObject *
806bytesio_getstate(bytesio *self)
807{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300808 PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000809 PyObject *dict;
810 PyObject *state;
811
812 if (initvalue == NULL)
813 return NULL;
814 if (self->dict == NULL) {
815 Py_INCREF(Py_None);
816 dict = Py_None;
817 }
818 else {
819 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200820 if (dict == NULL) {
821 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000822 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200823 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000824 }
825
826 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
827 Py_DECREF(initvalue);
828 return state;
829}
830
831static PyObject *
832bytesio_setstate(bytesio *self, PyObject *state)
833{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200834 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000835 PyObject *position_obj;
836 PyObject *dict;
837 Py_ssize_t pos;
838
839 assert(state != NULL);
840
841 /* We allow the state tuple to be longer than 3, because we may need
842 someday to extend the object's state without breaking
843 backward-compatibility. */
844 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
845 PyErr_Format(PyExc_TypeError,
846 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
847 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
848 return NULL;
849 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200850 CHECK_EXPORTS(self);
851 /* Reset the object to its default state. This is only needed to handle
852 the case of repeated calls to __setstate__. */
853 self->string_size = 0;
854 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000855
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200856 /* Set the value of the internal buffer. If state[0] does not support the
857 buffer protocol, bytesio_write will raise the appropriate TypeError. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300858 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200859 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000860 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200861 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000862
863 /* Set carefully the position value. Alternatively, we could use the seek
864 method instead of modifying self->pos directly to better protect the
865 object internal state against errneous (or malicious) inputs. */
866 position_obj = PyTuple_GET_ITEM(state, 1);
867 if (!PyLong_Check(position_obj)) {
868 PyErr_Format(PyExc_TypeError,
869 "second item of state must be an integer, not %.200s",
870 Py_TYPE(position_obj)->tp_name);
871 return NULL;
872 }
873 pos = PyLong_AsSsize_t(position_obj);
874 if (pos == -1 && PyErr_Occurred())
875 return NULL;
876 if (pos < 0) {
877 PyErr_SetString(PyExc_ValueError,
878 "position value cannot be negative");
879 return NULL;
880 }
881 self->pos = pos;
882
883 /* Set the dictionary of the instance variables. */
884 dict = PyTuple_GET_ITEM(state, 2);
885 if (dict != Py_None) {
886 if (!PyDict_Check(dict)) {
887 PyErr_Format(PyExc_TypeError,
888 "third item of state should be a dict, got a %.200s",
889 Py_TYPE(dict)->tp_name);
890 return NULL;
891 }
892 if (self->dict) {
893 /* Alternatively, we could replace the internal dictionary
894 completely. However, it seems more practical to just update it. */
895 if (PyDict_Update(self->dict, dict) < 0)
896 return NULL;
897 }
898 else {
899 Py_INCREF(dict);
900 self->dict = dict;
901 }
902 }
903
904 Py_RETURN_NONE;
905}
906
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000907static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000908bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000909{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000910 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000911 if (self->exports > 0) {
912 PyErr_SetString(PyExc_SystemError,
913 "deallocated BytesIO object has exported buffers");
914 PyErr_Print();
915 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200916 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000917 Py_CLEAR(self->dict);
918 if (self->weakreflist != NULL)
919 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000920 Py_TYPE(self)->tp_free(self);
921}
922
923static PyObject *
924bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
925{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000926 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000927
928 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000929 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000930 if (self == NULL)
931 return NULL;
932
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000933 /* tp_alloc initializes all the fields to zero. So we don't have to
934 initialize them here. */
935
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200936 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000937 if (self->buf == NULL) {
938 Py_DECREF(self);
939 return PyErr_NoMemory();
940 }
941
942 return (PyObject *)self;
943}
944
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300945/*[clinic input]
946_io.BytesIO.__init__
947 initial_bytes as initvalue: object(c_default="NULL") = b''
948
949Buffered I/O implementation using an in-memory bytes buffer.
950[clinic start generated code]*/
951
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000952static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300953_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
954/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000955{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200956 /* In case, __init__ is called multiple times. */
957 self->string_size = 0;
958 self->pos = 0;
959
960 if (self->exports > 0) {
961 PyErr_SetString(PyExc_BufferError,
962 "Existing exports of data: object cannot be re-sized");
963 return -1;
964 }
965 if (initvalue && initvalue != Py_None) {
966 if (PyBytes_CheckExact(initvalue)) {
967 Py_INCREF(initvalue);
968 Py_XDECREF(self->buf);
969 self->buf = initvalue;
970 self->string_size = PyBytes_GET_SIZE(initvalue);
971 }
972 else {
973 PyObject *res;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300974 res = _io_BytesIO_write(self, initvalue);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200975 if (res == NULL)
976 return -1;
977 Py_DECREF(res);
978 self->pos = 0;
979 }
980 }
981
982 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000983}
984
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200985static PyObject *
986bytesio_sizeof(bytesio *self, void *unused)
987{
988 Py_ssize_t res;
989
990 res = sizeof(bytesio);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200991 if (self->buf && !SHARED_BUF(self))
992 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200993 return PyLong_FromSsize_t(res);
994}
995
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000996static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000997bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000998{
999 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001000 return 0;
1001}
1002
1003static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001004bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001005{
1006 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001007 return 0;
1008}
1009
1010
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001011#include "clinic/bytesio.c.h"
1012
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001013static PyGetSetDef bytesio_getsetlist[] = {
1014 {"closed", (getter)bytesio_get_closed, NULL,
1015 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001016 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001017};
1018
1019static struct PyMethodDef bytesio_methods[] = {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001020 _IO_BYTESIO_READABLE_METHODDEF
1021 _IO_BYTESIO_SEEKABLE_METHODDEF
1022 _IO_BYTESIO_WRITABLE_METHODDEF
1023 _IO_BYTESIO_CLOSE_METHODDEF
1024 _IO_BYTESIO_FLUSH_METHODDEF
1025 _IO_BYTESIO_ISATTY_METHODDEF
1026 _IO_BYTESIO_TELL_METHODDEF
1027 _IO_BYTESIO_WRITE_METHODDEF
1028 _IO_BYTESIO_WRITELINES_METHODDEF
1029 _IO_BYTESIO_READ1_METHODDEF
1030 _IO_BYTESIO_READINTO_METHODDEF
1031 _IO_BYTESIO_READLINE_METHODDEF
1032 _IO_BYTESIO_READLINES_METHODDEF
1033 _IO_BYTESIO_READ_METHODDEF
1034 _IO_BYTESIO_GETBUFFER_METHODDEF
1035 _IO_BYTESIO_GETVALUE_METHODDEF
1036 _IO_BYTESIO_SEEK_METHODDEF
1037 _IO_BYTESIO_TRUNCATE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001038 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
1039 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +02001040 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001041 {NULL, NULL} /* sentinel */
1042};
1043
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001045 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001047 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001048 0, /*tp_itemsize*/
1049 (destructor)bytesio_dealloc, /*tp_dealloc*/
1050 0, /*tp_print*/
1051 0, /*tp_getattr*/
1052 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001053 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001054 0, /*tp_repr*/
1055 0, /*tp_as_number*/
1056 0, /*tp_as_sequence*/
1057 0, /*tp_as_mapping*/
1058 0, /*tp_hash*/
1059 0, /*tp_call*/
1060 0, /*tp_str*/
1061 0, /*tp_getattro*/
1062 0, /*tp_setattro*/
1063 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001064 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1065 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001066 _io_BytesIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067 (traverseproc)bytesio_traverse, /*tp_traverse*/
1068 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001069 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001070 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001071 PyObject_SelfIter, /*tp_iter*/
1072 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1073 bytesio_methods, /*tp_methods*/
1074 0, /*tp_members*/
1075 bytesio_getsetlist, /*tp_getset*/
1076 0, /*tp_base*/
1077 0, /*tp_dict*/
1078 0, /*tp_descr_get*/
1079 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001080 offsetof(bytesio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001081 _io_BytesIO___init__, /*tp_init*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001082 0, /*tp_alloc*/
1083 bytesio_new, /*tp_new*/
1084};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001085
1086
1087/*
1088 * Implementation of the small intermediate object used by getbuffer().
1089 * getbuffer() returns a memoryview over this object, which should make it
1090 * invisible from Python code.
1091 */
1092
1093static int
1094bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1095{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001096 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001097
1098 if (view == NULL) {
1099 PyErr_SetString(PyExc_BufferError,
1100 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1101 return -1;
1102 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001103 if (SHARED_BUF(b)) {
1104 if (unshare_buffer(b, b->string_size) < 0)
1105 return -1;
1106 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001107
1108 /* cannot fail if view != NULL and readonly == 0 */
1109 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001110 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001111 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001112 b->exports++;
1113 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001114}
1115
1116static void
1117bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1118{
1119 bytesio *b = (bytesio *) obj->source;
1120 b->exports--;
1121}
1122
1123static int
1124bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1125{
1126 Py_VISIT(self->source);
1127 return 0;
1128}
1129
1130static void
1131bytesiobuf_dealloc(bytesiobuf *self)
1132{
1133 Py_CLEAR(self->source);
1134 Py_TYPE(self)->tp_free(self);
1135}
1136
1137static PyBufferProcs bytesiobuf_as_buffer = {
1138 (getbufferproc) bytesiobuf_getbuffer,
1139 (releasebufferproc) bytesiobuf_releasebuffer,
1140};
1141
1142PyTypeObject _PyBytesIOBuffer_Type = {
1143 PyVarObject_HEAD_INIT(NULL, 0)
1144 "_io._BytesIOBuffer", /*tp_name*/
1145 sizeof(bytesiobuf), /*tp_basicsize*/
1146 0, /*tp_itemsize*/
1147 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1148 0, /*tp_print*/
1149 0, /*tp_getattr*/
1150 0, /*tp_setattr*/
1151 0, /*tp_reserved*/
1152 0, /*tp_repr*/
1153 0, /*tp_as_number*/
1154 0, /*tp_as_sequence*/
1155 0, /*tp_as_mapping*/
1156 0, /*tp_hash*/
1157 0, /*tp_call*/
1158 0, /*tp_str*/
1159 0, /*tp_getattro*/
1160 0, /*tp_setattro*/
1161 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1162 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1163 0, /*tp_doc*/
1164 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1165 0, /*tp_clear*/
1166 0, /*tp_richcompare*/
1167 0, /*tp_weaklistoffset*/
1168 0, /*tp_iter*/
1169 0, /*tp_iternext*/
1170 0, /*tp_methods*/
1171 0, /*tp_members*/
1172 0, /*tp_getset*/
1173 0, /*tp_base*/
1174 0, /*tp_dict*/
1175 0, /*tp_descr_get*/
1176 0, /*tp_descr_set*/
1177 0, /*tp_dictoffset*/
1178 0, /*tp_init*/
1179 0, /*tp_alloc*/
1180 0, /*tp_new*/
1181};