blob: fc4ea74b23f370055db474ec26213319dacce33e [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
5typedef struct {
6 PyObject_HEAD
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02007 PyObject *buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00008 Py_ssize_t pos;
9 Py_ssize_t string_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000010 PyObject *dict;
11 PyObject *weakreflist;
Antoine Pitrou972ee132010-09-06 18:48:21 +000012 Py_ssize_t exports;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000013} bytesio;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000014
Antoine Pitrou972ee132010-09-06 18:48:21 +000015typedef struct {
16 PyObject_HEAD
17 bytesio *source;
18} bytesiobuf;
19
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020020/* The bytesio object can be in three states:
21 * Py_REFCNT(buf) == 1, exports == 0.
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020022 * Py_REFCNT(buf) > 1. exports == 0,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020023 first modification or export causes the internal buffer copying.
24 * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden.
25*/
Antoine Pitrou972ee132010-09-06 18:48:21 +000026
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020027#define CHECK_CLOSED(self) \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000028 if ((self)->buf == NULL) { \
29 PyErr_SetString(PyExc_ValueError, \
30 "I/O operation on closed file."); \
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020031 return NULL; \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000032 }
33
Antoine Pitrou972ee132010-09-06 18:48:21 +000034#define CHECK_EXPORTS(self) \
35 if ((self)->exports > 0) { \
36 PyErr_SetString(PyExc_BufferError, \
37 "Existing exports of data: object cannot be re-sized"); \
38 return NULL; \
39 }
40
Serhiy Storchaka38c30e62015-02-03 18:51:58 +020041#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
Antoine Pitroucc66a732014-07-29 19:41:11 -040042
Antoine Pitrou972ee132010-09-06 18:48:21 +000043
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000044/* Internal routine to get a line from the buffer of a BytesIO
45 object. Returns the length between the current position to the
46 next newline character. */
47static Py_ssize_t
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030048scan_eol(bytesio *self, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000049{
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030050 const char *start, *n;
51 Py_ssize_t maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000052
53 assert(self->buf != NULL);
54
55 /* Move to the end of the line, up to the end of the string, s. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020056 start = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030057 maxlen = self->string_size - self->pos;
58 if (len < 0 || len > maxlen)
59 len = maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000060
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030061 if (len) {
62 n = memchr(start, '\n', len);
63 if (n)
64 /* Get the length from the current position to the end of
65 the line. */
66 len = n - start + 1;
67 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000068 assert(len >= 0);
69 assert(self->pos < PY_SSIZE_T_MAX - len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000070
71 return len;
72}
73
Serhiy Storchaka87d0b452015-02-03 11:30:10 +020074/* Internal routine for detaching the shared buffer of BytesIO objects.
75 The caller should ensure that the 'size' argument is non-negative and
76 not lesser than self->string_size. Returns 0 on success, -1 otherwise. */
77static int
78unshare_buffer(bytesio *self, size_t size)
79{
80 PyObject *new_buf, *old_buf;
81 assert(SHARED_BUF(self));
82 assert(self->exports == 0);
83 assert(size >= (size_t)self->string_size);
84 new_buf = PyBytes_FromStringAndSize(NULL, size);
85 if (new_buf == NULL)
86 return -1;
87 memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
88 self->string_size);
89 old_buf = self->buf;
90 self->buf = new_buf;
91 Py_DECREF(old_buf);
92 return 0;
93}
94
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000095/* Internal routine for changing the size of the buffer of BytesIO objects.
96 The caller should ensure that the 'size' argument is non-negative. Returns
97 0 on success, -1 otherwise. */
98static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000100{
101 /* Here, unsigned types are used to avoid dealing with signed integer
102 overflow, which is undefined in C. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200103 size_t alloc = PyBytes_GET_SIZE(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000104
105 assert(self->buf != NULL);
106
107 /* For simplicity, stay in the range of the signed type. Anyway, Python
108 doesn't allow strings to be longer than this. */
109 if (size > PY_SSIZE_T_MAX)
110 goto overflow;
111
112 if (size < alloc / 2) {
113 /* Major downsize; resize down to exact size. */
114 alloc = size + 1;
115 }
116 else if (size < alloc) {
117 /* Within allocated size; quick exit */
118 return 0;
119 }
120 else if (size <= alloc * 1.125) {
121 /* Moderate upsize; overallocate similar to list_resize() */
122 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
123 }
124 else {
125 /* Major upsize; resize up to exact size */
126 alloc = size + 1;
127 }
128
129 if (alloc > ((size_t)-1) / sizeof(char))
130 goto overflow;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200131
132 if (SHARED_BUF(self)) {
133 if (unshare_buffer(self, alloc) < 0)
134 return -1;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000135 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200136 else {
137 if (_PyBytes_Resize(&self->buf, alloc) < 0)
138 return -1;
139 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000140
141 return 0;
142
143 overflow:
144 PyErr_SetString(PyExc_OverflowError,
145 "new buffer size too large");
146 return -1;
147}
148
149/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200150 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000151static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000152write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000153{
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200154 size_t endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000155 assert(self->buf != NULL);
156 assert(self->pos >= 0);
157 assert(len >= 0);
158
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200159 endpos = (size_t)self->pos + len;
160 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
161 if (resize_buffer(self, endpos) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000162 return -1;
163 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200164 else if (SHARED_BUF(self)) {
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200165 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200166 return -1;
167 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000168
169 if (self->pos > self->string_size) {
170 /* In case of overseek, pad with null bytes the buffer region between
171 the end of stream and the current position.
172
173 0 lo string_size hi
174 | |<---used--->|<----------available----------->|
175 | | <--to pad-->|<---to write---> |
176 0 buf position
177 */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200178 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000179 (self->pos - self->string_size) * sizeof(char));
180 }
181
182 /* Copy the data to the internal buffer, overwriting some of the existing
183 data if self->pos < self->string_size. */
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200184 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200185 self->pos = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000186
187 /* Set the new length of the internal string if it has changed. */
Serhiy Storchaka38c30e62015-02-03 18:51:58 +0200188 if ((size_t)self->string_size < endpos) {
189 self->string_size = endpos;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000190 }
191
192 return len;
193}
194
195static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000197{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000198 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000199 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000200 }
201 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000202 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000203 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000204}
205
Antoine Pitrou1d857452012-09-05 20:11:49 +0200206PyDoc_STRVAR(readable_doc,
207"readable() -> bool. Returns True if the IO object can be read.");
208
209PyDoc_STRVAR(writable_doc,
210"writable() -> bool. Returns True if the IO object can be written.");
211
212PyDoc_STRVAR(seekable_doc,
213"seekable() -> bool. Returns True if the IO object can be seeked.");
214
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000215/* Generic getter for the writable, readable and seekable properties */
216static PyObject *
Antoine Pitrou1d857452012-09-05 20:11:49 +0200217return_not_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000218{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200219 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000220 Py_RETURN_TRUE;
221}
222
223PyDoc_STRVAR(flush_doc,
224"flush() -> None. Does nothing.");
225
226static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000227bytesio_flush(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000228{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200229 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000230 Py_RETURN_NONE;
231}
232
Antoine Pitrou972ee132010-09-06 18:48:21 +0000233PyDoc_STRVAR(getbuffer_doc,
234"getbuffer() -> bytes.\n"
235"\n"
236"Get a read-write view over the contents of the BytesIO object.");
237
238static PyObject *
239bytesio_getbuffer(bytesio *self)
240{
241 PyTypeObject *type = &_PyBytesIOBuffer_Type;
242 bytesiobuf *buf;
243 PyObject *view;
244
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200245 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000246
247 buf = (bytesiobuf *) type->tp_alloc(type, 0);
248 if (buf == NULL)
249 return NULL;
250 Py_INCREF(self);
251 buf->source = self;
252 view = PyMemoryView_FromObject((PyObject *) buf);
253 Py_DECREF(buf);
254 return view;
255}
256
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000257PyDoc_STRVAR(getval_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000258"getvalue() -> bytes.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000259"\n"
260"Retrieve the entire contents of the BytesIO object.");
261
262static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000263bytesio_getvalue(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000264{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200265 CHECK_CLOSED(self);
266 if (self->string_size <= 1 || self->exports > 0)
267 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
268 self->string_size);
269
270 if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
271 if (SHARED_BUF(self)) {
272 if (unshare_buffer(self, self->string_size) < 0)
273 return NULL;
274 }
275 else {
276 if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
277 return NULL;
278 }
279 }
280 Py_INCREF(self->buf);
281 return self->buf;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000282}
283
284PyDoc_STRVAR(isatty_doc,
285"isatty() -> False.\n"
286"\n"
287"Always returns False since BytesIO objects are not connected\n"
288"to a tty-like device.");
289
290static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000291bytesio_isatty(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000292{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200293 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000294 Py_RETURN_FALSE;
295}
296
297PyDoc_STRVAR(tell_doc,
298"tell() -> current file position, an integer\n");
299
300static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000301bytesio_tell(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000302{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200303 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000304 return PyLong_FromSsize_t(self->pos);
305}
306
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200307static PyObject *
308read_bytes(bytesio *self, Py_ssize_t size)
309{
310 char *output;
311
312 assert(self->buf != NULL);
Serhiy Storchakab9765ee2015-02-03 14:57:49 +0200313 assert(size <= self->string_size);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200314 if (size > 1 &&
315 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
316 self->exports == 0) {
317 self->pos += size;
318 Py_INCREF(self->buf);
319 return self->buf;
320 }
321
322 output = PyBytes_AS_STRING(self->buf) + self->pos;
323 self->pos += size;
324 return PyBytes_FromStringAndSize(output, size);
325}
326
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000327PyDoc_STRVAR(read_doc,
328"read([size]) -> read at most size bytes, returned as a string.\n"
329"\n"
330"If the size argument is negative, read until EOF is reached.\n"
331"Return an empty string at EOF.");
332
333static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000334bytesio_read(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000335{
336 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000337 PyObject *arg = Py_None;
338
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200339 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000340
341 if (!PyArg_ParseTuple(args, "|O:read", &arg))
342 return NULL;
343
344 if (PyLong_Check(arg)) {
345 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000346 if (size == -1 && PyErr_Occurred())
347 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000348 }
349 else if (arg == Py_None) {
350 /* Read until EOF is reached, by default. */
351 size = -1;
352 }
353 else {
354 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
355 Py_TYPE(arg)->tp_name);
356 return NULL;
357 }
358
359 /* adjust invalid sizes */
360 n = self->string_size - self->pos;
361 if (size < 0 || size > n) {
362 size = n;
363 if (size < 0)
364 size = 0;
365 }
366
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200367 return read_bytes(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000368}
369
370
371PyDoc_STRVAR(read1_doc,
372"read1(size) -> read at most size bytes, returned as a string.\n"
373"\n"
374"If the size argument is negative or omitted, read until EOF is reached.\n"
375"Return an empty string at EOF.");
376
377static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000378bytesio_read1(bytesio *self, PyObject *n)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000379{
380 PyObject *arg, *res;
381
382 arg = PyTuple_Pack(1, n);
383 if (arg == NULL)
384 return NULL;
385 res = bytesio_read(self, arg);
386 Py_DECREF(arg);
387 return res;
388}
389
390PyDoc_STRVAR(readline_doc,
391"readline([size]) -> next line from the file, as a string.\n"
392"\n"
393"Retain newline. A non-negative size argument limits the maximum\n"
394"number of bytes to return (an incomplete line may be returned then).\n"
395"Return an empty string at EOF.\n");
396
397static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000398bytesio_readline(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000399{
400 Py_ssize_t size, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000401 PyObject *arg = Py_None;
402
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200403 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000404
405 if (!PyArg_ParseTuple(args, "|O:readline", &arg))
406 return NULL;
407
408 if (PyLong_Check(arg)) {
409 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000410 if (size == -1 && PyErr_Occurred())
411 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000412 }
413 else if (arg == Py_None) {
414 /* No size limit, by default. */
415 size = -1;
416 }
417 else {
418 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
419 Py_TYPE(arg)->tp_name);
420 return NULL;
421 }
422
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300423 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000424
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200425 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000426}
427
428PyDoc_STRVAR(readlines_doc,
429"readlines([size]) -> list of strings, each a line from the file.\n"
430"\n"
431"Call readline() repeatedly and return a list of the lines so read.\n"
432"The optional size argument, if given, is an approximate bound on the\n"
433"total number of bytes in the lines returned.\n");
434
435static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000436bytesio_readlines(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000437{
438 Py_ssize_t maxsize, size, n;
439 PyObject *result, *line;
440 char *output;
441 PyObject *arg = Py_None;
442
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200443 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000444
445 if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
446 return NULL;
447
448 if (PyLong_Check(arg)) {
449 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000450 if (maxsize == -1 && PyErr_Occurred())
451 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000452 }
453 else if (arg == Py_None) {
454 /* No size limit, by default. */
455 maxsize = -1;
456 }
457 else {
458 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
459 Py_TYPE(arg)->tp_name);
460 return NULL;
461 }
462
463 size = 0;
464 result = PyList_New(0);
465 if (!result)
466 return NULL;
467
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200468 output = PyBytes_AS_STRING(self->buf) + self->pos;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300469 while ((n = scan_eol(self, -1)) != 0) {
470 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000471 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000472 if (!line)
473 goto on_error;
474 if (PyList_Append(result, line) == -1) {
475 Py_DECREF(line);
476 goto on_error;
477 }
478 Py_DECREF(line);
479 size += n;
480 if (maxsize > 0 && size >= maxsize)
481 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300482 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000483 }
484 return result;
485
486 on_error:
487 Py_DECREF(result);
488 return NULL;
489}
490
491PyDoc_STRVAR(readinto_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000492"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000493"\n"
494"Returns number of bytes read (0 for EOF), or None if the object\n"
495"is set not to block as has no data to read.");
496
497static PyObject *
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200498bytesio_readinto(bytesio *self, PyObject *arg)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000499{
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200500 Py_buffer buffer;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000501 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000502
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200503 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000504
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200505 if (!PyArg_Parse(arg, "w*", &buffer))
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000506 return NULL;
507
Benjamin Petersonfa735552010-11-20 17:24:04 +0000508 /* adjust invalid sizes */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200509 len = buffer.len;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000510 n = self->string_size - self->pos;
511 if (len > n) {
512 len = n;
513 if (len < 0)
514 len = 0;
515 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000516
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200517 memcpy(buffer.buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000518 assert(self->pos + len < PY_SSIZE_T_MAX);
519 assert(len >= 0);
520 self->pos += len;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200521 PyBuffer_Release(&buffer);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000522
523 return PyLong_FromSsize_t(len);
524}
525
526PyDoc_STRVAR(truncate_doc,
527"truncate([size]) -> int. Truncate the file to at most size bytes.\n"
528"\n"
529"Size defaults to the current file position, as returned by tell().\n"
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000530"The current file position is unchanged. Returns the new size.\n");
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000531
532static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000533bytesio_truncate(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000534{
535 Py_ssize_t size;
536 PyObject *arg = Py_None;
537
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200538 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000539 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000540
541 if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
542 return NULL;
543
544 if (PyLong_Check(arg)) {
545 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000546 if (size == -1 && PyErr_Occurred())
547 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000548 }
549 else if (arg == Py_None) {
550 /* Truncate to current position if no argument is passed. */
551 size = self->pos;
552 }
553 else {
554 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
555 Py_TYPE(arg)->tp_name);
556 return NULL;
557 }
558
559 if (size < 0) {
560 PyErr_Format(PyExc_ValueError,
561 "negative size value %zd", size);
562 return NULL;
563 }
564
565 if (size < self->string_size) {
566 self->string_size = size;
567 if (resize_buffer(self, size) < 0)
568 return NULL;
569 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000570
571 return PyLong_FromSsize_t(size);
572}
573
574static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000575bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000576{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000577 Py_ssize_t n;
578
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200579 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000580
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300581 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000582
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300583 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000584 return NULL;
585
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200586 return read_bytes(self, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000587}
588
589PyDoc_STRVAR(seek_doc,
590"seek(pos, whence=0) -> int. Change stream position.\n"
591"\n"
592"Seek to byte offset pos relative to position indicated by whence:\n"
593" 0 Start of stream (the default). pos should be >= 0;\n"
594" 1 Current position - pos may be negative;\n"
595" 2 End of stream - pos usually negative.\n"
596"Returns the new absolute position.");
597
598static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000599bytesio_seek(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000600{
601 Py_ssize_t pos;
602 int mode = 0;
603
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200604 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000605
606 if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
607 return NULL;
608
609 if (pos < 0 && mode == 0) {
610 PyErr_Format(PyExc_ValueError,
611 "negative seek value %zd", pos);
612 return NULL;
613 }
614
615 /* mode 0: offset relative to beginning of the string.
616 mode 1: offset relative to current position.
617 mode 2: offset relative the end of the string. */
618 if (mode == 1) {
619 if (pos > PY_SSIZE_T_MAX - self->pos) {
620 PyErr_SetString(PyExc_OverflowError,
621 "new position too large");
622 return NULL;
623 }
624 pos += self->pos;
625 }
626 else if (mode == 2) {
627 if (pos > PY_SSIZE_T_MAX - self->string_size) {
628 PyErr_SetString(PyExc_OverflowError,
629 "new position too large");
630 return NULL;
631 }
632 pos += self->string_size;
633 }
634 else if (mode != 0) {
635 PyErr_Format(PyExc_ValueError,
636 "invalid whence (%i, should be 0, 1 or 2)", mode);
637 return NULL;
638 }
639
640 if (pos < 0)
641 pos = 0;
642 self->pos = pos;
643
644 return PyLong_FromSsize_t(self->pos);
645}
646
647PyDoc_STRVAR(write_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000648"write(bytes) -> int. Write bytes to file.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000649"\n"
650"Return the number of bytes written.");
651
652static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653bytesio_write(bytesio *self, PyObject *obj)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000654{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000655 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656 Py_buffer buf;
657 PyObject *result = NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000658
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200659 CHECK_CLOSED(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000660 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000661
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662 if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000663 return NULL;
664
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665 if (buf.len != 0)
666 n = write_bytes(self, buf.buf, buf.len);
667 if (n >= 0)
668 result = PyLong_FromSsize_t(n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000669
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670 PyBuffer_Release(&buf);
671 return result;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000672}
673
674PyDoc_STRVAR(writelines_doc,
Alexandre Vassalotti7d060892008-05-07 01:47:37 +0000675"writelines(sequence_of_strings) -> None. Write strings to the file.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000676"\n"
Alexandre Vassalotti7d060892008-05-07 01:47:37 +0000677"Note that newlines are not added. The sequence can be any iterable\n"
678"object producing strings. This is equivalent to calling write() for\n"
679"each string.");
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000680
681static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000682bytesio_writelines(bytesio *self, PyObject *v)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000683{
684 PyObject *it, *item;
685 PyObject *ret;
686
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200687 CHECK_CLOSED(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000688
689 it = PyObject_GetIter(v);
690 if (it == NULL)
691 return NULL;
692
693 while ((item = PyIter_Next(it)) != NULL) {
694 ret = bytesio_write(self, item);
695 Py_DECREF(item);
696 if (ret == NULL) {
697 Py_DECREF(it);
698 return NULL;
699 }
700 Py_DECREF(ret);
701 }
702 Py_DECREF(it);
703
704 /* See if PyIter_Next failed */
705 if (PyErr_Occurred())
706 return NULL;
707
708 Py_RETURN_NONE;
709}
710
711PyDoc_STRVAR(close_doc,
712"close() -> None. Disable all I/O operations.");
713
714static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000715bytesio_close(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000716{
Serhiy Storchakac057c382015-02-03 02:00:18 +0200717 CHECK_EXPORTS(self);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200718 Py_CLEAR(self->buf);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000719 Py_RETURN_NONE;
720}
721
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000722/* Pickling support.
723
724 Note that only pickle protocol 2 and onward are supported since we use
725 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
726
727 Providing support for protocol < 2 would require the __reduce_ex__ method
728 which is notably long-winded when defined properly.
729
730 For BytesIO, the implementation would similar to one coded for
731 object.__reduce_ex__, but slightly less general. To be more specific, we
732 could call bytesio_getstate directly and avoid checking for the presence of
733 a fallback __reduce__ method. However, we would still need a __newobj__
734 function to use the efficient instance representation of PEP 307.
735 */
736
737static PyObject *
738bytesio_getstate(bytesio *self)
739{
740 PyObject *initvalue = bytesio_getvalue(self);
741 PyObject *dict;
742 PyObject *state;
743
744 if (initvalue == NULL)
745 return NULL;
746 if (self->dict == NULL) {
747 Py_INCREF(Py_None);
748 dict = Py_None;
749 }
750 else {
751 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200752 if (dict == NULL) {
753 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000754 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200755 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000756 }
757
758 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
759 Py_DECREF(initvalue);
760 return state;
761}
762
763static PyObject *
764bytesio_setstate(bytesio *self, PyObject *state)
765{
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200766 PyObject *result;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000767 PyObject *position_obj;
768 PyObject *dict;
769 Py_ssize_t pos;
770
771 assert(state != NULL);
772
773 /* We allow the state tuple to be longer than 3, because we may need
774 someday to extend the object's state without breaking
775 backward-compatibility. */
776 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
777 PyErr_Format(PyExc_TypeError,
778 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
779 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
780 return NULL;
781 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200782 CHECK_EXPORTS(self);
783 /* Reset the object to its default state. This is only needed to handle
784 the case of repeated calls to __setstate__. */
785 self->string_size = 0;
786 self->pos = 0;
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000787
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200788 /* Set the value of the internal buffer. If state[0] does not support the
789 buffer protocol, bytesio_write will raise the appropriate TypeError. */
790 result = bytesio_write(self, PyTuple_GET_ITEM(state, 0));
791 if (result == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000792 return NULL;
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200793 Py_DECREF(result);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000794
795 /* Set carefully the position value. Alternatively, we could use the seek
796 method instead of modifying self->pos directly to better protect the
797 object internal state against errneous (or malicious) inputs. */
798 position_obj = PyTuple_GET_ITEM(state, 1);
799 if (!PyLong_Check(position_obj)) {
800 PyErr_Format(PyExc_TypeError,
801 "second item of state must be an integer, not %.200s",
802 Py_TYPE(position_obj)->tp_name);
803 return NULL;
804 }
805 pos = PyLong_AsSsize_t(position_obj);
806 if (pos == -1 && PyErr_Occurred())
807 return NULL;
808 if (pos < 0) {
809 PyErr_SetString(PyExc_ValueError,
810 "position value cannot be negative");
811 return NULL;
812 }
813 self->pos = pos;
814
815 /* Set the dictionary of the instance variables. */
816 dict = PyTuple_GET_ITEM(state, 2);
817 if (dict != Py_None) {
818 if (!PyDict_Check(dict)) {
819 PyErr_Format(PyExc_TypeError,
820 "third item of state should be a dict, got a %.200s",
821 Py_TYPE(dict)->tp_name);
822 return NULL;
823 }
824 if (self->dict) {
825 /* Alternatively, we could replace the internal dictionary
826 completely. However, it seems more practical to just update it. */
827 if (PyDict_Update(self->dict, dict) < 0)
828 return NULL;
829 }
830 else {
831 Py_INCREF(dict);
832 self->dict = dict;
833 }
834 }
835
836 Py_RETURN_NONE;
837}
838
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000839static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000840bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000841{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000842 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000843 if (self->exports > 0) {
844 PyErr_SetString(PyExc_SystemError,
845 "deallocated BytesIO object has exported buffers");
846 PyErr_Print();
847 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200848 Py_CLEAR(self->buf);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000849 Py_CLEAR(self->dict);
850 if (self->weakreflist != NULL)
851 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000852 Py_TYPE(self)->tp_free(self);
853}
854
855static PyObject *
856bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
857{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000858 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000859
860 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000861 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000862 if (self == NULL)
863 return NULL;
864
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000865 /* tp_alloc initializes all the fields to zero. So we don't have to
866 initialize them here. */
867
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200868 self->buf = PyBytes_FromStringAndSize(NULL, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000869 if (self->buf == NULL) {
870 Py_DECREF(self);
871 return PyErr_NoMemory();
872 }
873
874 return (PyObject *)self;
875}
876
877static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000878bytesio_init(bytesio *self, PyObject *args, PyObject *kwds)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000879{
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000880 char *kwlist[] = {"initial_bytes", NULL};
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000881 PyObject *initvalue = NULL;
882
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000883 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:BytesIO", kwlist,
884 &initvalue))
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000885 return -1;
886
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200887 /* In case, __init__ is called multiple times. */
888 self->string_size = 0;
889 self->pos = 0;
890
891 if (self->exports > 0) {
892 PyErr_SetString(PyExc_BufferError,
893 "Existing exports of data: object cannot be re-sized");
894 return -1;
895 }
896 if (initvalue && initvalue != Py_None) {
897 if (PyBytes_CheckExact(initvalue)) {
898 Py_INCREF(initvalue);
899 Py_XDECREF(self->buf);
900 self->buf = initvalue;
901 self->string_size = PyBytes_GET_SIZE(initvalue);
902 }
903 else {
904 PyObject *res;
905 res = bytesio_write(self, initvalue);
906 if (res == NULL)
907 return -1;
908 Py_DECREF(res);
909 self->pos = 0;
910 }
911 }
912
913 return 0;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000914}
915
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200916static PyObject *
917bytesio_sizeof(bytesio *self, void *unused)
918{
919 Py_ssize_t res;
920
921 res = sizeof(bytesio);
Serhiy Storchaka87d0b452015-02-03 11:30:10 +0200922 if (self->buf && !SHARED_BUF(self))
923 res += _PySys_GetSizeOf(self->buf);
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200924 return PyLong_FromSsize_t(res);
925}
926
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000928bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929{
930 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931 return 0;
932}
933
934static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000935bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936{
937 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 return 0;
939}
940
941
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000942static PyGetSetDef bytesio_getsetlist[] = {
943 {"closed", (getter)bytesio_get_closed, NULL,
944 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000945 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000946};
947
948static struct PyMethodDef bytesio_methods[] = {
Antoine Pitrou1d857452012-09-05 20:11:49 +0200949 {"readable", (PyCFunction)return_not_closed, METH_NOARGS, readable_doc},
950 {"seekable", (PyCFunction)return_not_closed, METH_NOARGS, seekable_doc},
951 {"writable", (PyCFunction)return_not_closed, METH_NOARGS, writable_doc},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000952 {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc},
953 {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc},
954 {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc},
955 {"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc},
956 {"write", (PyCFunction)bytesio_write, METH_O, write_doc},
957 {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
958 {"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc},
959 {"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc},
960 {"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
961 {"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
962 {"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
Antoine Pitrou972ee132010-09-06 18:48:21 +0000963 {"getbuffer", (PyCFunction)bytesio_getbuffer, METH_NOARGS, getbuffer_doc},
Antoine Pitroud5c3f6c2010-09-02 19:48:07 +0000964 {"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000965 {"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
966 {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000967 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
968 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200969 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000970 {NULL, NULL} /* sentinel */
971};
972
973PyDoc_STRVAR(bytesio_doc,
974"BytesIO([buffer]) -> object\n"
975"\n"
976"Create a buffered I/O implementation using an in-memory bytes\n"
977"buffer, ready for reading and writing.");
978
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000979PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000980 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000982 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000983 0, /*tp_itemsize*/
984 (destructor)bytesio_dealloc, /*tp_dealloc*/
985 0, /*tp_print*/
986 0, /*tp_getattr*/
987 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000988 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000989 0, /*tp_repr*/
990 0, /*tp_as_number*/
991 0, /*tp_as_sequence*/
992 0, /*tp_as_mapping*/
993 0, /*tp_hash*/
994 0, /*tp_call*/
995 0, /*tp_str*/
996 0, /*tp_getattro*/
997 0, /*tp_setattro*/
998 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000999 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1000 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001001 bytesio_doc, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001002 (traverseproc)bytesio_traverse, /*tp_traverse*/
1003 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001004 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001005 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001006 PyObject_SelfIter, /*tp_iter*/
1007 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1008 bytesio_methods, /*tp_methods*/
1009 0, /*tp_members*/
1010 bytesio_getsetlist, /*tp_getset*/
1011 0, /*tp_base*/
1012 0, /*tp_dict*/
1013 0, /*tp_descr_get*/
1014 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001015 offsetof(bytesio, dict), /*tp_dictoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001016 (initproc)bytesio_init, /*tp_init*/
1017 0, /*tp_alloc*/
1018 bytesio_new, /*tp_new*/
1019};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001020
1021
1022/*
1023 * Implementation of the small intermediate object used by getbuffer().
1024 * getbuffer() returns a memoryview over this object, which should make it
1025 * invisible from Python code.
1026 */
1027
1028static int
1029bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1030{
Antoine Pitrou972ee132010-09-06 18:48:21 +00001031 bytesio *b = (bytesio *) obj->source;
Stefan Krah650c1e82015-02-03 21:43:23 +01001032
1033 if (view == NULL) {
1034 PyErr_SetString(PyExc_BufferError,
1035 "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1036 return -1;
1037 }
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001038 if (SHARED_BUF(b)) {
1039 if (unshare_buffer(b, b->string_size) < 0)
1040 return -1;
1041 }
Stefan Krah650c1e82015-02-03 21:43:23 +01001042
1043 /* cannot fail if view != NULL and readonly == 0 */
1044 (void)PyBuffer_FillInfo(view, (PyObject*)obj,
Serhiy Storchaka87d0b452015-02-03 11:30:10 +02001045 PyBytes_AS_STRING(b->buf), b->string_size,
Antoine Pitrou972ee132010-09-06 18:48:21 +00001046 0, flags);
Stefan Krah650c1e82015-02-03 21:43:23 +01001047 b->exports++;
1048 return 0;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001049}
1050
1051static void
1052bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1053{
1054 bytesio *b = (bytesio *) obj->source;
1055 b->exports--;
1056}
1057
1058static int
1059bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1060{
1061 Py_VISIT(self->source);
1062 return 0;
1063}
1064
1065static void
1066bytesiobuf_dealloc(bytesiobuf *self)
1067{
1068 Py_CLEAR(self->source);
1069 Py_TYPE(self)->tp_free(self);
1070}
1071
1072static PyBufferProcs bytesiobuf_as_buffer = {
1073 (getbufferproc) bytesiobuf_getbuffer,
1074 (releasebufferproc) bytesiobuf_releasebuffer,
1075};
1076
1077PyTypeObject _PyBytesIOBuffer_Type = {
1078 PyVarObject_HEAD_INIT(NULL, 0)
1079 "_io._BytesIOBuffer", /*tp_name*/
1080 sizeof(bytesiobuf), /*tp_basicsize*/
1081 0, /*tp_itemsize*/
1082 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1083 0, /*tp_print*/
1084 0, /*tp_getattr*/
1085 0, /*tp_setattr*/
1086 0, /*tp_reserved*/
1087 0, /*tp_repr*/
1088 0, /*tp_as_number*/
1089 0, /*tp_as_sequence*/
1090 0, /*tp_as_mapping*/
1091 0, /*tp_hash*/
1092 0, /*tp_call*/
1093 0, /*tp_str*/
1094 0, /*tp_getattro*/
1095 0, /*tp_setattro*/
1096 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1097 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1098 0, /*tp_doc*/
1099 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1100 0, /*tp_clear*/
1101 0, /*tp_richcompare*/
1102 0, /*tp_weaklistoffset*/
1103 0, /*tp_iter*/
1104 0, /*tp_iternext*/
1105 0, /*tp_methods*/
1106 0, /*tp_members*/
1107 0, /*tp_getset*/
1108 0, /*tp_base*/
1109 0, /*tp_dict*/
1110 0, /*tp_descr_get*/
1111 0, /*tp_descr_set*/
1112 0, /*tp_dictoffset*/
1113 0, /*tp_init*/
1114 0, /*tp_alloc*/
1115 0, /*tp_new*/
1116};