2
#include "structmember.h" /* for offsetof() */
9
Py_ssize_t string_size;
12
PyObject *weakreflist;
22
#define CHECK_CLOSED(self) \
23
if ((self)->buf == NULL) { \
24
PyErr_SetString(PyExc_ValueError, \
25
"I/O operation on closed file."); \
29
#define CHECK_EXPORTS(self) \
30
if ((self)->exports > 0) { \
31
PyErr_SetString(PyExc_BufferError, \
32
"Existing exports of data: object cannot be re-sized"); \
37
/* Internal routine to get a line from the buffer of a BytesIO
38
object. Returns the length between the current position to the
39
next newline character. */
41
get_line(bytesio *self, char **output)
47
assert(self->buf != NULL);
49
/* Move to the end of the line, up to the end of the string, s. */
50
str_end = self->buf + self->string_size;
51
for (n = self->buf + self->pos;
52
n < str_end && *n != '\n';
55
/* Skip the newline character */
59
/* Get the length from the current position to the end of the line. */
60
len = n - (self->buf + self->pos);
61
*output = self->buf + self->pos;
64
assert(self->pos < PY_SSIZE_T_MAX - len);
70
/* Internal routine for changing the size of the buffer of BytesIO objects.
71
The caller should ensure that the 'size' argument is non-negative. Returns
72
0 on success, -1 otherwise. */
74
resize_buffer(bytesio *self, size_t size)
76
/* Here, unsigned types are used to avoid dealing with signed integer
77
overflow, which is undefined in C. */
78
size_t alloc = self->buf_size;
81
assert(self->buf != NULL);
83
/* For simplicity, stay in the range of the signed type. Anyway, Python
84
doesn't allow strings to be longer than this. */
85
if (size > PY_SSIZE_T_MAX)
88
if (size < alloc / 2) {
89
/* Major downsize; resize down to exact size. */
92
else if (size < alloc) {
93
/* Within allocated size; quick exit */
96
else if (size <= alloc * 1.125) {
97
/* Moderate upsize; overallocate similar to list_resize() */
98
alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
101
/* Major upsize; resize up to exact size */
105
if (alloc > ((size_t)-1) / sizeof(char))
107
new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char));
108
if (new_buf == NULL) {
112
self->buf_size = alloc;
118
PyErr_SetString(PyExc_OverflowError,
119
"new buffer size too large");
123
/* Internal routine for writing a string of bytes to the buffer of a BytesIO
124
object. Returns the number of bytes written, or -1 on error. */
126
write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
128
assert(self->buf != NULL);
129
assert(self->pos >= 0);
132
if ((size_t)self->pos + len > self->buf_size) {
133
if (resize_buffer(self, (size_t)self->pos + len) < 0)
137
if (self->pos > self->string_size) {
138
/* In case of overseek, pad with null bytes the buffer region between
139
the end of stream and the current position.
142
| |<---used--->|<----------available----------->|
143
| | <--to pad-->|<---to write---> |
146
memset(self->buf + self->string_size, '\0',
147
(self->pos - self->string_size) * sizeof(char));
150
/* Copy the data to the internal buffer, overwriting some of the existing
151
data if self->pos < self->string_size. */
152
memcpy(self->buf + self->pos, bytes, len);
155
/* Set the new length of the internal string if it has changed. */
156
if (self->string_size < self->pos) {
157
self->string_size = self->pos;
164
bytesio_get_closed(bytesio *self)
166
if (self->buf == NULL) {
174
PyDoc_STRVAR(readable_doc,
175
"readable() -> bool. Returns True if the IO object can be read.");
177
PyDoc_STRVAR(writable_doc,
178
"writable() -> bool. Returns True if the IO object can be written.");
180
PyDoc_STRVAR(seekable_doc,
181
"seekable() -> bool. Returns True if the IO object can be seeked.");
183
/* Generic getter for the writable, readable and seekable properties */
185
return_not_closed(bytesio *self)
191
PyDoc_STRVAR(flush_doc,
192
"flush() -> None. Does nothing.");
195
bytesio_flush(bytesio *self)
201
PyDoc_STRVAR(getbuffer_doc,
202
"getbuffer() -> bytes.\n"
204
"Get a read-write view over the contents of the BytesIO object.");
207
bytesio_getbuffer(bytesio *self)
209
PyTypeObject *type = &_PyBytesIOBuffer_Type;
215
buf = (bytesiobuf *) type->tp_alloc(type, 0);
220
view = PyMemoryView_FromObject((PyObject *) buf);
225
PyDoc_STRVAR(getval_doc,
226
"getvalue() -> bytes.\n"
228
"Retrieve the entire contents of the BytesIO object.");
231
bytesio_getvalue(bytesio *self)
234
return PyBytes_FromStringAndSize(self->buf, self->string_size);
237
PyDoc_STRVAR(isatty_doc,
238
"isatty() -> False.\n"
240
"Always returns False since BytesIO objects are not connected\n"
241
"to a tty-like device.");
244
bytesio_isatty(bytesio *self)
250
PyDoc_STRVAR(tell_doc,
251
"tell() -> current file position, an integer\n");
254
bytesio_tell(bytesio *self)
257
return PyLong_FromSsize_t(self->pos);
260
PyDoc_STRVAR(read_doc,
261
"read([size]) -> read at most size bytes, returned as a string.\n"
263
"If the size argument is negative, read until EOF is reached.\n"
264
"Return an empty string at EOF.");
267
bytesio_read(bytesio *self, PyObject *args)
271
PyObject *arg = Py_None;
275
if (!PyArg_ParseTuple(args, "|O:read", &arg))
278
if (PyLong_Check(arg)) {
279
size = PyLong_AsSsize_t(arg);
280
if (size == -1 && PyErr_Occurred())
283
else if (arg == Py_None) {
284
/* Read until EOF is reached, by default. */
288
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
289
Py_TYPE(arg)->tp_name);
293
/* adjust invalid sizes */
294
n = self->string_size - self->pos;
295
if (size < 0 || size > n) {
301
assert(self->buf != NULL);
302
output = self->buf + self->pos;
305
return PyBytes_FromStringAndSize(output, size);
309
PyDoc_STRVAR(read1_doc,
310
"read1(size) -> read at most size bytes, returned as a string.\n"
312
"If the size argument is negative or omitted, read until EOF is reached.\n"
313
"Return an empty string at EOF.");
316
bytesio_read1(bytesio *self, PyObject *n)
320
arg = PyTuple_Pack(1, n);
323
res = bytesio_read(self, arg);
328
PyDoc_STRVAR(readline_doc,
329
"readline([size]) -> next line from the file, as a string.\n"
331
"Retain newline. A non-negative size argument limits the maximum\n"
332
"number of bytes to return (an incomplete line may be returned then).\n"
333
"Return an empty string at EOF.\n");
336
bytesio_readline(bytesio *self, PyObject *args)
340
PyObject *arg = Py_None;
344
if (!PyArg_ParseTuple(args, "|O:readline", &arg))
347
if (PyLong_Check(arg)) {
348
size = PyLong_AsSsize_t(arg);
349
if (size == -1 && PyErr_Occurred())
352
else if (arg == Py_None) {
353
/* No size limit, by default. */
357
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
358
Py_TYPE(arg)->tp_name);
362
n = get_line(self, &output);
364
if (size >= 0 && size < n) {
370
return PyBytes_FromStringAndSize(output, n);
373
PyDoc_STRVAR(readlines_doc,
374
"readlines([size]) -> list of strings, each a line from the file.\n"
376
"Call readline() repeatedly and return a list of the lines so read.\n"
377
"The optional size argument, if given, is an approximate bound on the\n"
378
"total number of bytes in the lines returned.\n");
381
bytesio_readlines(bytesio *self, PyObject *args)
383
Py_ssize_t maxsize, size, n;
384
PyObject *result, *line;
386
PyObject *arg = Py_None;
390
if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
393
if (PyLong_Check(arg)) {
394
maxsize = PyLong_AsSsize_t(arg);
395
if (maxsize == -1 && PyErr_Occurred())
398
else if (arg == Py_None) {
399
/* No size limit, by default. */
403
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
404
Py_TYPE(arg)->tp_name);
409
result = PyList_New(0);
413
while ((n = get_line(self, &output)) != 0) {
414
line = PyBytes_FromStringAndSize(output, n);
417
if (PyList_Append(result, line) == -1) {
423
if (maxsize > 0 && size >= maxsize)
433
PyDoc_STRVAR(readinto_doc,
434
"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n"
436
"Returns number of bytes read (0 for EOF), or None if the object\n"
437
"is set not to block as has no data to read.");
440
bytesio_readinto(bytesio *self, PyObject *buffer)
447
if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
450
/* adjust invalid sizes */
451
n = self->string_size - self->pos;
458
memcpy(raw_buffer, self->buf + self->pos, len);
459
assert(self->pos + len < PY_SSIZE_T_MAX);
463
return PyLong_FromSsize_t(len);
466
PyDoc_STRVAR(truncate_doc,
467
"truncate([size]) -> int. Truncate the file to at most size bytes.\n"
469
"Size defaults to the current file position, as returned by tell().\n"
470
"The current file position is unchanged. Returns the new size.\n");
473
bytesio_truncate(bytesio *self, PyObject *args)
476
PyObject *arg = Py_None;
481
if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
484
if (PyLong_Check(arg)) {
485
size = PyLong_AsSsize_t(arg);
486
if (size == -1 && PyErr_Occurred())
489
else if (arg == Py_None) {
490
/* Truncate to current position if no argument is passed. */
494
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
495
Py_TYPE(arg)->tp_name);
500
PyErr_Format(PyExc_ValueError,
501
"negative size value %zd", size);
505
if (size < self->string_size) {
506
self->string_size = size;
507
if (resize_buffer(self, size) < 0)
511
return PyLong_FromSsize_t(size);
515
bytesio_iternext(bytesio *self)
522
n = get_line(self, &next);
527
return PyBytes_FromStringAndSize(next, n);
530
PyDoc_STRVAR(seek_doc,
531
"seek(pos, whence=0) -> int. Change stream position.\n"
533
"Seek to byte offset pos relative to position indicated by whence:\n"
534
" 0 Start of stream (the default). pos should be >= 0;\n"
535
" 1 Current position - pos may be negative;\n"
536
" 2 End of stream - pos usually negative.\n"
537
"Returns the new absolute position.");
540
bytesio_seek(bytesio *self, PyObject *args)
547
if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
550
if (pos < 0 && mode == 0) {
551
PyErr_Format(PyExc_ValueError,
552
"negative seek value %zd", pos);
556
/* mode 0: offset relative to beginning of the string.
557
mode 1: offset relative to current position.
558
mode 2: offset relative the end of the string. */
560
if (pos > PY_SSIZE_T_MAX - self->pos) {
561
PyErr_SetString(PyExc_OverflowError,
562
"new position too large");
567
else if (mode == 2) {
568
if (pos > PY_SSIZE_T_MAX - self->string_size) {
569
PyErr_SetString(PyExc_OverflowError,
570
"new position too large");
573
pos += self->string_size;
575
else if (mode != 0) {
576
PyErr_Format(PyExc_ValueError,
577
"invalid whence (%i, should be 0, 1 or 2)", mode);
585
return PyLong_FromSsize_t(self->pos);
588
PyDoc_STRVAR(write_doc,
589
"write(bytes) -> int. Write bytes to file.\n"
591
"Return the number of bytes written.");
594
bytesio_write(bytesio *self, PyObject *obj)
598
PyObject *result = NULL;
603
if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
607
n = write_bytes(self, buf.buf, buf.len);
609
result = PyLong_FromSsize_t(n);
611
PyBuffer_Release(&buf);
615
PyDoc_STRVAR(writelines_doc,
616
"writelines(sequence_of_strings) -> None. Write strings to the file.\n"
618
"Note that newlines are not added. The sequence can be any iterable\n"
619
"object producing strings. This is equivalent to calling write() for\n"
623
bytesio_writelines(bytesio *self, PyObject *v)
630
it = PyObject_GetIter(v);
634
while ((item = PyIter_Next(it)) != NULL) {
635
ret = bytesio_write(self, item);
645
/* See if PyIter_Next failed */
646
if (PyErr_Occurred())
652
PyDoc_STRVAR(close_doc,
653
"close() -> None. Disable all I/O operations.");
656
bytesio_close(bytesio *self)
658
if (self->buf != NULL) {
659
PyMem_Free(self->buf);
667
Note that only pickle protocol 2 and onward are supported since we use
668
extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
670
Providing support for protocol < 2 would require the __reduce_ex__ method
671
which is notably long-winded when defined properly.
673
For BytesIO, the implementation would similar to one coded for
674
object.__reduce_ex__, but slightly less general. To be more specific, we
675
could call bytesio_getstate directly and avoid checking for the presence of
676
a fallback __reduce__ method. However, we would still need a __newobj__
677
function to use the efficient instance representation of PEP 307.
681
bytesio_getstate(bytesio *self)
683
PyObject *initvalue = bytesio_getvalue(self);
687
if (initvalue == NULL)
689
if (self->dict == NULL) {
694
dict = PyDict_Copy(self->dict);
696
Py_DECREF(initvalue);
701
state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
702
Py_DECREF(initvalue);
707
bytesio_setstate(bytesio *self, PyObject *state)
710
PyObject *position_obj;
714
assert(state != NULL);
716
/* We allow the state tuple to be longer than 3, because we may need
717
someday to extend the object's state without breaking
718
backward-compatibility. */
719
if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
720
PyErr_Format(PyExc_TypeError,
721
"%.200s.__setstate__ argument should be 3-tuple, got %.200s",
722
Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
726
/* Reset the object to its default state. This is only needed to handle
727
the case of repeated calls to __setstate__. */
728
self->string_size = 0;
731
/* Set the value of the internal buffer. If state[0] does not support the
732
buffer protocol, bytesio_write will raise the appropriate TypeError. */
733
result = bytesio_write(self, PyTuple_GET_ITEM(state, 0));
738
/* Set carefully the position value. Alternatively, we could use the seek
739
method instead of modifying self->pos directly to better protect the
740
object internal state against errneous (or malicious) inputs. */
741
position_obj = PyTuple_GET_ITEM(state, 1);
742
if (!PyLong_Check(position_obj)) {
743
PyErr_Format(PyExc_TypeError,
744
"second item of state must be an integer, not %.200s",
745
Py_TYPE(position_obj)->tp_name);
748
pos = PyLong_AsSsize_t(position_obj);
749
if (pos == -1 && PyErr_Occurred())
752
PyErr_SetString(PyExc_ValueError,
753
"position value cannot be negative");
758
/* Set the dictionary of the instance variables. */
759
dict = PyTuple_GET_ITEM(state, 2);
760
if (dict != Py_None) {
761
if (!PyDict_Check(dict)) {
762
PyErr_Format(PyExc_TypeError,
763
"third item of state should be a dict, got a %.200s",
764
Py_TYPE(dict)->tp_name);
768
/* Alternatively, we could replace the internal dictionary
769
completely. However, it seems more practical to just update it. */
770
if (PyDict_Update(self->dict, dict) < 0)
783
bytesio_dealloc(bytesio *self)
785
_PyObject_GC_UNTRACK(self);
786
if (self->exports > 0) {
787
PyErr_SetString(PyExc_SystemError,
788
"deallocated BytesIO object has exported buffers");
791
if (self->buf != NULL) {
792
PyMem_Free(self->buf);
795
Py_CLEAR(self->dict);
796
if (self->weakreflist != NULL)
797
PyObject_ClearWeakRefs((PyObject *) self);
798
Py_TYPE(self)->tp_free(self);
802
bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
806
assert(type != NULL && type->tp_alloc != NULL);
807
self = (bytesio *)type->tp_alloc(type, 0);
811
/* tp_alloc initializes all the fields to zero. So we don't have to
812
initialize them here. */
814
self->buf = (char *)PyMem_Malloc(0);
815
if (self->buf == NULL) {
817
return PyErr_NoMemory();
820
return (PyObject *)self;
824
bytesio_init(bytesio *self, PyObject *args, PyObject *kwds)
826
char *kwlist[] = {"initial_bytes", NULL};
827
PyObject *initvalue = NULL;
829
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:BytesIO", kwlist,
833
/* In case, __init__ is called multiple times. */
834
self->string_size = 0;
837
if (initvalue && initvalue != Py_None) {
839
res = bytesio_write(self, initvalue);
850
bytesio_sizeof(bytesio *self, void *unused)
854
res = sizeof(bytesio);
856
res += self->buf_size;
857
return PyLong_FromSsize_t(res);
861
bytesio_traverse(bytesio *self, visitproc visit, void *arg)
863
Py_VISIT(self->dict);
868
bytesio_clear(bytesio *self)
870
Py_CLEAR(self->dict);
875
static PyGetSetDef bytesio_getsetlist[] = {
876
{"closed", (getter)bytesio_get_closed, NULL,
877
"True if the file is closed."},
878
{NULL}, /* sentinel */
881
static struct PyMethodDef bytesio_methods[] = {
882
{"readable", (PyCFunction)return_not_closed, METH_NOARGS, readable_doc},
883
{"seekable", (PyCFunction)return_not_closed, METH_NOARGS, seekable_doc},
884
{"writable", (PyCFunction)return_not_closed, METH_NOARGS, writable_doc},
885
{"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc},
886
{"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc},
887
{"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc},
888
{"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc},
889
{"write", (PyCFunction)bytesio_write, METH_O, write_doc},
890
{"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
891
{"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc},
892
{"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc},
893
{"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
894
{"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
895
{"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
896
{"getbuffer", (PyCFunction)bytesio_getbuffer, METH_NOARGS, getbuffer_doc},
897
{"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
898
{"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
899
{"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
900
{"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
901
{"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
902
{"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
903
{NULL, NULL} /* sentinel */
906
PyDoc_STRVAR(bytesio_doc,
907
"BytesIO([buffer]) -> object\n"
909
"Create a buffered I/O implementation using an in-memory bytes\n"
910
"buffer, ready for reading and writing.");
912
PyTypeObject PyBytesIO_Type = {
913
PyVarObject_HEAD_INIT(NULL, 0)
914
"_io.BytesIO", /*tp_name*/
915
sizeof(bytesio), /*tp_basicsize*/
917
(destructor)bytesio_dealloc, /*tp_dealloc*/
924
0, /*tp_as_sequence*/
932
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
933
Py_TPFLAGS_HAVE_GC, /*tp_flags*/
934
bytesio_doc, /*tp_doc*/
935
(traverseproc)bytesio_traverse, /*tp_traverse*/
936
(inquiry)bytesio_clear, /*tp_clear*/
937
0, /*tp_richcompare*/
938
offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
939
PyObject_SelfIter, /*tp_iter*/
940
(iternextfunc)bytesio_iternext, /*tp_iternext*/
941
bytesio_methods, /*tp_methods*/
943
bytesio_getsetlist, /*tp_getset*/
948
offsetof(bytesio, dict), /*tp_dictoffset*/
949
(initproc)bytesio_init, /*tp_init*/
951
bytesio_new, /*tp_new*/
956
* Implementation of the small intermediate object used by getbuffer().
957
* getbuffer() returns a memoryview over this object, which should make it
958
* invisible from Python code.
962
bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
965
bytesio *b = (bytesio *) obj->source;
970
ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size,
979
bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
981
bytesio *b = (bytesio *) obj->source;
986
bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
988
Py_VISIT(self->source);
993
bytesiobuf_dealloc(bytesiobuf *self)
995
Py_CLEAR(self->source);
996
Py_TYPE(self)->tp_free(self);
999
static PyBufferProcs bytesiobuf_as_buffer = {
1000
(getbufferproc) bytesiobuf_getbuffer,
1001
(releasebufferproc) bytesiobuf_releasebuffer,
1004
PyTypeObject _PyBytesIOBuffer_Type = {
1005
PyVarObject_HEAD_INIT(NULL, 0)
1006
"_io._BytesIOBuffer", /*tp_name*/
1007
sizeof(bytesiobuf), /*tp_basicsize*/
1009
(destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1016
0, /*tp_as_sequence*/
1017
0, /*tp_as_mapping*/
1023
&bytesiobuf_as_buffer, /*tp_as_buffer*/
1024
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1026
(traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1028
0, /*tp_richcompare*/
1029
0, /*tp_weaklistoffset*/
1039
0, /*tp_dictoffset*/