2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
4 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
7 Written by Amaury Forgeot d'Arc and Antoine Pitrou
10 #define PY_SSIZE_T_CLEAN
12 #include "structmember.h"
14 #include "_iomodule.h"
17 * BufferedIOBase class, inherits from IOBase.
19 PyDoc_STRVAR(bufferediobase_doc
,
20 "Base class for buffered IO objects.\n"
22 "The main difference with RawIOBase is that the read() method\n"
23 "supports omitting the size argument, and does not have a default\n"
24 "implementation that defers to readinto().\n"
26 "In addition, read(), readinto() and write() may raise\n"
27 "BlockingIOError if the underlying raw stream is in non-blocking\n"
28 "mode and not ready; unlike their raw counterparts, they will never\n"
31 "A typical implementation should not inherit from a RawIOBase\n"
32 "implementation, but wrap one.\n"
36 bufferediobase_readinto(PyObject
*self
, PyObject
*args
)
42 if (!PyArg_ParseTuple(args
, "w*:readinto", &buf
)) {
46 data
= PyObject_CallMethod(self
, "read", "n", buf
.len
);
50 if (!PyBytes_Check(data
)) {
52 PyErr_SetString(PyExc_TypeError
, "read() should return bytes");
57 memcpy(buf
.buf
, PyBytes_AS_STRING(data
), len
);
59 PyBuffer_Release(&buf
);
62 return PyLong_FromSsize_t(len
);
65 PyBuffer_Release(&buf
);
70 bufferediobase_unsupported(const char *message
)
72 PyErr_SetString(_PyIO_unsupported_operation
, message
);
76 PyDoc_STRVAR(bufferediobase_detach_doc
,
77 "Disconnect this buffer from its underlying raw stream and return it.\n"
79 "After the raw stream has been detached, the buffer is in an unusable\n"
83 bufferediobase_detach(PyObject
*self
)
85 return bufferediobase_unsupported("detach");
88 PyDoc_STRVAR(bufferediobase_read_doc
,
89 "Read and return up to n bytes.\n"
91 "If the argument is omitted, None, or negative, reads and\n"
92 "returns all data until EOF.\n"
94 "If the argument is positive, and the underlying raw stream is\n"
95 "not 'interactive', multiple raw reads may be issued to satisfy\n"
96 "the byte count (unless EOF is reached first). But for\n"
97 "interactive raw streams (as well as sockets and pipes), at most\n"
98 "one raw read will be issued, and a short result does not imply\n"
99 "that EOF is imminent.\n"
101 "Returns an empty bytes object on EOF.\n"
103 "Returns None if the underlying raw stream was open in non-blocking\n"
104 "mode and no data is available at the moment.\n");
107 bufferediobase_read(PyObject
*self
, PyObject
*args
)
109 return bufferediobase_unsupported("read");
112 PyDoc_STRVAR(bufferediobase_read1_doc
,
113 "Read and return up to n bytes, with at most one read() call\n"
114 "to the underlying raw stream. A short result does not imply\n"
115 "that EOF is imminent.\n"
117 "Returns an empty bytes object on EOF.\n");
120 bufferediobase_read1(PyObject
*self
, PyObject
*args
)
122 return bufferediobase_unsupported("read1");
125 PyDoc_STRVAR(bufferediobase_write_doc
,
126 "Write the given buffer to the IO stream.\n"
128 "Returns the number of bytes written, which is never less than\n"
131 "Raises BlockingIOError if the buffer is full and the\n"
132 "underlying raw stream cannot accept more data at the moment.\n");
135 bufferediobase_write(PyObject
*self
, PyObject
*args
)
137 return bufferediobase_unsupported("write");
141 static PyMethodDef bufferediobase_methods
[] = {
142 {"detach", (PyCFunction
)bufferediobase_detach
, METH_NOARGS
, bufferediobase_detach_doc
},
143 {"read", bufferediobase_read
, METH_VARARGS
, bufferediobase_read_doc
},
144 {"read1", bufferediobase_read1
, METH_VARARGS
, bufferediobase_read1_doc
},
145 {"readinto", bufferediobase_readinto
, METH_VARARGS
, NULL
},
146 {"write", bufferediobase_write
, METH_VARARGS
, bufferediobase_write_doc
},
150 PyTypeObject PyBufferedIOBase_Type
= {
151 PyVarObject_HEAD_INIT(NULL
, 0)
152 "_io._BufferedIOBase", /*tp_name*/
162 0, /*tp_as_sequence*/
170 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
171 bufferediobase_doc
, /* tp_doc */
174 0, /* tp_richcompare */
175 0, /* tp_weaklistoffset */
178 bufferediobase_methods
, /* tp_methods */
181 &PyIOBase_Type
, /* tp_base */
183 0, /* tp_descr_get */
184 0, /* tp_descr_set */
185 0, /* tp_dictoffset */
196 int ok
; /* Initialized? */
201 /* True if this is a vanilla Buffered object (rather than a user derived
202 class) *and* the raw stream is a vanilla FileIO object. */
203 int fast_closed_checks
;
205 /* Absolute position inside the raw stream (-1 if unknown). */
208 /* A static buffer of size `buffer_size` */
210 /* Current logical position in the buffer. */
212 /* Position of the raw stream in the buffer. */
215 /* Just after the last buffered byte in the buffer, or -1 if the buffer
216 isn't ready for reading. */
219 /* Just after the last byte actually written */
221 /* Just after the last byte waiting to be written, or -1 if the buffer
222 isn't ready for writing. */
226 PyThread_type_lock lock
;
230 Py_ssize_t buffer_size
;
231 Py_ssize_t buffer_mask
;
234 PyObject
*weakreflist
;
238 Implementation notes:
240 * BufferedReader, BufferedWriter and BufferedRandom try to share most
241 methods (this is helped by the members `readable` and `writable`, which
242 are initialized in the respective constructors)
243 * They also share a single buffer for reading and writing. This enables
244 interleaved reads and writes without flushing. It also makes the logic
245 a bit trickier to get right.
246 * The absolute position of the raw stream is cached, if possible, in the
247 `abs_pos` member. It must be updated every time an operation is done
248 on the raw stream. If not sure, it can be reinitialized by calling
249 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
250 also does it). To read it, use RAW_TELL().
251 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
252 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
254 NOTE: we should try to maintain block alignment of reads and writes to the
255 raw stream (according to the buffer size), but for now it is only done
256 in read() and friends.
260 /* These macros protect the buffered object against concurrent operations. */
265 _enter_buffered_busy(buffered
*self
)
267 if (self
->owner
== PyThread_get_thread_ident()) {
268 PyObject
*r
= PyObject_Repr((PyObject
*) self
);
270 PyErr_Format(PyExc_RuntimeError
,
271 "reentrant call inside %s",
272 PyString_AS_STRING(r
));
277 Py_BEGIN_ALLOW_THREADS
278 PyThread_acquire_lock(self
->lock
, 1);
283 #define ENTER_BUFFERED(self) \
284 ( (PyThread_acquire_lock(self->lock, 0) ? \
285 1 : _enter_buffered_busy(self)) \
286 && (self->owner = PyThread_get_thread_ident(), 1) )
288 #define LEAVE_BUFFERED(self) \
291 PyThread_release_lock(self->lock); \
295 #define ENTER_BUFFERED(self) 1
296 #define LEAVE_BUFFERED(self)
299 #define CHECK_INITIALIZED(self) \
300 if (self->ok <= 0) { \
301 if (self->detached) { \
302 PyErr_SetString(PyExc_ValueError, \
303 "raw stream has been detached"); \
305 PyErr_SetString(PyExc_ValueError, \
306 "I/O operation on uninitialized object"); \
311 #define CHECK_INITIALIZED_INT(self) \
312 if (self->ok <= 0) { \
313 if (self->detached) { \
314 PyErr_SetString(PyExc_ValueError, \
315 "raw stream has been detached"); \
317 PyErr_SetString(PyExc_ValueError, \
318 "I/O operation on uninitialized object"); \
323 #define IS_CLOSED(self) \
324 (self->fast_closed_checks \
325 ? _PyFileIO_closed(self->raw) \
326 : buffered_closed(self))
328 #define CHECK_CLOSED(self, error_msg) \
329 if (IS_CLOSED(self)) { \
330 PyErr_SetString(PyExc_ValueError, error_msg); \
335 #define VALID_READ_BUFFER(self) \
336 (self->readable && self->read_end != -1)
338 #define VALID_WRITE_BUFFER(self) \
339 (self->writable && self->write_end != -1)
341 #define ADJUST_POSITION(self, _new_pos) \
343 self->pos = _new_pos; \
344 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
345 self->read_end = self->pos; \
348 #define READAHEAD(self) \
349 ((self->readable && VALID_READ_BUFFER(self)) \
350 ? (self->read_end - self->pos) : 0)
352 #define RAW_OFFSET(self) \
353 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
354 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
356 #define RAW_TELL(self) \
357 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
359 #define MINUS_LAST_BLOCK(self, size) \
360 (self->buffer_mask ? \
361 (size & ~self->buffer_mask) : \
362 (self->buffer_size * (size / self->buffer_size)))
366 buffered_dealloc(buffered
*self
)
368 if (self
->ok
&& _PyIOBase_finalize((PyObject
*) self
) < 0)
370 _PyObject_GC_UNTRACK(self
);
372 if (self
->weakreflist
!= NULL
)
373 PyObject_ClearWeakRefs((PyObject
*)self
);
376 PyMem_Free(self
->buffer
);
381 PyThread_free_lock(self
->lock
);
385 Py_CLEAR(self
->dict
);
386 Py_TYPE(self
)->tp_free((PyObject
*)self
);
390 buffered_sizeof(buffered
*self
, void *unused
)
394 res
= sizeof(buffered
);
396 res
+= self
->buffer_size
;
397 return PyLong_FromSsize_t(res
);
401 buffered_traverse(buffered
*self
, visitproc visit
, void *arg
)
404 Py_VISIT(self
->dict
);
409 buffered_clear(buffered
*self
)
411 if (self
->ok
&& _PyIOBase_finalize((PyObject
*) self
) < 0)
415 Py_CLEAR(self
->dict
);
420 * _BufferedIOMixin methods
421 * This is not a class, just a collection of methods that will be reused
422 * by BufferedReader and BufferedWriter
425 /* Flush and close */
428 buffered_simple_flush(buffered
*self
, PyObject
*args
)
430 CHECK_INITIALIZED(self
)
431 return PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_flush
, NULL
);
435 buffered_closed(buffered
*self
)
439 CHECK_INITIALIZED_INT(self
)
440 res
= PyObject_GetAttr(self
->raw
, _PyIO_str_closed
);
443 closed
= PyObject_IsTrue(res
);
449 buffered_closed_get(buffered
*self
, void *context
)
451 CHECK_INITIALIZED(self
)
452 return PyObject_GetAttr(self
->raw
, _PyIO_str_closed
);
456 buffered_close(buffered
*self
, PyObject
*args
)
458 PyObject
*res
= NULL
, *exc
= NULL
, *val
, *tb
;
461 CHECK_INITIALIZED(self
)
462 if (!ENTER_BUFFERED(self
))
465 r
= buffered_closed(self
);
473 /* flush() will most probably re-take the lock, so drop it first */
475 res
= PyObject_CallMethodObjArgs((PyObject
*)self
, _PyIO_str_flush
, NULL
);
476 if (!ENTER_BUFFERED(self
))
479 PyErr_Fetch(&exc
, &val
, &tb
);
483 res
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_close
, NULL
);
486 _PyErr_ReplaceException(exc
, val
, tb
);
498 buffered_detach(buffered
*self
, PyObject
*args
)
501 CHECK_INITIALIZED(self
)
502 res
= PyObject_CallMethodObjArgs((PyObject
*)self
, _PyIO_str_flush
, NULL
);
516 buffered_seekable(buffered
*self
, PyObject
*args
)
518 CHECK_INITIALIZED(self
)
519 return PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_seekable
, NULL
);
523 buffered_readable(buffered
*self
, PyObject
*args
)
525 CHECK_INITIALIZED(self
)
526 return PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_readable
, NULL
);
530 buffered_writable(buffered
*self
, PyObject
*args
)
532 CHECK_INITIALIZED(self
)
533 return PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_writable
, NULL
);
537 buffered_name_get(buffered
*self
, void *context
)
539 CHECK_INITIALIZED(self
)
540 return PyObject_GetAttrString(self
->raw
, "name");
544 buffered_mode_get(buffered
*self
, void *context
)
546 CHECK_INITIALIZED(self
)
547 return PyObject_GetAttrString(self
->raw
, "mode");
550 /* Lower-level APIs */
553 buffered_fileno(buffered
*self
, PyObject
*args
)
555 CHECK_INITIALIZED(self
)
556 return PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_fileno
, NULL
);
560 buffered_isatty(buffered
*self
, PyObject
*args
)
562 CHECK_INITIALIZED(self
)
563 return PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_isatty
, NULL
);
569 _bufferedwriter_flush_unlocked(buffered
*);
571 _bufferedreader_fill_buffer(buffered
*self
);
573 _bufferedreader_reset_buf(buffered
*self
);
575 _bufferedwriter_reset_buf(buffered
*self
);
577 _bufferedreader_peek_unlocked(buffered
*self
, Py_ssize_t
);
579 _bufferedreader_read_all(buffered
*self
);
581 _bufferedreader_read_fast(buffered
*self
, Py_ssize_t
);
583 _bufferedreader_read_generic(buffered
*self
, Py_ssize_t
);
590 /* Sets the current error to BlockingIOError */
592 _set_BlockingIOError(char *msg
, Py_ssize_t written
)
595 err
= PyObject_CallFunction(PyExc_BlockingIOError
, "isn",
596 errno
, msg
, written
);
598 PyErr_SetObject(PyExc_BlockingIOError
, err
);
602 /* Returns the address of the `written` member if a BlockingIOError was
603 raised, NULL otherwise. The error is always re-raised. */
605 _buffered_check_blocking_error(void)
607 PyObject
*t
, *v
, *tb
;
608 PyBlockingIOErrorObject
*err
;
610 PyErr_Fetch(&t
, &v
, &tb
);
611 if (v
== NULL
|| !PyErr_GivenExceptionMatches(v
, PyExc_BlockingIOError
)) {
612 PyErr_Restore(t
, v
, tb
);
615 err
= (PyBlockingIOErrorObject
*) v
;
616 /* TODO: sanity check (err->written >= 0) */
617 PyErr_Restore(t
, v
, tb
);
618 return &err
->written
;
622 _buffered_raw_tell(buffered
*self
)
626 res
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_tell
, NULL
);
629 n
= PyNumber_AsOff_t(res
, PyExc_ValueError
);
632 if (!PyErr_Occurred())
633 PyErr_Format(PyExc_IOError
,
634 "Raw stream returned invalid position %" PY_PRIdOFF
,
643 _buffered_raw_seek(buffered
*self
, Py_off_t target
, int whence
)
645 PyObject
*res
, *posobj
, *whenceobj
;
648 posobj
= PyLong_FromOff_t(target
);
651 whenceobj
= PyLong_FromLong(whence
);
652 if (whenceobj
== NULL
) {
656 res
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_seek
,
657 posobj
, whenceobj
, NULL
);
659 Py_DECREF(whenceobj
);
662 n
= PyNumber_AsOff_t(res
, PyExc_ValueError
);
665 if (!PyErr_Occurred())
666 PyErr_Format(PyExc_IOError
,
667 "Raw stream returned invalid position %" PY_PRIdOFF
,
676 _buffered_init(buffered
*self
)
679 if (self
->buffer_size
<= 0) {
680 PyErr_SetString(PyExc_ValueError
,
681 "buffer size must be strictly positive");
685 PyMem_Free(self
->buffer
);
686 self
->buffer
= PyMem_Malloc(self
->buffer_size
);
687 if (self
->buffer
== NULL
) {
693 PyThread_free_lock(self
->lock
);
694 self
->lock
= PyThread_allocate_lock();
695 if (self
->lock
== NULL
) {
696 PyErr_SetString(PyExc_RuntimeError
, "can't allocate read lock");
701 /* Find out whether buffer_size is a power of 2 */
702 /* XXX is this optimization useful? */
703 for (n
= self
->buffer_size
- 1; n
& 1; n
>>= 1)
706 self
->buffer_mask
= self
->buffer_size
- 1;
708 self
->buffer_mask
= 0;
709 if (_buffered_raw_tell(self
) == -1)
714 /* Return 1 if an EnvironmentError with errno == EINTR is set (and then
715 clears the error indicator), 0 otherwise.
716 Should only be called when PyErr_Occurred() is true.
719 _PyIO_trap_eintr(void)
721 static PyObject
*eintr_int
= NULL
;
722 PyObject
*typ
, *val
, *tb
;
723 PyEnvironmentErrorObject
*env_err
;
725 if (eintr_int
== NULL
) {
726 eintr_int
= PyLong_FromLong(EINTR
);
727 assert(eintr_int
!= NULL
);
729 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError
))
731 PyErr_Fetch(&typ
, &val
, &tb
);
732 PyErr_NormalizeException(&typ
, &val
, &tb
);
733 env_err
= (PyEnvironmentErrorObject
*) val
;
734 assert(env_err
!= NULL
);
735 if (env_err
->myerrno
!= NULL
&&
736 PyObject_RichCompareBool(env_err
->myerrno
, eintr_int
, Py_EQ
) > 0) {
742 /* This silences any error set by PyObject_RichCompareBool() */
743 PyErr_Restore(typ
, val
, tb
);
748 * Shared methods and wrappers
752 buffered_flush_and_rewind_unlocked(buffered
*self
)
756 res
= _bufferedwriter_flush_unlocked(self
);
761 if (self
->readable
) {
762 /* Rewind the raw stream so that its position corresponds to
763 the current logical position. */
765 n
= _buffered_raw_seek(self
, -RAW_OFFSET(self
), 1);
766 _bufferedreader_reset_buf(self
);
774 buffered_flush(buffered
*self
, PyObject
*args
)
778 CHECK_INITIALIZED(self
)
779 CHECK_CLOSED(self
, "flush of closed file")
781 if (!ENTER_BUFFERED(self
))
783 res
= buffered_flush_and_rewind_unlocked(self
);
790 buffered_peek(buffered
*self
, PyObject
*args
)
793 PyObject
*res
= NULL
;
795 CHECK_INITIALIZED(self
)
796 if (!PyArg_ParseTuple(args
, "|n:peek", &n
)) {
800 if (!ENTER_BUFFERED(self
))
803 if (self
->writable
) {
804 res
= buffered_flush_and_rewind_unlocked(self
);
809 res
= _bufferedreader_peek_unlocked(self
, n
);
817 buffered_read(buffered
*self
, PyObject
*args
)
822 CHECK_INITIALIZED(self
)
823 if (!PyArg_ParseTuple(args
, "|O&:read", &_PyIO_ConvertSsize_t
, &n
)) {
827 PyErr_SetString(PyExc_ValueError
,
828 "read length must be positive or -1");
832 CHECK_CLOSED(self
, "read of closed file")
835 /* The number of bytes is unspecified, read until the end of stream */
836 if (!ENTER_BUFFERED(self
))
838 res
= _bufferedreader_read_all(self
);
841 res
= _bufferedreader_read_fast(self
, n
);
845 if (!ENTER_BUFFERED(self
))
847 res
= _bufferedreader_read_generic(self
, n
);
855 buffered_read1(buffered
*self
, PyObject
*args
)
857 Py_ssize_t n
, have
, r
;
858 PyObject
*res
= NULL
;
860 CHECK_INITIALIZED(self
)
861 if (!PyArg_ParseTuple(args
, "n:read1", &n
)) {
866 PyErr_SetString(PyExc_ValueError
,
867 "read length must be positive");
871 return PyBytes_FromStringAndSize(NULL
, 0);
873 if (!ENTER_BUFFERED(self
))
876 /* Return up to n bytes. If at least one byte is buffered, we
877 only return buffered bytes. Otherwise, we do one raw read. */
879 /* XXX: this mimicks the io.py implementation but is probably wrong.
880 If we need to read from the raw stream, then we could actually read
881 all `n` bytes asked by the caller (and possibly more, so as to fill
882 our buffer for the next reads). */
884 have
= Py_SAFE_DOWNCAST(READAHEAD(self
), Py_off_t
, Py_ssize_t
);
888 res
= PyBytes_FromStringAndSize(self
->buffer
+ self
->pos
, n
);
895 if (self
->writable
) {
896 res
= buffered_flush_and_rewind_unlocked(self
);
902 /* Fill the buffer from the raw stream, and copy it to the result. */
903 _bufferedreader_reset_buf(self
);
904 r
= _bufferedreader_fill_buffer(self
);
911 res
= PyBytes_FromStringAndSize(self
->buffer
, n
);
922 buffered_readinto(buffered
*self
, PyObject
*args
)
924 CHECK_INITIALIZED(self
)
926 /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
927 return bufferediobase_readinto((PyObject
*)self
, args
);
931 _buffered_readline(buffered
*self
, Py_ssize_t limit
)
933 PyObject
*res
= NULL
;
934 PyObject
*chunks
= NULL
;
935 Py_ssize_t n
, written
= 0;
936 const char *start
, *s
, *end
;
938 CHECK_CLOSED(self
, "readline of closed file")
940 /* First, try to find a line in the buffer. This can run unlocked because
941 the calls to the C API are simple enough that they can't trigger
942 any thread switch. */
943 n
= Py_SAFE_DOWNCAST(READAHEAD(self
), Py_off_t
, Py_ssize_t
);
944 if (limit
>= 0 && n
> limit
)
946 start
= self
->buffer
+ self
->pos
;
947 s
= memchr(start
, '\n', n
);
949 res
= PyBytes_FromStringAndSize(start
, s
- start
+ 1);
951 self
->pos
+= s
- start
+ 1;
955 res
= PyBytes_FromStringAndSize(start
, n
);
961 if (!ENTER_BUFFERED(self
))
964 /* Now we try to get some more from the raw stream */
965 chunks
= PyList_New(0);
969 res
= PyBytes_FromStringAndSize(start
, n
);
972 if (PyList_Append(chunks
, res
) < 0) {
982 if (self
->writable
) {
983 PyObject
*r
= buffered_flush_and_rewind_unlocked(self
);
990 _bufferedreader_reset_buf(self
);
991 n
= _bufferedreader_fill_buffer(self
);
996 if (limit
>= 0 && n
> limit
)
998 start
= self
->buffer
;
1003 res
= PyBytes_FromStringAndSize(start
, s
- start
);
1006 self
->pos
= s
- start
;
1010 res
= PyBytes_FromStringAndSize(start
, n
);
1017 if (PyList_Append(chunks
, res
) < 0) {
1027 if (res
!= NULL
&& PyList_Append(chunks
, res
) < 0) {
1032 res
= _PyBytes_Join(_PyIO_empty_bytes
, chunks
);
1035 LEAVE_BUFFERED(self
)
1042 buffered_readline(buffered
*self
, PyObject
*args
)
1044 Py_ssize_t limit
= -1;
1046 CHECK_INITIALIZED(self
)
1047 if (!PyArg_ParseTuple(args
, "|O&:readline", &_PyIO_ConvertSsize_t
, &limit
))
1049 return _buffered_readline(self
, limit
);
1054 buffered_tell(buffered
*self
, PyObject
*args
)
1058 CHECK_INITIALIZED(self
)
1059 pos
= _buffered_raw_tell(self
);
1062 pos
-= RAW_OFFSET(self
);
1063 /* TODO: sanity check (pos >= 0) */
1064 return PyLong_FromOff_t(pos
);
1068 buffered_seek(buffered
*self
, PyObject
*args
)
1072 PyObject
*targetobj
, *res
= NULL
;
1074 CHECK_INITIALIZED(self
)
1075 if (!PyArg_ParseTuple(args
, "O|i:seek", &targetobj
, &whence
)) {
1078 if (whence
< 0 || whence
> 2) {
1079 PyErr_Format(PyExc_ValueError
,
1080 "whence must be between 0 and 2, not %d", whence
);
1084 CHECK_CLOSED(self
, "seek of closed file")
1086 target
= PyNumber_AsOff_t(targetobj
, PyExc_ValueError
);
1087 if (target
== -1 && PyErr_Occurred())
1090 if (whence
!= 2 && self
->readable
) {
1091 Py_off_t current
, avail
;
1092 /* Check if seeking leaves us inside the current buffer,
1093 so as to return quickly if possible. Also, we needn't take the
1094 lock in this fast path.
1095 Don't know how to do that when whence == 2, though. */
1096 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1097 state at this point. */
1098 current
= RAW_TELL(self
);
1099 avail
= READAHEAD(self
);
1103 offset
= target
- (current
- RAW_OFFSET(self
));
1106 if (offset
>= -self
->pos
&& offset
<= avail
) {
1107 self
->pos
+= offset
;
1108 return PyLong_FromOff_t(current
- avail
+ offset
);
1113 if (!ENTER_BUFFERED(self
))
1116 /* Fallback: invoke raw seek() method and clear buffer */
1117 if (self
->writable
) {
1118 res
= _bufferedwriter_flush_unlocked(self
);
1122 _bufferedwriter_reset_buf(self
);
1125 /* TODO: align on block boundary and read buffer if needed? */
1127 target
-= RAW_OFFSET(self
);
1128 n
= _buffered_raw_seek(self
, target
, whence
);
1132 res
= PyLong_FromOff_t(n
);
1133 if (res
!= NULL
&& self
->readable
)
1134 _bufferedreader_reset_buf(self
);
1137 LEAVE_BUFFERED(self
)
1142 buffered_truncate(buffered
*self
, PyObject
*args
)
1144 PyObject
*pos
= Py_None
;
1145 PyObject
*res
= NULL
;
1147 CHECK_INITIALIZED(self
)
1148 if (!PyArg_ParseTuple(args
, "|O:truncate", &pos
)) {
1152 if (!ENTER_BUFFERED(self
))
1155 if (self
->writable
) {
1156 res
= buffered_flush_and_rewind_unlocked(self
);
1161 res
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_truncate
, pos
, NULL
);
1164 /* Reset cached position */
1165 if (_buffered_raw_tell(self
) == -1)
1169 LEAVE_BUFFERED(self
)
1174 buffered_iternext(buffered
*self
)
1179 CHECK_INITIALIZED(self
);
1182 if (tp
== &PyBufferedReader_Type
||
1183 tp
== &PyBufferedRandom_Type
) {
1184 /* Skip method call overhead for speed */
1185 line
= _buffered_readline(self
, -1);
1188 line
= PyObject_CallMethodObjArgs((PyObject
*)self
,
1189 _PyIO_str_readline
, NULL
);
1190 if (line
&& !PyBytes_Check(line
)) {
1191 PyErr_Format(PyExc_IOError
,
1192 "readline() should have returned a bytes object, "
1193 "not '%.200s'", Py_TYPE(line
)->tp_name
);
1202 if (PyBytes_GET_SIZE(line
) == 0) {
1203 /* Reached EOF or would have blocked */
1212 buffered_repr(buffered
*self
)
1214 PyObject
*nameobj
, *res
;
1216 nameobj
= PyObject_GetAttrString((PyObject
*) self
, "name");
1217 if (nameobj
== NULL
) {
1218 if (PyErr_ExceptionMatches(PyExc_Exception
))
1222 res
= PyString_FromFormat("<%s>", Py_TYPE(self
)->tp_name
);
1225 PyObject
*repr
= PyObject_Repr(nameobj
);
1229 res
= PyString_FromFormat("<%s name=%s>",
1230 Py_TYPE(self
)->tp_name
,
1231 PyString_AS_STRING(repr
));
1238 * class BufferedReader
1241 PyDoc_STRVAR(bufferedreader_doc
,
1242 "Create a new buffered reader using the given readable raw IO object.");
1244 static void _bufferedreader_reset_buf(buffered
*self
)
1246 self
->read_end
= -1;
1250 bufferedreader_init(buffered
*self
, PyObject
*args
, PyObject
*kwds
)
1252 char *kwlist
[] = {"raw", "buffer_size", NULL
};
1253 Py_ssize_t buffer_size
= DEFAULT_BUFFER_SIZE
;
1259 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|n:BufferedReader", kwlist
,
1260 &raw
, &buffer_size
)) {
1264 if (_PyIOBase_check_readable(raw
, Py_True
) == NULL
)
1267 Py_CLEAR(self
->raw
);
1270 self
->buffer_size
= buffer_size
;
1274 if (_buffered_init(self
) < 0)
1276 _bufferedreader_reset_buf(self
);
1278 self
->fast_closed_checks
= (Py_TYPE(self
) == &PyBufferedReader_Type
&&
1279 Py_TYPE(raw
) == &PyFileIO_Type
);
1286 _bufferedreader_raw_read(buffered
*self
, char *start
, Py_ssize_t len
)
1289 PyObject
*memobj
, *res
;
1291 /* NOTE: the buffer needn't be released as its object is NULL. */
1292 if (PyBuffer_FillInfo(&buf
, NULL
, start
, len
, 0, PyBUF_CONTIG
) == -1)
1294 memobj
= PyMemoryView_FromBuffer(&buf
);
1297 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1298 occurs so we needn't do it ourselves.
1299 We then retry reading, ignoring the signal if no handler has
1300 raised (see issue #10956).
1303 res
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_readinto
, memobj
, NULL
);
1304 } while (res
== NULL
&& _PyIO_trap_eintr());
1308 if (res
== Py_None
) {
1309 /* Non-blocking stream would have blocked. Special return code! */
1313 n
= PyNumber_AsSsize_t(res
, PyExc_ValueError
);
1315 if (n
< 0 || n
> len
) {
1316 PyErr_Format(PyExc_IOError
,
1317 "raw readinto() returned invalid length %zd "
1318 "(should have been between 0 and %zd)", n
, len
);
1321 if (n
> 0 && self
->abs_pos
!= -1)
1327 _bufferedreader_fill_buffer(buffered
*self
)
1329 Py_ssize_t start
, len
, n
;
1330 if (VALID_READ_BUFFER(self
))
1331 start
= Py_SAFE_DOWNCAST(self
->read_end
, Py_off_t
, Py_ssize_t
);
1334 len
= self
->buffer_size
- start
;
1335 n
= _bufferedreader_raw_read(self
, self
->buffer
+ start
, len
);
1338 self
->read_end
= start
+ n
;
1339 self
->raw_pos
= start
+ n
;
1344 _bufferedreader_read_all(buffered
*self
)
1346 Py_ssize_t current_size
;
1347 PyObject
*res
, *data
= NULL
;
1348 PyObject
*chunks
= PyList_New(0);
1353 /* First copy what we have in the current buffer. */
1354 current_size
= Py_SAFE_DOWNCAST(READAHEAD(self
), Py_off_t
, Py_ssize_t
);
1356 data
= PyBytes_FromStringAndSize(
1357 self
->buffer
+ self
->pos
, current_size
);
1362 self
->pos
+= current_size
;
1364 /* We're going past the buffer's bounds, flush it */
1365 if (self
->writable
) {
1366 res
= buffered_flush_and_rewind_unlocked(self
);
1373 _bufferedreader_reset_buf(self
);
1376 if (PyList_Append(chunks
, data
) < 0) {
1384 /* Read until EOF or until read() would block. */
1385 data
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_read
, NULL
);
1390 if (data
!= Py_None
&& !PyBytes_Check(data
)) {
1393 PyErr_SetString(PyExc_TypeError
, "read() should return bytes");
1396 if (data
== Py_None
|| PyBytes_GET_SIZE(data
) == 0) {
1397 if (current_size
== 0) {
1402 res
= _PyBytes_Join(_PyIO_empty_bytes
, chunks
);
1408 current_size
+= PyBytes_GET_SIZE(data
);
1409 if (self
->abs_pos
!= -1)
1410 self
->abs_pos
+= PyBytes_GET_SIZE(data
);
1414 /* Read n bytes from the buffer if it can, otherwise return None.
1415 This function is simple enough that it can run unlocked. */
1417 _bufferedreader_read_fast(buffered
*self
, Py_ssize_t n
)
1419 Py_ssize_t current_size
;
1421 current_size
= Py_SAFE_DOWNCAST(READAHEAD(self
), Py_off_t
, Py_ssize_t
);
1422 if (n
<= current_size
) {
1423 /* Fast path: the data to read is fully buffered. */
1424 PyObject
*res
= PyBytes_FromStringAndSize(self
->buffer
+ self
->pos
, n
);
1432 /* Generic read function: read from the stream until enough bytes are read,
1433 * or until an EOF occurs or until read() would block.
1436 _bufferedreader_read_generic(buffered
*self
, Py_ssize_t n
)
1438 PyObject
*res
= NULL
;
1439 Py_ssize_t current_size
, remaining
, written
;
1442 current_size
= Py_SAFE_DOWNCAST(READAHEAD(self
), Py_off_t
, Py_ssize_t
);
1443 if (n
<= current_size
)
1444 return _bufferedreader_read_fast(self
, n
);
1446 res
= PyBytes_FromStringAndSize(NULL
, n
);
1449 out
= PyBytes_AS_STRING(res
);
1452 if (current_size
> 0) {
1453 memcpy(out
, self
->buffer
+ self
->pos
, current_size
);
1454 remaining
-= current_size
;
1455 written
+= current_size
;
1456 self
->pos
+= current_size
;
1458 /* Flush the write buffer if necessary */
1459 if (self
->writable
) {
1460 PyObject
*r
= buffered_flush_and_rewind_unlocked(self
);
1465 _bufferedreader_reset_buf(self
);
1466 while (remaining
> 0) {
1467 /* We want to read a whole block at the end into buffer.
1468 If we had readv() we could do this in one pass. */
1469 Py_ssize_t r
= MINUS_LAST_BLOCK(self
, remaining
);
1472 r
= _bufferedreader_raw_read(self
, out
+ written
, r
);
1475 if (r
== 0 || r
== -2) {
1476 /* EOF occurred or read() would block. */
1477 if (r
== 0 || written
> 0) {
1478 if (_PyBytes_Resize(&res
, written
))
1489 assert(remaining
<= self
->buffer_size
);
1493 /* NOTE: when the read is satisfied, we avoid issuing any additional
1494 reads, which could block indefinitely (e.g. on a socket).
1496 while (remaining
> 0 && self
->read_end
< self
->buffer_size
) {
1497 Py_ssize_t r
= _bufferedreader_fill_buffer(self
);
1500 if (r
== 0 || r
== -2) {
1501 /* EOF occurred or read() would block. */
1502 if (r
== 0 || written
> 0) {
1503 if (_PyBytes_Resize(&res
, written
))
1511 if (remaining
> r
) {
1512 memcpy(out
+ written
, self
->buffer
+ self
->pos
, r
);
1517 else if (remaining
> 0) {
1518 memcpy(out
+ written
, self
->buffer
+ self
->pos
, remaining
);
1519 written
+= remaining
;
1520 self
->pos
+= remaining
;
1535 _bufferedreader_peek_unlocked(buffered
*self
, Py_ssize_t n
)
1539 have
= Py_SAFE_DOWNCAST(READAHEAD(self
), Py_off_t
, Py_ssize_t
);
1541 1. we don't want to advance the file position.
1542 2. we don't want to lose block alignment, so we can't shift the buffer
1544 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1547 return PyBytes_FromStringAndSize(self
->buffer
+ self
->pos
, have
);
1550 /* Fill the buffer from the raw stream, and copy it to the result. */
1551 _bufferedreader_reset_buf(self
);
1552 r
= _bufferedreader_fill_buffer(self
);
1558 return PyBytes_FromStringAndSize(self
->buffer
, r
);
1561 static PyMethodDef bufferedreader_methods
[] = {
1562 /* BufferedIOMixin methods */
1563 {"detach", (PyCFunction
)buffered_detach
, METH_NOARGS
},
1564 {"flush", (PyCFunction
)buffered_simple_flush
, METH_NOARGS
},
1565 {"close", (PyCFunction
)buffered_close
, METH_NOARGS
},
1566 {"seekable", (PyCFunction
)buffered_seekable
, METH_NOARGS
},
1567 {"readable", (PyCFunction
)buffered_readable
, METH_NOARGS
},
1568 {"writable", (PyCFunction
)buffered_writable
, METH_NOARGS
},
1569 {"fileno", (PyCFunction
)buffered_fileno
, METH_NOARGS
},
1570 {"isatty", (PyCFunction
)buffered_isatty
, METH_NOARGS
},
1572 {"read", (PyCFunction
)buffered_read
, METH_VARARGS
},
1573 {"peek", (PyCFunction
)buffered_peek
, METH_VARARGS
},
1574 {"read1", (PyCFunction
)buffered_read1
, METH_VARARGS
},
1575 {"readline", (PyCFunction
)buffered_readline
, METH_VARARGS
},
1576 {"seek", (PyCFunction
)buffered_seek
, METH_VARARGS
},
1577 {"tell", (PyCFunction
)buffered_tell
, METH_NOARGS
},
1578 {"truncate", (PyCFunction
)buffered_truncate
, METH_VARARGS
},
1579 {"__sizeof__", (PyCFunction
)buffered_sizeof
, METH_NOARGS
},
1583 static PyMemberDef bufferedreader_members
[] = {
1584 {"raw", T_OBJECT
, offsetof(buffered
, raw
), READONLY
},
1588 static PyGetSetDef bufferedreader_getset
[] = {
1589 {"closed", (getter
)buffered_closed_get
, NULL
, NULL
},
1590 {"name", (getter
)buffered_name_get
, NULL
, NULL
},
1591 {"mode", (getter
)buffered_mode_get
, NULL
, NULL
},
1596 PyTypeObject PyBufferedReader_Type
= {
1597 PyVarObject_HEAD_INIT(NULL
, 0)
1598 "_io.BufferedReader", /*tp_name*/
1599 sizeof(buffered
), /*tp_basicsize*/
1601 (destructor
)buffered_dealloc
, /*tp_dealloc*/
1606 (reprfunc
)buffered_repr
, /*tp_repr*/
1608 0, /*tp_as_sequence*/
1609 0, /*tp_as_mapping*/
1616 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
1617 | Py_TPFLAGS_HAVE_GC
, /*tp_flags*/
1618 bufferedreader_doc
, /* tp_doc */
1619 (traverseproc
)buffered_traverse
, /* tp_traverse */
1620 (inquiry
)buffered_clear
, /* tp_clear */
1621 0, /* tp_richcompare */
1622 offsetof(buffered
, weakreflist
), /*tp_weaklistoffset*/
1624 (iternextfunc
)buffered_iternext
, /* tp_iternext */
1625 bufferedreader_methods
, /* tp_methods */
1626 bufferedreader_members
, /* tp_members */
1627 bufferedreader_getset
, /* tp_getset */
1630 0, /* tp_descr_get */
1631 0, /* tp_descr_set */
1632 offsetof(buffered
, dict
), /* tp_dictoffset */
1633 (initproc
)bufferedreader_init
, /* tp_init */
1635 PyType_GenericNew
, /* tp_new */
1641 complain_about_max_buffer_size(void)
1643 if (PyErr_WarnEx(PyExc_DeprecationWarning
,
1644 "max_buffer_size is deprecated", 1) < 0)
1650 * class BufferedWriter
1652 PyDoc_STRVAR(bufferedwriter_doc
,
1653 "A buffer for a writeable sequential RawIO object.\n"
1655 "The constructor creates a BufferedWriter for the given writeable raw\n"
1656 "stream. If the buffer_size is not given, it defaults to\n"
1657 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1661 _bufferedwriter_reset_buf(buffered
*self
)
1663 self
->write_pos
= 0;
1664 self
->write_end
= -1;
1668 bufferedwriter_init(buffered
*self
, PyObject
*args
, PyObject
*kwds
)
1670 /* TODO: properly deprecate max_buffer_size */
1671 char *kwlist
[] = {"raw", "buffer_size", "max_buffer_size", NULL
};
1672 Py_ssize_t buffer_size
= DEFAULT_BUFFER_SIZE
;
1673 Py_ssize_t max_buffer_size
= -234;
1679 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|nn:BufferedWriter", kwlist
,
1680 &raw
, &buffer_size
, &max_buffer_size
)) {
1684 if (max_buffer_size
!= -234 && !complain_about_max_buffer_size())
1687 if (_PyIOBase_check_writable(raw
, Py_True
) == NULL
)
1690 Py_CLEAR(self
->raw
);
1696 self
->buffer_size
= buffer_size
;
1697 if (_buffered_init(self
) < 0)
1699 _bufferedwriter_reset_buf(self
);
1702 self
->fast_closed_checks
= (Py_TYPE(self
) == &PyBufferedWriter_Type
&&
1703 Py_TYPE(raw
) == &PyFileIO_Type
);
1710 _bufferedwriter_raw_write(buffered
*self
, char *start
, Py_ssize_t len
)
1713 PyObject
*memobj
, *res
;
1716 /* NOTE: the buffer needn't be released as its object is NULL. */
1717 if (PyBuffer_FillInfo(&buf
, NULL
, start
, len
, 1, PyBUF_CONTIG_RO
) == -1)
1719 memobj
= PyMemoryView_FromBuffer(&buf
);
1722 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1723 occurs so we needn't do it ourselves.
1724 We then retry writing, ignoring the signal if no handler has
1725 raised (see issue #10956).
1729 res
= PyObject_CallMethodObjArgs(self
->raw
, _PyIO_str_write
, memobj
, NULL
);
1731 } while (res
== NULL
&& _PyIO_trap_eintr());
1735 if (res
== Py_None
) {
1736 /* Non-blocking stream would have blocked. Special return code!
1737 Being paranoid we reset errno in case it is changed by code
1738 triggered by a decref. errno is used by _set_BlockingIOError(). */
1743 n
= PyNumber_AsSsize_t(res
, PyExc_ValueError
);
1745 if (n
< 0 || n
> len
) {
1746 PyErr_Format(PyExc_IOError
,
1747 "raw write() returned invalid length %zd "
1748 "(should have been between 0 and %zd)", n
, len
);
1751 if (n
> 0 && self
->abs_pos
!= -1)
1756 /* `restore_pos` is 1 if we need to restore the raw stream position at
1757 the end, 0 otherwise. */
1759 _bufferedwriter_flush_unlocked(buffered
*self
)
1761 Py_ssize_t written
= 0;
1764 if (!VALID_WRITE_BUFFER(self
) || self
->write_pos
== self
->write_end
)
1767 rewind
= RAW_OFFSET(self
) + (self
->pos
- self
->write_pos
);
1769 n
= _buffered_raw_seek(self
, -rewind
, 1);
1773 self
->raw_pos
-= rewind
;
1775 while (self
->write_pos
< self
->write_end
) {
1776 n
= _bufferedwriter_raw_write(self
,
1777 self
->buffer
+ self
->write_pos
,
1778 Py_SAFE_DOWNCAST(self
->write_end
- self
->write_pos
,
1779 Py_off_t
, Py_ssize_t
));
1784 _set_BlockingIOError("write could not complete without blocking",
1788 self
->write_pos
+= n
;
1789 self
->raw_pos
= self
->write_pos
;
1790 written
+= Py_SAFE_DOWNCAST(n
, Py_off_t
, Py_ssize_t
);
1791 /* Partial writes can return successfully when interrupted by a
1792 signal (see write(2)). We must run signal handlers before
1793 blocking another time, possibly indefinitely. */
1794 if (PyErr_CheckSignals() < 0)
1798 _bufferedwriter_reset_buf(self
);
1808 bufferedwriter_write(buffered
*self
, PyObject
*args
)
1810 PyObject
*res
= NULL
;
1812 Py_ssize_t written
, avail
, remaining
;
1815 CHECK_INITIALIZED(self
)
1816 if (!PyArg_ParseTuple(args
, "s*:write", &buf
)) {
1820 if (IS_CLOSED(self
)) {
1821 PyErr_SetString(PyExc_ValueError
, "write to closed file");
1822 PyBuffer_Release(&buf
);
1826 if (!ENTER_BUFFERED(self
)) {
1827 PyBuffer_Release(&buf
);
1831 /* Fast path: the data to write can be fully buffered. */
1832 if (!VALID_READ_BUFFER(self
) && !VALID_WRITE_BUFFER(self
)) {
1836 avail
= Py_SAFE_DOWNCAST(self
->buffer_size
- self
->pos
, Py_off_t
, Py_ssize_t
);
1837 if (buf
.len
<= avail
) {
1838 memcpy(self
->buffer
+ self
->pos
, buf
.buf
, buf
.len
);
1839 if (!VALID_WRITE_BUFFER(self
) || self
->write_pos
> self
->pos
) {
1840 self
->write_pos
= self
->pos
;
1842 ADJUST_POSITION(self
, self
->pos
+ buf
.len
);
1843 if (self
->pos
> self
->write_end
)
1844 self
->write_end
= self
->pos
;
1849 /* First write the current buffer */
1850 res
= _bufferedwriter_flush_unlocked(self
);
1852 Py_ssize_t
*w
= _buffered_check_blocking_error();
1856 _bufferedreader_reset_buf(self
);
1857 /* Make some place by shifting the buffer. */
1858 assert(VALID_WRITE_BUFFER(self
));
1859 memmove(self
->buffer
, self
->buffer
+ self
->write_pos
,
1860 Py_SAFE_DOWNCAST(self
->write_end
- self
->write_pos
,
1861 Py_off_t
, Py_ssize_t
));
1862 self
->write_end
-= self
->write_pos
;
1863 self
->raw_pos
-= self
->write_pos
;
1864 self
->pos
-= self
->write_pos
;
1865 self
->write_pos
= 0;
1866 avail
= Py_SAFE_DOWNCAST(self
->buffer_size
- self
->write_end
,
1867 Py_off_t
, Py_ssize_t
);
1868 if (buf
.len
<= avail
) {
1869 /* Everything can be buffered */
1871 memcpy(self
->buffer
+ self
->write_end
, buf
.buf
, buf
.len
);
1872 self
->write_end
+= buf
.len
;
1873 self
->pos
+= buf
.len
;
1877 /* Buffer as much as possible. */
1878 memcpy(self
->buffer
+ self
->write_end
, buf
.buf
, avail
);
1879 self
->write_end
+= avail
;
1881 /* XXX Modifying the existing exception e using the pointer w
1882 will change e.characters_written but not e.args[2].
1883 Therefore we just replace with a new error. */
1884 _set_BlockingIOError("write could not complete without blocking",
1890 /* Adjust the raw stream position if it is away from the logical stream
1891 position. This happens if the read buffer has been filled but not
1892 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1893 the raw stream by itself).
1896 offset
= RAW_OFFSET(self
);
1898 if (_buffered_raw_seek(self
, -offset
, 1) < 0)
1900 self
->raw_pos
-= offset
;
1903 /* Then write buf itself. At this point the buffer has been emptied. */
1904 remaining
= buf
.len
;
1906 while (remaining
> self
->buffer_size
) {
1907 Py_ssize_t n
= _bufferedwriter_raw_write(
1908 self
, (char *) buf
.buf
+ written
, buf
.len
- written
);
1911 } else if (n
== -2) {
1912 /* Write failed because raw file is non-blocking */
1913 if (remaining
> self
->buffer_size
) {
1914 /* Can't buffer everything, still buffer as much as possible */
1915 memcpy(self
->buffer
,
1916 (char *) buf
.buf
+ written
, self
->buffer_size
);
1918 ADJUST_POSITION(self
, self
->buffer_size
);
1919 self
->write_end
= self
->buffer_size
;
1920 written
+= self
->buffer_size
;
1921 _set_BlockingIOError("write could not complete without "
1922 "blocking", written
);
1930 /* Partial writes can return successfully when interrupted by a
1931 signal (see write(2)). We must run signal handlers before
1932 blocking another time, possibly indefinitely. */
1933 if (PyErr_CheckSignals() < 0)
1937 _bufferedreader_reset_buf(self
);
1938 if (remaining
> 0) {
1939 memcpy(self
->buffer
, (char *) buf
.buf
+ written
, remaining
);
1940 written
+= remaining
;
1942 self
->write_pos
= 0;
1943 /* TODO: sanity check (remaining >= 0) */
1944 self
->write_end
= remaining
;
1945 ADJUST_POSITION(self
, remaining
);
1949 res
= PyLong_FromSsize_t(written
);
1952 LEAVE_BUFFERED(self
)
1953 PyBuffer_Release(&buf
);
1957 static PyMethodDef bufferedwriter_methods
[] = {
1958 /* BufferedIOMixin methods */
1959 {"close", (PyCFunction
)buffered_close
, METH_NOARGS
},
1960 {"detach", (PyCFunction
)buffered_detach
, METH_NOARGS
},
1961 {"seekable", (PyCFunction
)buffered_seekable
, METH_NOARGS
},
1962 {"readable", (PyCFunction
)buffered_readable
, METH_NOARGS
},
1963 {"writable", (PyCFunction
)buffered_writable
, METH_NOARGS
},
1964 {"fileno", (PyCFunction
)buffered_fileno
, METH_NOARGS
},
1965 {"isatty", (PyCFunction
)buffered_isatty
, METH_NOARGS
},
1967 {"write", (PyCFunction
)bufferedwriter_write
, METH_VARARGS
},
1968 {"truncate", (PyCFunction
)buffered_truncate
, METH_VARARGS
},
1969 {"flush", (PyCFunction
)buffered_flush
, METH_NOARGS
},
1970 {"seek", (PyCFunction
)buffered_seek
, METH_VARARGS
},
1971 {"tell", (PyCFunction
)buffered_tell
, METH_NOARGS
},
1972 {"__sizeof__", (PyCFunction
)buffered_sizeof
, METH_NOARGS
},
1976 static PyMemberDef bufferedwriter_members
[] = {
1977 {"raw", T_OBJECT
, offsetof(buffered
, raw
), READONLY
},
1981 static PyGetSetDef bufferedwriter_getset
[] = {
1982 {"closed", (getter
)buffered_closed_get
, NULL
, NULL
},
1983 {"name", (getter
)buffered_name_get
, NULL
, NULL
},
1984 {"mode", (getter
)buffered_mode_get
, NULL
, NULL
},
1989 PyTypeObject PyBufferedWriter_Type
= {
1990 PyVarObject_HEAD_INIT(NULL
, 0)
1991 "_io.BufferedWriter", /*tp_name*/
1992 sizeof(buffered
), /*tp_basicsize*/
1994 (destructor
)buffered_dealloc
, /*tp_dealloc*/
1999 (reprfunc
)buffered_repr
, /*tp_repr*/
2001 0, /*tp_as_sequence*/
2002 0, /*tp_as_mapping*/
2009 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
2010 | Py_TPFLAGS_HAVE_GC
, /*tp_flags*/
2011 bufferedwriter_doc
, /* tp_doc */
2012 (traverseproc
)buffered_traverse
, /* tp_traverse */
2013 (inquiry
)buffered_clear
, /* tp_clear */
2014 0, /* tp_richcompare */
2015 offsetof(buffered
, weakreflist
), /*tp_weaklistoffset*/
2017 0, /* tp_iternext */
2018 bufferedwriter_methods
, /* tp_methods */
2019 bufferedwriter_members
, /* tp_members */
2020 bufferedwriter_getset
, /* tp_getset */
2023 0, /* tp_descr_get */
2024 0, /* tp_descr_set */
2025 offsetof(buffered
, dict
), /* tp_dictoffset */
2026 (initproc
)bufferedwriter_init
, /* tp_init */
2028 PyType_GenericNew
, /* tp_new */
2037 PyDoc_STRVAR(bufferedrwpair_doc
,
2038 "A buffered reader and writer object together.\n"
2040 "A buffered reader object and buffered writer object put together to\n"
2041 "form a sequential IO object that can read and write. This is typically\n"
2042 "used with a socket or two-way pipe.\n"
2044 "reader and writer are RawIOBase objects that are readable and\n"
2045 "writeable respectively. If the buffer_size is omitted it defaults to\n"
2046 "DEFAULT_BUFFER_SIZE.\n"
2049 /* XXX The usefulness of this (compared to having two separate IO objects) is
2058 PyObject
*weakreflist
;
2062 bufferedrwpair_init(rwpair
*self
, PyObject
*args
, PyObject
*kwds
)
2064 PyObject
*reader
, *writer
;
2065 Py_ssize_t buffer_size
= DEFAULT_BUFFER_SIZE
;
2066 Py_ssize_t max_buffer_size
= -234;
2068 if (!PyArg_ParseTuple(args
, "OO|nn:BufferedRWPair", &reader
, &writer
,
2069 &buffer_size
, &max_buffer_size
)) {
2073 if (max_buffer_size
!= -234 && !complain_about_max_buffer_size())
2076 if (_PyIOBase_check_readable(reader
, Py_True
) == NULL
)
2078 if (_PyIOBase_check_writable(writer
, Py_True
) == NULL
)
2081 self
->reader
= (buffered
*) PyObject_CallFunction(
2082 (PyObject
*) &PyBufferedReader_Type
, "On", reader
, buffer_size
);
2083 if (self
->reader
== NULL
)
2086 self
->writer
= (buffered
*) PyObject_CallFunction(
2087 (PyObject
*) &PyBufferedWriter_Type
, "On", writer
, buffer_size
);
2088 if (self
->writer
== NULL
) {
2089 Py_CLEAR(self
->reader
);
2097 bufferedrwpair_traverse(rwpair
*self
, visitproc visit
, void *arg
)
2099 Py_VISIT(self
->dict
);
2104 bufferedrwpair_clear(rwpair
*self
)
2106 Py_CLEAR(self
->reader
);
2107 Py_CLEAR(self
->writer
);
2108 Py_CLEAR(self
->dict
);
2113 bufferedrwpair_dealloc(rwpair
*self
)
2115 _PyObject_GC_UNTRACK(self
);
2116 if (self
->weakreflist
!= NULL
)
2117 PyObject_ClearWeakRefs((PyObject
*)self
);
2118 Py_CLEAR(self
->reader
);
2119 Py_CLEAR(self
->writer
);
2120 Py_CLEAR(self
->dict
);
2121 Py_TYPE(self
)->tp_free((PyObject
*) self
);
2125 _forward_call(buffered
*self
, const char *name
, PyObject
*args
)
2127 PyObject
*func
, *ret
;
2129 PyErr_SetString(PyExc_ValueError
,
2130 "I/O operation on uninitialized object");
2134 func
= PyObject_GetAttrString((PyObject
*)self
, name
);
2136 PyErr_SetString(PyExc_AttributeError
, name
);
2140 ret
= PyObject_CallObject(func
, args
);
2146 bufferedrwpair_read(rwpair
*self
, PyObject
*args
)
2148 return _forward_call(self
->reader
, "read", args
);
2152 bufferedrwpair_peek(rwpair
*self
, PyObject
*args
)
2154 return _forward_call(self
->reader
, "peek", args
);
2158 bufferedrwpair_read1(rwpair
*self
, PyObject
*args
)
2160 return _forward_call(self
->reader
, "read1", args
);
2164 bufferedrwpair_readinto(rwpair
*self
, PyObject
*args
)
2166 return _forward_call(self
->reader
, "readinto", args
);
2170 bufferedrwpair_write(rwpair
*self
, PyObject
*args
)
2172 return _forward_call(self
->writer
, "write", args
);
2176 bufferedrwpair_flush(rwpair
*self
, PyObject
*args
)
2178 return _forward_call(self
->writer
, "flush", args
);
2182 bufferedrwpair_readable(rwpair
*self
, PyObject
*args
)
2184 return _forward_call(self
->reader
, "readable", args
);
2188 bufferedrwpair_writable(rwpair
*self
, PyObject
*args
)
2190 return _forward_call(self
->writer
, "writable", args
);
2194 bufferedrwpair_close(rwpair
*self
, PyObject
*args
)
2196 PyObject
*exc
= NULL
, *val
, *tb
;
2197 PyObject
*ret
= _forward_call(self
->writer
, "close", args
);
2199 PyErr_Fetch(&exc
, &val
, &tb
);
2202 ret
= _forward_call(self
->reader
, "close", args
);
2206 PyErr_Restore(exc
, val
, tb
);
2218 bufferedrwpair_isatty(rwpair
*self
, PyObject
*args
)
2220 PyObject
*ret
= _forward_call(self
->writer
, "isatty", args
);
2222 if (ret
!= Py_False
) {
2223 /* either True or exception */
2228 return _forward_call(self
->reader
, "isatty", args
);
2232 bufferedrwpair_closed_get(rwpair
*self
, void *context
)
2234 if (self
->writer
== NULL
) {
2235 PyErr_SetString(PyExc_RuntimeError
,
2236 "the BufferedRWPair object is being garbage-collected");
2239 return PyObject_GetAttr((PyObject
*) self
->writer
, _PyIO_str_closed
);
2242 static PyMethodDef bufferedrwpair_methods
[] = {
2243 {"read", (PyCFunction
)bufferedrwpair_read
, METH_VARARGS
},
2244 {"peek", (PyCFunction
)bufferedrwpair_peek
, METH_VARARGS
},
2245 {"read1", (PyCFunction
)bufferedrwpair_read1
, METH_VARARGS
},
2246 {"readinto", (PyCFunction
)bufferedrwpair_readinto
, METH_VARARGS
},
2248 {"write", (PyCFunction
)bufferedrwpair_write
, METH_VARARGS
},
2249 {"flush", (PyCFunction
)bufferedrwpair_flush
, METH_NOARGS
},
2251 {"readable", (PyCFunction
)bufferedrwpair_readable
, METH_NOARGS
},
2252 {"writable", (PyCFunction
)bufferedrwpair_writable
, METH_NOARGS
},
2254 {"close", (PyCFunction
)bufferedrwpair_close
, METH_NOARGS
},
2255 {"isatty", (PyCFunction
)bufferedrwpair_isatty
, METH_NOARGS
},
2260 static PyGetSetDef bufferedrwpair_getset
[] = {
2261 {"closed", (getter
)bufferedrwpair_closed_get
, NULL
, NULL
},
2265 PyTypeObject PyBufferedRWPair_Type
= {
2266 PyVarObject_HEAD_INIT(NULL
, 0)
2267 "_io.BufferedRWPair", /*tp_name*/
2268 sizeof(rwpair
), /*tp_basicsize*/
2270 (destructor
)bufferedrwpair_dealloc
, /*tp_dealloc*/
2277 0, /*tp_as_sequence*/
2278 0, /*tp_as_mapping*/
2285 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
2286 | Py_TPFLAGS_HAVE_GC
, /* tp_flags */
2287 bufferedrwpair_doc
, /* tp_doc */
2288 (traverseproc
)bufferedrwpair_traverse
, /* tp_traverse */
2289 (inquiry
)bufferedrwpair_clear
, /* tp_clear */
2290 0, /* tp_richcompare */
2291 offsetof(rwpair
, weakreflist
), /*tp_weaklistoffset*/
2293 0, /* tp_iternext */
2294 bufferedrwpair_methods
, /* tp_methods */
2296 bufferedrwpair_getset
, /* tp_getset */
2299 0, /* tp_descr_get */
2300 0, /* tp_descr_set */
2301 offsetof(rwpair
, dict
), /* tp_dictoffset */
2302 (initproc
)bufferedrwpair_init
, /* tp_init */
2304 PyType_GenericNew
, /* tp_new */
2313 PyDoc_STRVAR(bufferedrandom_doc
,
2314 "A buffered interface to random access streams.\n"
2316 "The constructor creates a reader and writer for a seekable stream,\n"
2317 "raw, given in the first argument. If the buffer_size is omitted it\n"
2318 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2322 bufferedrandom_init(buffered
*self
, PyObject
*args
, PyObject
*kwds
)
2324 char *kwlist
[] = {"raw", "buffer_size", "max_buffer_size", NULL
};
2325 Py_ssize_t buffer_size
= DEFAULT_BUFFER_SIZE
;
2326 Py_ssize_t max_buffer_size
= -234;
2332 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O|nn:BufferedRandom", kwlist
,
2333 &raw
, &buffer_size
, &max_buffer_size
)) {
2337 if (max_buffer_size
!= -234 && !complain_about_max_buffer_size())
2340 if (_PyIOBase_check_seekable(raw
, Py_True
) == NULL
)
2342 if (_PyIOBase_check_readable(raw
, Py_True
) == NULL
)
2344 if (_PyIOBase_check_writable(raw
, Py_True
) == NULL
)
2347 Py_CLEAR(self
->raw
);
2350 self
->buffer_size
= buffer_size
;
2354 if (_buffered_init(self
) < 0)
2356 _bufferedreader_reset_buf(self
);
2357 _bufferedwriter_reset_buf(self
);
2360 self
->fast_closed_checks
= (Py_TYPE(self
) == &PyBufferedRandom_Type
&&
2361 Py_TYPE(raw
) == &PyFileIO_Type
);
2367 static PyMethodDef bufferedrandom_methods
[] = {
2368 /* BufferedIOMixin methods */
2369 {"close", (PyCFunction
)buffered_close
, METH_NOARGS
},
2370 {"detach", (PyCFunction
)buffered_detach
, METH_NOARGS
},
2371 {"seekable", (PyCFunction
)buffered_seekable
, METH_NOARGS
},
2372 {"readable", (PyCFunction
)buffered_readable
, METH_NOARGS
},
2373 {"writable", (PyCFunction
)buffered_writable
, METH_NOARGS
},
2374 {"fileno", (PyCFunction
)buffered_fileno
, METH_NOARGS
},
2375 {"isatty", (PyCFunction
)buffered_isatty
, METH_NOARGS
},
2377 {"flush", (PyCFunction
)buffered_flush
, METH_NOARGS
},
2379 {"seek", (PyCFunction
)buffered_seek
, METH_VARARGS
},
2380 {"tell", (PyCFunction
)buffered_tell
, METH_NOARGS
},
2381 {"truncate", (PyCFunction
)buffered_truncate
, METH_VARARGS
},
2382 {"read", (PyCFunction
)buffered_read
, METH_VARARGS
},
2383 {"read1", (PyCFunction
)buffered_read1
, METH_VARARGS
},
2384 {"readinto", (PyCFunction
)buffered_readinto
, METH_VARARGS
},
2385 {"readline", (PyCFunction
)buffered_readline
, METH_VARARGS
},
2386 {"peek", (PyCFunction
)buffered_peek
, METH_VARARGS
},
2387 {"write", (PyCFunction
)bufferedwriter_write
, METH_VARARGS
},
2388 {"__sizeof__", (PyCFunction
)buffered_sizeof
, METH_NOARGS
},
2392 static PyMemberDef bufferedrandom_members
[] = {
2393 {"raw", T_OBJECT
, offsetof(buffered
, raw
), READONLY
},
2397 static PyGetSetDef bufferedrandom_getset
[] = {
2398 {"closed", (getter
)buffered_closed_get
, NULL
, NULL
},
2399 {"name", (getter
)buffered_name_get
, NULL
, NULL
},
2400 {"mode", (getter
)buffered_mode_get
, NULL
, NULL
},
2405 PyTypeObject PyBufferedRandom_Type
= {
2406 PyVarObject_HEAD_INIT(NULL
, 0)
2407 "_io.BufferedRandom", /*tp_name*/
2408 sizeof(buffered
), /*tp_basicsize*/
2410 (destructor
)buffered_dealloc
, /*tp_dealloc*/
2415 (reprfunc
)buffered_repr
, /*tp_repr*/
2417 0, /*tp_as_sequence*/
2418 0, /*tp_as_mapping*/
2425 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
2426 | Py_TPFLAGS_HAVE_GC
, /*tp_flags*/
2427 bufferedrandom_doc
, /* tp_doc */
2428 (traverseproc
)buffered_traverse
, /* tp_traverse */
2429 (inquiry
)buffered_clear
, /* tp_clear */
2430 0, /* tp_richcompare */
2431 offsetof(buffered
, weakreflist
), /*tp_weaklistoffset*/
2433 (iternextfunc
)buffered_iternext
, /* tp_iternext */
2434 bufferedrandom_methods
, /* tp_methods */
2435 bufferedrandom_members
, /* tp_members */
2436 bufferedrandom_getset
, /* tp_getset */
2439 0, /* tp_descr_get */
2440 0, /* tp_descr_set */
2441 offsetof(buffered
, dict
), /*tp_dictoffset*/
2442 (initproc
)bufferedrandom_init
, /* tp_init */
2444 PyType_GenericNew
, /* tp_new */