1 /*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
3
4 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
6
7 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8 */
9
10 #define PY_SSIZE_T_CLEAN
11 #include "Python.h"
12 #include "structmember.h"
13 #include "pythread.h"
14 #include "_iomodule.h"
15
16 /*
17 * BufferedIOBase class, inherits from IOBase.
18 */
19 PyDoc_STRVAR(bufferediobase_doc,
20 "Base class for buffered IO objects.\n"
21 "\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"
25 "\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"
29 "return None.\n"
30 "\n"
31 "A typical implementation should not inherit from a RawIOBase\n"
32 "implementation, but wrap one.\n"
33 );
34
35 static PyObject *
bufferediobase_readinto(PyObject * self,PyObject * args)36 bufferediobase_readinto(PyObject *self, PyObject *args)
37 {
38 Py_buffer buf;
39 Py_ssize_t len;
40 PyObject *data;
41
42 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
43 return NULL;
44 }
45
46 data = PyObject_CallMethod(self, "read", "n", buf.len);
47 if (data == NULL)
48 goto error;
49
50 if (!PyBytes_Check(data)) {
51 Py_DECREF(data);
52 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
53 goto error;
54 }
55
56 len = Py_SIZE(data);
57 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
58
59 PyBuffer_Release(&buf);
60 Py_DECREF(data);
61
62 return PyLong_FromSsize_t(len);
63
64 error:
65 PyBuffer_Release(&buf);
66 return NULL;
67 }
68
69 static PyObject *
bufferediobase_unsupported(const char * message)70 bufferediobase_unsupported(const char *message)
71 {
72 PyErr_SetString(_PyIO_unsupported_operation, message);
73 return NULL;
74 }
75
76 PyDoc_STRVAR(bufferediobase_detach_doc,
77 "Disconnect this buffer from its underlying raw stream and return it.\n"
78 "\n"
79 "After the raw stream has been detached, the buffer is in an unusable\n"
80 "state.\n");
81
82 static PyObject *
bufferediobase_detach(PyObject * self)83 bufferediobase_detach(PyObject *self)
84 {
85 return bufferediobase_unsupported("detach");
86 }
87
88 PyDoc_STRVAR(bufferediobase_read_doc,
89 "Read and return up to n bytes.\n"
90 "\n"
91 "If the argument is omitted, None, or negative, reads and\n"
92 "returns all data until EOF.\n"
93 "\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"
100 "\n"
101 "Returns an empty bytes object on EOF.\n"
102 "\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");
105
106 static PyObject *
bufferediobase_read(PyObject * self,PyObject * args)107 bufferediobase_read(PyObject *self, PyObject *args)
108 {
109 return bufferediobase_unsupported("read");
110 }
111
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"
116 "\n"
117 "Returns an empty bytes object on EOF.\n");
118
119 static PyObject *
bufferediobase_read1(PyObject * self,PyObject * args)120 bufferediobase_read1(PyObject *self, PyObject *args)
121 {
122 return bufferediobase_unsupported("read1");
123 }
124
125 PyDoc_STRVAR(bufferediobase_write_doc,
126 "Write the given buffer to the IO stream.\n"
127 "\n"
128 "Returns the number of bytes written, which is always len(b).\n"
129 "\n"
130 "Raises BlockingIOError if the buffer is full and the\n"
131 "underlying raw stream cannot accept more data at the moment.\n");
132
133 static PyObject *
bufferediobase_write(PyObject * self,PyObject * args)134 bufferediobase_write(PyObject *self, PyObject *args)
135 {
136 return bufferediobase_unsupported("write");
137 }
138
139
140 static PyMethodDef bufferediobase_methods[] = {
141 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
142 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
143 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
144 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
145 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
146 {NULL, NULL}
147 };
148
149 PyTypeObject PyBufferedIOBase_Type = {
150 PyVarObject_HEAD_INIT(NULL, 0)
151 "_io._BufferedIOBase", /*tp_name*/
152 0, /*tp_basicsize*/
153 0, /*tp_itemsize*/
154 0, /*tp_dealloc*/
155 0, /*tp_print*/
156 0, /*tp_getattr*/
157 0, /*tp_setattr*/
158 0, /*tp_compare */
159 0, /*tp_repr*/
160 0, /*tp_as_number*/
161 0, /*tp_as_sequence*/
162 0, /*tp_as_mapping*/
163 0, /*tp_hash */
164 0, /*tp_call*/
165 0, /*tp_str*/
166 0, /*tp_getattro*/
167 0, /*tp_setattro*/
168 0, /*tp_as_buffer*/
169 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
170 bufferediobase_doc, /* tp_doc */
171 0, /* tp_traverse */
172 0, /* tp_clear */
173 0, /* tp_richcompare */
174 0, /* tp_weaklistoffset */
175 0, /* tp_iter */
176 0, /* tp_iternext */
177 bufferediobase_methods, /* tp_methods */
178 0, /* tp_members */
179 0, /* tp_getset */
180 &PyIOBase_Type, /* tp_base */
181 0, /* tp_dict */
182 0, /* tp_descr_get */
183 0, /* tp_descr_set */
184 0, /* tp_dictoffset */
185 0, /* tp_init */
186 0, /* tp_alloc */
187 0, /* tp_new */
188 };
189
190
191 typedef struct {
192 PyObject_HEAD
193
194 PyObject *raw;
195 int ok; /* Initialized? */
196 int detached;
197 int readable;
198 int writable;
199
200 /* True if this is a vanilla Buffered object (rather than a user derived
201 class) *and* the raw stream is a vanilla FileIO object. */
202 int fast_closed_checks;
203
204 /* Absolute position inside the raw stream (-1 if unknown). */
205 Py_off_t abs_pos;
206
207 /* A static buffer of size `buffer_size` */
208 char *buffer;
209 /* Current logical position in the buffer. */
210 Py_off_t pos;
211 /* Position of the raw stream in the buffer. */
212 Py_off_t raw_pos;
213
214 /* Just after the last buffered byte in the buffer, or -1 if the buffer
215 isn't ready for reading. */
216 Py_off_t read_end;
217
218 /* Just after the last byte actually written */
219 Py_off_t write_pos;
220 /* Just after the last byte waiting to be written, or -1 if the buffer
221 isn't ready for writing. */
222 Py_off_t write_end;
223
224 #ifdef WITH_THREAD
225 PyThread_type_lock lock;
226 volatile long owner;
227 #endif
228
229 Py_ssize_t buffer_size;
230 Py_ssize_t buffer_mask;
231
232 PyObject *dict;
233 PyObject *weakreflist;
234 } buffered;
235
236 /*
237 Implementation notes:
238
239 * BufferedReader, BufferedWriter and BufferedRandom try to share most
240 methods (this is helped by the members `readable` and `writable`, which
241 are initialized in the respective constructors)
242 * They also share a single buffer for reading and writing. This enables
243 interleaved reads and writes without flushing. It also makes the logic
244 a bit trickier to get right.
245 * The absolute position of the raw stream is cached, if possible, in the
246 `abs_pos` member. It must be updated every time an operation is done
247 on the raw stream. If not sure, it can be reinitialized by calling
248 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
249 also does it). To read it, use RAW_TELL().
250 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
251 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
252
253 NOTE: we should try to maintain block alignment of reads and writes to the
254 raw stream (according to the buffer size), but for now it is only done
255 in read() and friends.
256
257 */
258
259 /* These macros protect the buffered object against concurrent operations. */
260
261 #ifdef WITH_THREAD
262
263 static int
_enter_buffered_busy(buffered * self)264 _enter_buffered_busy(buffered *self)
265 {
266 if (self->owner == PyThread_get_thread_ident()) {
267 PyObject *r = PyObject_Repr((PyObject *) self);
268 if (r != NULL) {
269 PyErr_Format(PyExc_RuntimeError,
270 "reentrant call inside %s",
271 PyString_AS_STRING(r));
272 Py_DECREF(r);
273 }
274 return 0;
275 }
276 Py_BEGIN_ALLOW_THREADS
277 PyThread_acquire_lock(self->lock, 1);
278 Py_END_ALLOW_THREADS
279 return 1;
280 }
281
282 #define ENTER_BUFFERED(self) \
283 ( (PyThread_acquire_lock(self->lock, 0) ? \
284 1 : _enter_buffered_busy(self)) \
285 && (self->owner = PyThread_get_thread_ident(), 1) )
286
287 #define LEAVE_BUFFERED(self) \
288 do { \
289 self->owner = 0; \
290 PyThread_release_lock(self->lock); \
291 } while(0);
292
293 #else
294 #define ENTER_BUFFERED(self) 1
295 #define LEAVE_BUFFERED(self)
296 #endif
297
298 #define CHECK_INITIALIZED(self) \
299 if (self->ok <= 0) { \
300 if (self->detached) { \
301 PyErr_SetString(PyExc_ValueError, \
302 "raw stream has been detached"); \
303 } else { \
304 PyErr_SetString(PyExc_ValueError, \
305 "I/O operation on uninitialized object"); \
306 } \
307 return NULL; \
308 }
309
310 #define CHECK_INITIALIZED_INT(self) \
311 if (self->ok <= 0) { \
312 if (self->detached) { \
313 PyErr_SetString(PyExc_ValueError, \
314 "raw stream has been detached"); \
315 } else { \
316 PyErr_SetString(PyExc_ValueError, \
317 "I/O operation on uninitialized object"); \
318 } \
319 return -1; \
320 }
321
322 #define IS_CLOSED(self) \
323 (self->fast_closed_checks \
324 ? _PyFileIO_closed(self->raw) \
325 : buffered_closed(self))
326
327 #define CHECK_CLOSED(self, error_msg) \
328 if (IS_CLOSED(self)) { \
329 PyErr_SetString(PyExc_ValueError, error_msg); \
330 return NULL; \
331 }
332
333
334 #define VALID_READ_BUFFER(self) \
335 (self->readable && self->read_end != -1)
336
337 #define VALID_WRITE_BUFFER(self) \
338 (self->writable && self->write_end != -1)
339
340 #define ADJUST_POSITION(self, _new_pos) \
341 do { \
342 self->pos = _new_pos; \
343 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
344 self->read_end = self->pos; \
345 } while(0)
346
347 #define READAHEAD(self) \
348 ((self->readable && VALID_READ_BUFFER(self)) \
349 ? (self->read_end - self->pos) : 0)
350
351 #define RAW_OFFSET(self) \
352 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
353 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
354
355 #define RAW_TELL(self) \
356 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
357
358 #define MINUS_LAST_BLOCK(self, size) \
359 (self->buffer_mask ? \
360 (size & ~self->buffer_mask) : \
361 (self->buffer_size * (size / self->buffer_size)))
362
363
364 static void
buffered_dealloc(buffered * self)365 buffered_dealloc(buffered *self)
366 {
367 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
368 return;
369 _PyObject_GC_UNTRACK(self);
370 self->ok = 0;
371 if (self->weakreflist != NULL)
372 PyObject_ClearWeakRefs((PyObject *)self);
373 Py_CLEAR(self->raw);
374 if (self->buffer) {
375 PyMem_Free(self->buffer);
376 self->buffer = NULL;
377 }
378 #ifdef WITH_THREAD
379 if (self->lock) {
380 PyThread_free_lock(self->lock);
381 self->lock = NULL;
382 }
383 #endif
384 Py_CLEAR(self->dict);
385 Py_TYPE(self)->tp_free((PyObject *)self);
386 }
387
388 static PyObject *
buffered_sizeof(buffered * self,void * unused)389 buffered_sizeof(buffered *self, void *unused)
390 {
391 Py_ssize_t res;
392
393 res = _PyObject_SIZE(Py_TYPE(self));
394 if (self->buffer)
395 res += self->buffer_size;
396 return PyLong_FromSsize_t(res);
397 }
398
399 static int
buffered_traverse(buffered * self,visitproc visit,void * arg)400 buffered_traverse(buffered *self, visitproc visit, void *arg)
401 {
402 Py_VISIT(self->raw);
403 Py_VISIT(self->dict);
404 return 0;
405 }
406
407 static int
buffered_clear(buffered * self)408 buffered_clear(buffered *self)
409 {
410 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
411 return -1;
412 self->ok = 0;
413 Py_CLEAR(self->raw);
414 Py_CLEAR(self->dict);
415 return 0;
416 }
417
418 /*
419 * _BufferedIOMixin methods
420 * This is not a class, just a collection of methods that will be reused
421 * by BufferedReader and BufferedWriter
422 */
423
424 /* Flush and close */
425
426 static PyObject *
buffered_simple_flush(buffered * self,PyObject * args)427 buffered_simple_flush(buffered *self, PyObject *args)
428 {
429 CHECK_INITIALIZED(self)
430 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
431 }
432
433 static int
buffered_closed(buffered * self)434 buffered_closed(buffered *self)
435 {
436 int closed;
437 PyObject *res;
438 CHECK_INITIALIZED_INT(self)
439 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
440 if (res == NULL)
441 return -1;
442 closed = PyObject_IsTrue(res);
443 Py_DECREF(res);
444 return closed;
445 }
446
447 static PyObject *
buffered_closed_get(buffered * self,void * context)448 buffered_closed_get(buffered *self, void *context)
449 {
450 CHECK_INITIALIZED(self)
451 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
452 }
453
454 static PyObject *
buffered_close(buffered * self,PyObject * args)455 buffered_close(buffered *self, PyObject *args)
456 {
457 PyObject *res = NULL, *exc = NULL, *val, *tb;
458 int r;
459
460 CHECK_INITIALIZED(self)
461 if (!ENTER_BUFFERED(self))
462 return NULL;
463
464 r = buffered_closed(self);
465 if (r < 0)
466 goto end;
467 if (r > 0) {
468 res = Py_None;
469 Py_INCREF(res);
470 goto end;
471 }
472 /* flush() will most probably re-take the lock, so drop it first */
473 LEAVE_BUFFERED(self)
474 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
475 if (!ENTER_BUFFERED(self))
476 return NULL;
477 if (res == NULL)
478 PyErr_Fetch(&exc, &val, &tb);
479 else
480 Py_DECREF(res);
481
482 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
483
484 if (exc != NULL) {
485 _PyErr_ReplaceException(exc, val, tb);
486 Py_CLEAR(res);
487 }
488
489 end:
490 LEAVE_BUFFERED(self)
491 return res;
492 }
493
494 /* detach */
495
496 static PyObject *
buffered_detach(buffered * self,PyObject * args)497 buffered_detach(buffered *self, PyObject *args)
498 {
499 PyObject *raw, *res;
500 CHECK_INITIALIZED(self)
501 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
502 if (res == NULL)
503 return NULL;
504 Py_DECREF(res);
505 raw = self->raw;
506 self->raw = NULL;
507 self->detached = 1;
508 self->ok = 0;
509 return raw;
510 }
511
512 /* Inquiries */
513
514 static PyObject *
buffered_seekable(buffered * self,PyObject * args)515 buffered_seekable(buffered *self, PyObject *args)
516 {
517 CHECK_INITIALIZED(self)
518 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
519 }
520
521 static PyObject *
buffered_readable(buffered * self,PyObject * args)522 buffered_readable(buffered *self, PyObject *args)
523 {
524 CHECK_INITIALIZED(self)
525 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
526 }
527
528 static PyObject *
buffered_writable(buffered * self,PyObject * args)529 buffered_writable(buffered *self, PyObject *args)
530 {
531 CHECK_INITIALIZED(self)
532 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
533 }
534
535 static PyObject *
buffered_name_get(buffered * self,void * context)536 buffered_name_get(buffered *self, void *context)
537 {
538 CHECK_INITIALIZED(self)
539 return PyObject_GetAttrString(self->raw, "name");
540 }
541
542 static PyObject *
buffered_mode_get(buffered * self,void * context)543 buffered_mode_get(buffered *self, void *context)
544 {
545 CHECK_INITIALIZED(self)
546 return PyObject_GetAttrString(self->raw, "mode");
547 }
548
549 /* Lower-level APIs */
550
551 static PyObject *
buffered_fileno(buffered * self,PyObject * args)552 buffered_fileno(buffered *self, PyObject *args)
553 {
554 CHECK_INITIALIZED(self)
555 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
556 }
557
558 static PyObject *
buffered_isatty(buffered * self,PyObject * args)559 buffered_isatty(buffered *self, PyObject *args)
560 {
561 CHECK_INITIALIZED(self)
562 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
563 }
564
565
566 /* Forward decls */
567 static PyObject *
568 _bufferedwriter_flush_unlocked(buffered *);
569 static Py_ssize_t
570 _bufferedreader_fill_buffer(buffered *self);
571 static void
572 _bufferedreader_reset_buf(buffered *self);
573 static void
574 _bufferedwriter_reset_buf(buffered *self);
575 static PyObject *
576 _bufferedreader_peek_unlocked(buffered *self, Py_ssize_t);
577 static PyObject *
578 _bufferedreader_read_all(buffered *self);
579 static PyObject *
580 _bufferedreader_read_fast(buffered *self, Py_ssize_t);
581 static PyObject *
582 _bufferedreader_read_generic(buffered *self, Py_ssize_t);
583
584
585 /*
586 * Helpers
587 */
588
589 /* Sets the current error to BlockingIOError */
590 static void
_set_BlockingIOError(char * msg,Py_ssize_t written)591 _set_BlockingIOError(char *msg, Py_ssize_t written)
592 {
593 PyObject *err;
594 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
595 errno, msg, written);
596 if (err)
597 PyErr_SetObject(PyExc_BlockingIOError, err);
598 Py_XDECREF(err);
599 }
600
601 /* Returns the address of the `written` member if a BlockingIOError was
602 raised, NULL otherwise. The error is always re-raised. */
603 static Py_ssize_t *
_buffered_check_blocking_error(void)604 _buffered_check_blocking_error(void)
605 {
606 PyObject *t, *v, *tb;
607 PyBlockingIOErrorObject *err;
608
609 PyErr_Fetch(&t, &v, &tb);
610 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
611 PyErr_Restore(t, v, tb);
612 return NULL;
613 }
614 err = (PyBlockingIOErrorObject *) v;
615 /* TODO: sanity check (err->written >= 0) */
616 PyErr_Restore(t, v, tb);
617 return &err->written;
618 }
619
620 static Py_off_t
_buffered_raw_tell(buffered * self)621 _buffered_raw_tell(buffered *self)
622 {
623 Py_off_t n;
624 PyObject *res;
625 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
626 if (res == NULL)
627 return -1;
628 n = PyNumber_AsOff_t(res, PyExc_ValueError);
629 Py_DECREF(res);
630 if (n < 0) {
631 if (!PyErr_Occurred())
632 PyErr_Format(PyExc_IOError,
633 "Raw stream returned invalid position %" PY_PRIdOFF,
634 (PY_OFF_T_COMPAT)n);
635 return -1;
636 }
637 self->abs_pos = n;
638 return n;
639 }
640
641 static Py_off_t
_buffered_raw_seek(buffered * self,Py_off_t target,int whence)642 _buffered_raw_seek(buffered *self, Py_off_t target, int whence)
643 {
644 PyObject *res, *posobj, *whenceobj;
645 Py_off_t n;
646
647 posobj = PyLong_FromOff_t(target);
648 if (posobj == NULL)
649 return -1;
650 whenceobj = PyLong_FromLong(whence);
651 if (whenceobj == NULL) {
652 Py_DECREF(posobj);
653 return -1;
654 }
655 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
656 posobj, whenceobj, NULL);
657 Py_DECREF(posobj);
658 Py_DECREF(whenceobj);
659 if (res == NULL)
660 return -1;
661 n = PyNumber_AsOff_t(res, PyExc_ValueError);
662 Py_DECREF(res);
663 if (n < 0) {
664 if (!PyErr_Occurred())
665 PyErr_Format(PyExc_IOError,
666 "Raw stream returned invalid position %" PY_PRIdOFF,
667 (PY_OFF_T_COMPAT)n);
668 return -1;
669 }
670 self->abs_pos = n;
671 return n;
672 }
673
674 static int
_buffered_init(buffered * self)675 _buffered_init(buffered *self)
676 {
677 Py_ssize_t n;
678 if (self->buffer_size <= 0) {
679 PyErr_SetString(PyExc_ValueError,
680 "buffer size must be strictly positive");
681 return -1;
682 }
683 if (self->buffer)
684 PyMem_Free(self->buffer);
685 self->buffer = PyMem_Malloc(self->buffer_size);
686 if (self->buffer == NULL) {
687 PyErr_NoMemory();
688 return -1;
689 }
690 #ifdef WITH_THREAD
691 if (self->lock)
692 PyThread_free_lock(self->lock);
693 self->lock = PyThread_allocate_lock();
694 if (self->lock == NULL) {
695 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
696 return -1;
697 }
698 self->owner = 0;
699 #endif
700 /* Find out whether buffer_size is a power of 2 */
701 /* XXX is this optimization useful? */
702 for (n = self->buffer_size - 1; n & 1; n >>= 1)
703 ;
704 if (n == 0)
705 self->buffer_mask = self->buffer_size - 1;
706 else
707 self->buffer_mask = 0;
708 if (_buffered_raw_tell(self) == -1)
709 PyErr_Clear();
710 return 0;
711 }
712
713 /* Return 1 if an EnvironmentError with errno == EINTR is set (and then
714 clears the error indicator), 0 otherwise.
715 Should only be called when PyErr_Occurred() is true.
716 */
717 int
_PyIO_trap_eintr(void)718 _PyIO_trap_eintr(void)
719 {
720 static PyObject *eintr_int = NULL;
721 PyObject *typ, *val, *tb;
722 PyEnvironmentErrorObject *env_err;
723
724 if (eintr_int == NULL) {
725 eintr_int = PyLong_FromLong(EINTR);
726 assert(eintr_int != NULL);
727 }
728 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
729 return 0;
730 PyErr_Fetch(&typ, &val, &tb);
731 PyErr_NormalizeException(&typ, &val, &tb);
732 env_err = (PyEnvironmentErrorObject *) val;
733 assert(env_err != NULL);
734 if (env_err->myerrno != NULL &&
735 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
736 Py_DECREF(typ);
737 Py_DECREF(val);
738 Py_XDECREF(tb);
739 return 1;
740 }
741 /* This silences any error set by PyObject_RichCompareBool() */
742 PyErr_Restore(typ, val, tb);
743 return 0;
744 }
745
746 /*
747 * Shared methods and wrappers
748 */
749
750 static PyObject *
buffered_flush_and_rewind_unlocked(buffered * self)751 buffered_flush_and_rewind_unlocked(buffered *self)
752 {
753 PyObject *res;
754
755 res = _bufferedwriter_flush_unlocked(self);
756 if (res == NULL)
757 return NULL;
758 Py_DECREF(res);
759
760 if (self->readable) {
761 /* Rewind the raw stream so that its position corresponds to
762 the current logical position. */
763 Py_off_t n;
764 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
765 _bufferedreader_reset_buf(self);
766 if (n == -1)
767 return NULL;
768 }
769 Py_RETURN_NONE;
770 }
771
772 static PyObject *
buffered_flush(buffered * self,PyObject * args)773 buffered_flush(buffered *self, PyObject *args)
774 {
775 PyObject *res;
776
777 CHECK_INITIALIZED(self)
778 CHECK_CLOSED(self, "flush of closed file")
779
780 if (!ENTER_BUFFERED(self))
781 return NULL;
782 res = buffered_flush_and_rewind_unlocked(self);
783 LEAVE_BUFFERED(self)
784
785 return res;
786 }
787
788 static PyObject *
buffered_peek(buffered * self,PyObject * args)789 buffered_peek(buffered *self, PyObject *args)
790 {
791 Py_ssize_t n = 0;
792 PyObject *res = NULL;
793
794 CHECK_INITIALIZED(self)
795 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
796 return NULL;
797 }
798
799 if (!ENTER_BUFFERED(self))
800 return NULL;
801
802 if (self->writable) {
803 res = buffered_flush_and_rewind_unlocked(self);
804 if (res == NULL)
805 goto end;
806 Py_CLEAR(res);
807 }
808 res = _bufferedreader_peek_unlocked(self, n);
809
810 end:
811 LEAVE_BUFFERED(self)
812 return res;
813 }
814
815 static PyObject *
buffered_read(buffered * self,PyObject * args)816 buffered_read(buffered *self, PyObject *args)
817 {
818 Py_ssize_t n = -1;
819 PyObject *res;
820
821 CHECK_INITIALIZED(self)
822 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
823 return NULL;
824 }
825 if (n < -1) {
826 PyErr_SetString(PyExc_ValueError,
827 "read length must be positive or -1");
828 return NULL;
829 }
830
831 CHECK_CLOSED(self, "read of closed file")
832
833 if (n == -1) {
834 /* The number of bytes is unspecified, read until the end of stream */
835 if (!ENTER_BUFFERED(self))
836 return NULL;
837 res = _bufferedreader_read_all(self);
838 }
839 else {
840 res = _bufferedreader_read_fast(self, n);
841 if (res != Py_None)
842 return res;
843 Py_DECREF(res);
844 if (!ENTER_BUFFERED(self))
845 return NULL;
846 res = _bufferedreader_read_generic(self, n);
847 }
848
849 LEAVE_BUFFERED(self)
850 return res;
851 }
852
853 static PyObject *
buffered_read1(buffered * self,PyObject * args)854 buffered_read1(buffered *self, PyObject *args)
855 {
856 Py_ssize_t n, have, r;
857 PyObject *res = NULL;
858
859 CHECK_INITIALIZED(self)
860 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
861 return NULL;
862 }
863
864 if (n < 0) {
865 PyErr_SetString(PyExc_ValueError,
866 "read length must be positive");
867 return NULL;
868 }
869 if (n == 0)
870 return PyBytes_FromStringAndSize(NULL, 0);
871
872 if (!ENTER_BUFFERED(self))
873 return NULL;
874
875 /* Return up to n bytes. If at least one byte is buffered, we
876 only return buffered bytes. Otherwise, we do one raw read. */
877
878 /* XXX: this mimicks the io.py implementation but is probably wrong.
879 If we need to read from the raw stream, then we could actually read
880 all `n` bytes asked by the caller (and possibly more, so as to fill
881 our buffer for the next reads). */
882
883 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
884 if (have > 0) {
885 if (n > have)
886 n = have;
887 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
888 if (res == NULL)
889 goto end;
890 self->pos += n;
891 goto end;
892 }
893
894 if (self->writable) {
895 res = buffered_flush_and_rewind_unlocked(self);
896 if (res == NULL)
897 goto end;
898 Py_DECREF(res);
899 }
900
901 /* Fill the buffer from the raw stream, and copy it to the result. */
902 _bufferedreader_reset_buf(self);
903 r = _bufferedreader_fill_buffer(self);
904 if (r == -1)
905 goto end;
906 if (r == -2)
907 r = 0;
908 if (n > r)
909 n = r;
910 res = PyBytes_FromStringAndSize(self->buffer, n);
911 if (res == NULL)
912 goto end;
913 self->pos = n;
914
915 end:
916 LEAVE_BUFFERED(self)
917 return res;
918 }
919
920 static PyObject *
buffered_readinto(buffered * self,PyObject * args)921 buffered_readinto(buffered *self, PyObject *args)
922 {
923 CHECK_INITIALIZED(self)
924
925 /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
926 return bufferediobase_readinto((PyObject *)self, args);
927 }
928
929 static PyObject *
_buffered_readline(buffered * self,Py_ssize_t limit)930 _buffered_readline(buffered *self, Py_ssize_t limit)
931 {
932 PyObject *res = NULL;
933 PyObject *chunks = NULL;
934 Py_ssize_t n, written = 0;
935 const char *start, *s, *end;
936
937 CHECK_CLOSED(self, "readline of closed file")
938
939 /* First, try to find a line in the buffer. This can run unlocked because
940 the calls to the C API are simple enough that they can't trigger
941 any thread switch. */
942 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
943 if (limit >= 0 && n > limit)
944 n = limit;
945 start = self->buffer + self->pos;
946 s = memchr(start, '\n', n);
947 if (s != NULL) {
948 res = PyBytes_FromStringAndSize(start, s - start + 1);
949 if (res != NULL)
950 self->pos += s - start + 1;
951 goto end_unlocked;
952 }
953 if (n == limit) {
954 res = PyBytes_FromStringAndSize(start, n);
955 if (res != NULL)
956 self->pos += n;
957 goto end_unlocked;
958 }
959
960 if (!ENTER_BUFFERED(self))
961 goto end_unlocked;
962
963 /* Now we try to get some more from the raw stream */
964 chunks = PyList_New(0);
965 if (chunks == NULL)
966 goto end;
967 if (n > 0) {
968 res = PyBytes_FromStringAndSize(start, n);
969 if (res == NULL)
970 goto end;
971 if (PyList_Append(chunks, res) < 0) {
972 Py_CLEAR(res);
973 goto end;
974 }
975 Py_CLEAR(res);
976 written += n;
977 self->pos += n;
978 if (limit >= 0)
979 limit -= n;
980 }
981 if (self->writable) {
982 PyObject *r = buffered_flush_and_rewind_unlocked(self);
983 if (r == NULL)
984 goto end;
985 Py_DECREF(r);
986 }
987
988 for (;;) {
989 _bufferedreader_reset_buf(self);
990 n = _bufferedreader_fill_buffer(self);
991 if (n == -1)
992 goto end;
993 if (n <= 0)
994 break;
995 if (limit >= 0 && n > limit)
996 n = limit;
997 start = self->buffer;
998 end = start + n;
999 s = start;
1000 while (s < end) {
1001 if (*s++ == '\n') {
1002 res = PyBytes_FromStringAndSize(start, s - start);
1003 if (res == NULL)
1004 goto end;
1005 self->pos = s - start;
1006 goto found;
1007 }
1008 }
1009 res = PyBytes_FromStringAndSize(start, n);
1010 if (res == NULL)
1011 goto end;
1012 if (n == limit) {
1013 self->pos = n;
1014 break;
1015 }
1016 if (PyList_Append(chunks, res) < 0) {
1017 Py_CLEAR(res);
1018 goto end;
1019 }
1020 Py_CLEAR(res);
1021 written += n;
1022 if (limit >= 0)
1023 limit -= n;
1024 }
1025 found:
1026 if (res != NULL && PyList_Append(chunks, res) < 0) {
1027 Py_CLEAR(res);
1028 goto end;
1029 }
1030 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
1031
1032 end:
1033 LEAVE_BUFFERED(self)
1034 end_unlocked:
1035 Py_XDECREF(chunks);
1036 return res;
1037 }
1038
1039 static PyObject *
buffered_readline(buffered * self,PyObject * args)1040 buffered_readline(buffered *self, PyObject *args)
1041 {
1042 Py_ssize_t limit = -1;
1043
1044 CHECK_INITIALIZED(self)
1045 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
1046 return NULL;
1047 return _buffered_readline(self, limit);
1048 }
1049
1050
1051 static PyObject *
buffered_tell(buffered * self,PyObject * args)1052 buffered_tell(buffered *self, PyObject *args)
1053 {
1054 Py_off_t pos;
1055
1056 CHECK_INITIALIZED(self)
1057 pos = _buffered_raw_tell(self);
1058 if (pos == -1)
1059 return NULL;
1060 pos -= RAW_OFFSET(self);
1061 /* TODO: sanity check (pos >= 0) */
1062 return PyLong_FromOff_t(pos);
1063 }
1064
1065 static PyObject *
buffered_seek(buffered * self,PyObject * args)1066 buffered_seek(buffered *self, PyObject *args)
1067 {
1068 Py_off_t target, n;
1069 int whence = 0;
1070 PyObject *targetobj, *res = NULL;
1071
1072 CHECK_INITIALIZED(self)
1073 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1074 return NULL;
1075 }
1076 if (whence < 0 || whence > 2) {
1077 PyErr_Format(PyExc_ValueError,
1078 "whence must be between 0 and 2, not %d", whence);
1079 return NULL;
1080 }
1081
1082 CHECK_CLOSED(self, "seek of closed file")
1083
1084 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1085 if (target == -1 && PyErr_Occurred())
1086 return NULL;
1087
1088 if (whence != 2 && self->readable) {
1089 Py_off_t current, avail;
1090 /* Check if seeking leaves us inside the current buffer,
1091 so as to return quickly if possible. Also, we needn't take the
1092 lock in this fast path.
1093 Don't know how to do that when whence == 2, though. */
1094 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1095 state at this point. */
1096 current = RAW_TELL(self);
1097 avail = READAHEAD(self);
1098 if (avail > 0) {
1099 Py_off_t offset;
1100 if (whence == 0)
1101 offset = target - (current - RAW_OFFSET(self));
1102 else
1103 offset = target;
1104 if (offset >= -self->pos && offset <= avail) {
1105 self->pos += offset;
1106 return PyLong_FromOff_t(current - avail + offset);
1107 }
1108 }
1109 }
1110
1111 if (!ENTER_BUFFERED(self))
1112 return NULL;
1113
1114 /* Fallback: invoke raw seek() method and clear buffer */
1115 if (self->writable) {
1116 res = _bufferedwriter_flush_unlocked(self);
1117 if (res == NULL)
1118 goto end;
1119 Py_CLEAR(res);
1120 _bufferedwriter_reset_buf(self);
1121 }
1122
1123 /* TODO: align on block boundary and read buffer if needed? */
1124 if (whence == 1)
1125 target -= RAW_OFFSET(self);
1126 n = _buffered_raw_seek(self, target, whence);
1127 if (n == -1)
1128 goto end;
1129 self->raw_pos = -1;
1130 res = PyLong_FromOff_t(n);
1131 if (res != NULL && self->readable)
1132 _bufferedreader_reset_buf(self);
1133
1134 end:
1135 LEAVE_BUFFERED(self)
1136 return res;
1137 }
1138
1139 static PyObject *
buffered_truncate(buffered * self,PyObject * args)1140 buffered_truncate(buffered *self, PyObject *args)
1141 {
1142 PyObject *pos = Py_None;
1143 PyObject *res = NULL;
1144
1145 CHECK_INITIALIZED(self)
1146 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1147 return NULL;
1148 }
1149
1150 if (!ENTER_BUFFERED(self))
1151 return NULL;
1152
1153 if (self->writable) {
1154 res = buffered_flush_and_rewind_unlocked(self);
1155 if (res == NULL)
1156 goto end;
1157 Py_CLEAR(res);
1158 }
1159 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1160 if (res == NULL)
1161 goto end;
1162 /* Reset cached position */
1163 if (_buffered_raw_tell(self) == -1)
1164 PyErr_Clear();
1165
1166 end:
1167 LEAVE_BUFFERED(self)
1168 return res;
1169 }
1170
1171 static PyObject *
buffered_iternext(buffered * self)1172 buffered_iternext(buffered *self)
1173 {
1174 PyObject *line;
1175 PyTypeObject *tp;
1176
1177 CHECK_INITIALIZED(self);
1178
1179 tp = Py_TYPE(self);
1180 if (tp == &PyBufferedReader_Type ||
1181 tp == &PyBufferedRandom_Type) {
1182 /* Skip method call overhead for speed */
1183 line = _buffered_readline(self, -1);
1184 }
1185 else {
1186 line = PyObject_CallMethodObjArgs((PyObject *)self,
1187 _PyIO_str_readline, NULL);
1188 if (line && !PyBytes_Check(line)) {
1189 PyErr_Format(PyExc_IOError,
1190 "readline() should have returned a bytes object, "
1191 "not '%.200s'", Py_TYPE(line)->tp_name);
1192 Py_DECREF(line);
1193 return NULL;
1194 }
1195 }
1196
1197 if (line == NULL)
1198 return NULL;
1199
1200 if (PyBytes_GET_SIZE(line) == 0) {
1201 /* Reached EOF or would have blocked */
1202 Py_DECREF(line);
1203 return NULL;
1204 }
1205
1206 return line;
1207 }
1208
1209 static PyObject *
buffered_repr(buffered * self)1210 buffered_repr(buffered *self)
1211 {
1212 PyObject *nameobj, *res;
1213
1214 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1215 if (nameobj == NULL) {
1216 if (PyErr_ExceptionMatches(PyExc_Exception))
1217 PyErr_Clear();
1218 else
1219 return NULL;
1220 res = PyString_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1221 }
1222 else {
1223 PyObject *repr = PyObject_Repr(nameobj);
1224 Py_DECREF(nameobj);
1225 if (repr == NULL)
1226 return NULL;
1227 res = PyString_FromFormat("<%s name=%s>",
1228 Py_TYPE(self)->tp_name,
1229 PyString_AS_STRING(repr));
1230 Py_DECREF(repr);
1231 }
1232 return res;
1233 }
1234
1235 /*
1236 * class BufferedReader
1237 */
1238
1239 PyDoc_STRVAR(bufferedreader_doc,
1240 "Create a new buffered reader using the given readable raw IO object.");
1241
_bufferedreader_reset_buf(buffered * self)1242 static void _bufferedreader_reset_buf(buffered *self)
1243 {
1244 self->read_end = -1;
1245 }
1246
1247 static int
bufferedreader_init(buffered * self,PyObject * args,PyObject * kwds)1248 bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
1249 {
1250 char *kwlist[] = {"raw", "buffer_size", NULL};
1251 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1252 PyObject *raw;
1253
1254 self->ok = 0;
1255 self->detached = 0;
1256
1257 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1258 &raw, &buffer_size)) {
1259 return -1;
1260 }
1261
1262 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
1263 return -1;
1264
1265 Py_INCREF(raw);
1266 Py_XSETREF(self->raw, raw);
1267 self->buffer_size = buffer_size;
1268 self->readable = 1;
1269 self->writable = 0;
1270
1271 if (_buffered_init(self) < 0)
1272 return -1;
1273 _bufferedreader_reset_buf(self);
1274
1275 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1276 Py_TYPE(raw) == &PyFileIO_Type);
1277
1278 self->ok = 1;
1279 return 0;
1280 }
1281
1282 static Py_ssize_t
_bufferedreader_raw_read(buffered * self,char * start,Py_ssize_t len)1283 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
1284 {
1285 Py_buffer buf;
1286 PyObject *memobj, *res;
1287 Py_ssize_t n;
1288 /* NOTE: the buffer needn't be released as its object is NULL. */
1289 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1290 return -1;
1291 memobj = PyMemoryView_FromBuffer(&buf);
1292 if (memobj == NULL)
1293 return -1;
1294 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1295 occurs so we needn't do it ourselves.
1296 We then retry reading, ignoring the signal if no handler has
1297 raised (see issue #10956).
1298 */
1299 do {
1300 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1301 } while (res == NULL && _PyIO_trap_eintr());
1302 Py_DECREF(memobj);
1303 if (res == NULL)
1304 return -1;
1305 if (res == Py_None) {
1306 /* Non-blocking stream would have blocked. Special return code! */
1307 Py_DECREF(res);
1308 return -2;
1309 }
1310 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1311 Py_DECREF(res);
1312 if (n < 0 || n > len) {
1313 PyErr_Format(PyExc_IOError,
1314 "raw readinto() returned invalid length %zd "
1315 "(should have been between 0 and %zd)", n, len);
1316 return -1;
1317 }
1318 if (n > 0 && self->abs_pos != -1)
1319 self->abs_pos += n;
1320 return n;
1321 }
1322
1323 static Py_ssize_t
_bufferedreader_fill_buffer(buffered * self)1324 _bufferedreader_fill_buffer(buffered *self)
1325 {
1326 Py_ssize_t start, len, n;
1327 if (VALID_READ_BUFFER(self))
1328 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1329 else
1330 start = 0;
1331 len = self->buffer_size - start;
1332 n = _bufferedreader_raw_read(self, self->buffer + start, len);
1333 if (n <= 0)
1334 return n;
1335 self->read_end = start + n;
1336 self->raw_pos = start + n;
1337 return n;
1338 }
1339
1340 static PyObject *
_bufferedreader_read_all(buffered * self)1341 _bufferedreader_read_all(buffered *self)
1342 {
1343 Py_ssize_t current_size;
1344 PyObject *res, *data = NULL;
1345 PyObject *chunks = PyList_New(0);
1346
1347 if (chunks == NULL)
1348 return NULL;
1349
1350 /* First copy what we have in the current buffer. */
1351 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1352 if (current_size) {
1353 data = PyBytes_FromStringAndSize(
1354 self->buffer + self->pos, current_size);
1355 if (data == NULL) {
1356 Py_DECREF(chunks);
1357 return NULL;
1358 }
1359 self->pos += current_size;
1360 }
1361 /* We're going past the buffer's bounds, flush it */
1362 if (self->writable) {
1363 res = buffered_flush_and_rewind_unlocked(self);
1364 if (res == NULL) {
1365 Py_DECREF(chunks);
1366 return NULL;
1367 }
1368 Py_CLEAR(res);
1369 }
1370 _bufferedreader_reset_buf(self);
1371 while (1) {
1372 if (data) {
1373 if (PyList_Append(chunks, data) < 0) {
1374 Py_DECREF(data);
1375 Py_DECREF(chunks);
1376 return NULL;
1377 }
1378 Py_DECREF(data);
1379 }
1380
1381 /* Read until EOF or until read() would block. */
1382 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1383 if (data == NULL) {
1384 Py_DECREF(chunks);
1385 return NULL;
1386 }
1387 if (data != Py_None && !PyBytes_Check(data)) {
1388 Py_DECREF(data);
1389 Py_DECREF(chunks);
1390 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1391 return NULL;
1392 }
1393 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1394 if (current_size == 0) {
1395 Py_DECREF(chunks);
1396 return data;
1397 }
1398 else {
1399 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1400 Py_DECREF(data);
1401 Py_DECREF(chunks);
1402 return res;
1403 }
1404 }
1405 current_size += PyBytes_GET_SIZE(data);
1406 if (self->abs_pos != -1)
1407 self->abs_pos += PyBytes_GET_SIZE(data);
1408 }
1409 }
1410
1411 /* Read n bytes from the buffer if it can, otherwise return None.
1412 This function is simple enough that it can run unlocked. */
1413 static PyObject *
_bufferedreader_read_fast(buffered * self,Py_ssize_t n)1414 _bufferedreader_read_fast(buffered *self, Py_ssize_t n)
1415 {
1416 Py_ssize_t current_size;
1417
1418 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1419 if (n <= current_size) {
1420 /* Fast path: the data to read is fully buffered. */
1421 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1422 if (res != NULL)
1423 self->pos += n;
1424 return res;
1425 }
1426 Py_RETURN_NONE;
1427 }
1428
1429 /* Generic read function: read from the stream until enough bytes are read,
1430 * or until an EOF occurs or until read() would block.
1431 */
1432 static PyObject *
_bufferedreader_read_generic(buffered * self,Py_ssize_t n)1433 _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
1434 {
1435 PyObject *res = NULL;
1436 Py_ssize_t current_size, remaining, written;
1437 char *out;
1438
1439 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1440 if (n <= current_size)
1441 return _bufferedreader_read_fast(self, n);
1442
1443 res = PyBytes_FromStringAndSize(NULL, n);
1444 if (res == NULL)
1445 goto error;
1446 out = PyBytes_AS_STRING(res);
1447 remaining = n;
1448 written = 0;
1449 if (current_size > 0) {
1450 memcpy(out, self->buffer + self->pos, current_size);
1451 remaining -= current_size;
1452 written += current_size;
1453 self->pos += current_size;
1454 }
1455 /* Flush the write buffer if necessary */
1456 if (self->writable) {
1457 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1458 if (r == NULL)
1459 goto error;
1460 Py_DECREF(r);
1461 }
1462 _bufferedreader_reset_buf(self);
1463 while (remaining > 0) {
1464 /* We want to read a whole block at the end into buffer.
1465 If we had readv() we could do this in one pass. */
1466 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1467 if (r == 0)
1468 break;
1469 r = _bufferedreader_raw_read(self, out + written, r);
1470 if (r == -1)
1471 goto error;
1472 if (r == 0 || r == -2) {
1473 /* EOF occurred or read() would block. */
1474 if (r == 0 || written > 0) {
1475 if (_PyBytes_Resize(&res, written))
1476 goto error;
1477 return res;
1478 }
1479 Py_DECREF(res);
1480 Py_INCREF(Py_None);
1481 return Py_None;
1482 }
1483 remaining -= r;
1484 written += r;
1485 }
1486 assert(remaining <= self->buffer_size);
1487 self->pos = 0;
1488 self->raw_pos = 0;
1489 self->read_end = 0;
1490 /* NOTE: when the read is satisfied, we avoid issuing any additional
1491 reads, which could block indefinitely (e.g. on a socket).
1492 See issue #9550. */
1493 while (remaining > 0 && self->read_end < self->buffer_size) {
1494 Py_ssize_t r = _bufferedreader_fill_buffer(self);
1495 if (r == -1)
1496 goto error;
1497 if (r == 0 || r == -2) {
1498 /* EOF occurred or read() would block. */
1499 if (r == 0 || written > 0) {
1500 if (_PyBytes_Resize(&res, written))
1501 goto error;
1502 return res;
1503 }
1504 Py_DECREF(res);
1505 Py_INCREF(Py_None);
1506 return Py_None;
1507 }
1508 if (remaining > r) {
1509 memcpy(out + written, self->buffer + self->pos, r);
1510 written += r;
1511 self->pos += r;
1512 remaining -= r;
1513 }
1514 else if (remaining > 0) {
1515 memcpy(out + written, self->buffer + self->pos, remaining);
1516 written += remaining;
1517 self->pos += remaining;
1518 remaining = 0;
1519 }
1520 if (remaining == 0)
1521 break;
1522 }
1523
1524 return res;
1525
1526 error:
1527 Py_XDECREF(res);
1528 return NULL;
1529 }
1530
1531 static PyObject *
_bufferedreader_peek_unlocked(buffered * self,Py_ssize_t n)1532 _bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
1533 {
1534 Py_ssize_t have, r;
1535
1536 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1537 /* Constraints:
1538 1. we don't want to advance the file position.
1539 2. we don't want to lose block alignment, so we can't shift the buffer
1540 to make some place.
1541 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1542 */
1543 if (have > 0) {
1544 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1545 }
1546
1547 /* Fill the buffer from the raw stream, and copy it to the result. */
1548 _bufferedreader_reset_buf(self);
1549 r = _bufferedreader_fill_buffer(self);
1550 if (r == -1)
1551 return NULL;
1552 if (r == -2)
1553 r = 0;
1554 self->pos = 0;
1555 return PyBytes_FromStringAndSize(self->buffer, r);
1556 }
1557
1558 static PyMethodDef bufferedreader_methods[] = {
1559 /* BufferedIOMixin methods */
1560 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1561 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1562 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1563 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1564 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1565 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1566 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1567 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
1568
1569 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1570 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1571 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
1572 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1573 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1574 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1575 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1576 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
1577 {NULL, NULL}
1578 };
1579
1580 static PyMemberDef bufferedreader_members[] = {
1581 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
1582 {NULL}
1583 };
1584
1585 static PyGetSetDef bufferedreader_getset[] = {
1586 {"closed", (getter)buffered_closed_get, NULL, NULL},
1587 {"name", (getter)buffered_name_get, NULL, NULL},
1588 {"mode", (getter)buffered_mode_get, NULL, NULL},
1589 {NULL}
1590 };
1591
1592
1593 PyTypeObject PyBufferedReader_Type = {
1594 PyVarObject_HEAD_INIT(NULL, 0)
1595 "_io.BufferedReader", /*tp_name*/
1596 sizeof(buffered), /*tp_basicsize*/
1597 0, /*tp_itemsize*/
1598 (destructor)buffered_dealloc, /*tp_dealloc*/
1599 0, /*tp_print*/
1600 0, /*tp_getattr*/
1601 0, /*tp_setattr*/
1602 0, /*tp_compare */
1603 (reprfunc)buffered_repr, /*tp_repr*/
1604 0, /*tp_as_number*/
1605 0, /*tp_as_sequence*/
1606 0, /*tp_as_mapping*/
1607 0, /*tp_hash */
1608 0, /*tp_call*/
1609 0, /*tp_str*/
1610 0, /*tp_getattro*/
1611 0, /*tp_setattro*/
1612 0, /*tp_as_buffer*/
1613 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1614 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1615 bufferedreader_doc, /* tp_doc */
1616 (traverseproc)buffered_traverse, /* tp_traverse */
1617 (inquiry)buffered_clear, /* tp_clear */
1618 0, /* tp_richcompare */
1619 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
1620 0, /* tp_iter */
1621 (iternextfunc)buffered_iternext, /* tp_iternext */
1622 bufferedreader_methods, /* tp_methods */
1623 bufferedreader_members, /* tp_members */
1624 bufferedreader_getset, /* tp_getset */
1625 0, /* tp_base */
1626 0, /* tp_dict */
1627 0, /* tp_descr_get */
1628 0, /* tp_descr_set */
1629 offsetof(buffered, dict), /* tp_dictoffset */
1630 (initproc)bufferedreader_init, /* tp_init */
1631 0, /* tp_alloc */
1632 PyType_GenericNew, /* tp_new */
1633 };
1634
1635
1636
1637 static int
complain_about_max_buffer_size(void)1638 complain_about_max_buffer_size(void)
1639 {
1640 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1641 "max_buffer_size is deprecated", 1) < 0)
1642 return 0;
1643 return 1;
1644 }
1645
1646 /*
1647 * class BufferedWriter
1648 */
1649 PyDoc_STRVAR(bufferedwriter_doc,
1650 "A buffer for a writeable sequential RawIO object.\n"
1651 "\n"
1652 "The constructor creates a BufferedWriter for the given writeable raw\n"
1653 "stream. If the buffer_size is not given, it defaults to\n"
1654 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1655 );
1656
1657 static void
_bufferedwriter_reset_buf(buffered * self)1658 _bufferedwriter_reset_buf(buffered *self)
1659 {
1660 self->write_pos = 0;
1661 self->write_end = -1;
1662 }
1663
1664 static int
bufferedwriter_init(buffered * self,PyObject * args,PyObject * kwds)1665 bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
1666 {
1667 /* TODO: properly deprecate max_buffer_size */
1668 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1669 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1670 Py_ssize_t max_buffer_size = -234;
1671 PyObject *raw;
1672
1673 self->ok = 0;
1674 self->detached = 0;
1675
1676 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedWriter", kwlist,
1677 &raw, &buffer_size, &max_buffer_size)) {
1678 return -1;
1679 }
1680
1681 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1682 return -1;
1683
1684 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
1685 return -1;
1686
1687 Py_INCREF(raw);
1688 Py_XSETREF(self->raw, raw);
1689 self->readable = 0;
1690 self->writable = 1;
1691
1692 self->buffer_size = buffer_size;
1693 if (_buffered_init(self) < 0)
1694 return -1;
1695 _bufferedwriter_reset_buf(self);
1696 self->pos = 0;
1697
1698 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1699 Py_TYPE(raw) == &PyFileIO_Type);
1700
1701 self->ok = 1;
1702 return 0;
1703 }
1704
1705 static Py_ssize_t
_bufferedwriter_raw_write(buffered * self,char * start,Py_ssize_t len)1706 _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
1707 {
1708 Py_buffer buf;
1709 PyObject *memobj, *res;
1710 Py_ssize_t n;
1711 int errnum;
1712 /* NOTE: the buffer needn't be released as its object is NULL. */
1713 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1714 return -1;
1715 memobj = PyMemoryView_FromBuffer(&buf);
1716 if (memobj == NULL)
1717 return -1;
1718 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1719 occurs so we needn't do it ourselves.
1720 We then retry writing, ignoring the signal if no handler has
1721 raised (see issue #10956).
1722 */
1723 do {
1724 errno = 0;
1725 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1726 errnum = errno;
1727 } while (res == NULL && _PyIO_trap_eintr());
1728 Py_DECREF(memobj);
1729 if (res == NULL)
1730 return -1;
1731 if (res == Py_None) {
1732 /* Non-blocking stream would have blocked. Special return code!
1733 Being paranoid we reset errno in case it is changed by code
1734 triggered by a decref. errno is used by _set_BlockingIOError(). */
1735 Py_DECREF(res);
1736 errno = errnum;
1737 return -2;
1738 }
1739 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1740 Py_DECREF(res);
1741 if (n < 0 || n > len) {
1742 PyErr_Format(PyExc_IOError,
1743 "raw write() returned invalid length %zd "
1744 "(should have been between 0 and %zd)", n, len);
1745 return -1;
1746 }
1747 if (n > 0 && self->abs_pos != -1)
1748 self->abs_pos += n;
1749 return n;
1750 }
1751
1752 /* `restore_pos` is 1 if we need to restore the raw stream position at
1753 the end, 0 otherwise. */
1754 static PyObject *
_bufferedwriter_flush_unlocked(buffered * self)1755 _bufferedwriter_flush_unlocked(buffered *self)
1756 {
1757 Py_ssize_t written = 0;
1758 Py_off_t n, rewind;
1759
1760 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1761 goto end;
1762 /* First, rewind */
1763 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1764 if (rewind != 0) {
1765 n = _buffered_raw_seek(self, -rewind, 1);
1766 if (n < 0) {
1767 goto error;
1768 }
1769 self->raw_pos -= rewind;
1770 }
1771 while (self->write_pos < self->write_end) {
1772 n = _bufferedwriter_raw_write(self,
1773 self->buffer + self->write_pos,
1774 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1775 Py_off_t, Py_ssize_t));
1776 if (n == -1) {
1777 goto error;
1778 }
1779 else if (n == -2) {
1780 _set_BlockingIOError("write could not complete without blocking",
1781 0);
1782 goto error;
1783 }
1784 self->write_pos += n;
1785 self->raw_pos = self->write_pos;
1786 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
1787 /* Partial writes can return successfully when interrupted by a
1788 signal (see write(2)). We must run signal handlers before
1789 blocking another time, possibly indefinitely. */
1790 if (PyErr_CheckSignals() < 0)
1791 goto error;
1792 }
1793
1794 _bufferedwriter_reset_buf(self);
1795
1796 end:
1797 Py_RETURN_NONE;
1798
1799 error:
1800 return NULL;
1801 }
1802
1803 static PyObject *
bufferedwriter_write(buffered * self,PyObject * args)1804 bufferedwriter_write(buffered *self, PyObject *args)
1805 {
1806 PyObject *res = NULL;
1807 Py_buffer buf;
1808 Py_ssize_t written, avail, remaining;
1809 Py_off_t offset;
1810
1811 CHECK_INITIALIZED(self)
1812 if (!PyArg_ParseTuple(args, "s*:write", &buf)) {
1813 return NULL;
1814 }
1815
1816 if (IS_CLOSED(self)) {
1817 PyErr_SetString(PyExc_ValueError, "write to closed file");
1818 PyBuffer_Release(&buf);
1819 return NULL;
1820 }
1821
1822 if (!ENTER_BUFFERED(self)) {
1823 PyBuffer_Release(&buf);
1824 return NULL;
1825 }
1826
1827 /* Fast path: the data to write can be fully buffered. */
1828 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1829 self->pos = 0;
1830 self->raw_pos = 0;
1831 }
1832 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1833 if (buf.len <= avail) {
1834 memcpy(self->buffer + self->pos, buf.buf, buf.len);
1835 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
1836 self->write_pos = self->pos;
1837 }
1838 ADJUST_POSITION(self, self->pos + buf.len);
1839 if (self->pos > self->write_end)
1840 self->write_end = self->pos;
1841 written = buf.len;
1842 goto end;
1843 }
1844
1845 /* First write the current buffer */
1846 res = _bufferedwriter_flush_unlocked(self);
1847 if (res == NULL) {
1848 Py_ssize_t *w = _buffered_check_blocking_error();
1849 if (w == NULL)
1850 goto error;
1851 if (self->readable)
1852 _bufferedreader_reset_buf(self);
1853 /* Make some place by shifting the buffer. */
1854 assert(VALID_WRITE_BUFFER(self));
1855 memmove(self->buffer, self->buffer + self->write_pos,
1856 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1857 Py_off_t, Py_ssize_t));
1858 self->write_end -= self->write_pos;
1859 self->raw_pos -= self->write_pos;
1860 self->pos -= self->write_pos;
1861 self->write_pos = 0;
1862 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1863 Py_off_t, Py_ssize_t);
1864 if (buf.len <= avail) {
1865 /* Everything can be buffered */
1866 PyErr_Clear();
1867 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1868 self->write_end += buf.len;
1869 self->pos += buf.len;
1870 written = buf.len;
1871 goto end;
1872 }
1873 /* Buffer as much as possible. */
1874 memcpy(self->buffer + self->write_end, buf.buf, avail);
1875 self->write_end += avail;
1876 self->pos += avail;
1877 /* XXX Modifying the existing exception e using the pointer w
1878 will change e.characters_written but not e.args[2].
1879 Therefore we just replace with a new error. */
1880 _set_BlockingIOError("write could not complete without blocking",
1881 avail);
1882 goto error;
1883 }
1884 Py_CLEAR(res);
1885
1886 /* Adjust the raw stream position if it is away from the logical stream
1887 position. This happens if the read buffer has been filled but not
1888 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1889 the raw stream by itself).
1890 Fixes issue #6629.
1891 */
1892 offset = RAW_OFFSET(self);
1893 if (offset != 0) {
1894 if (_buffered_raw_seek(self, -offset, 1) < 0)
1895 goto error;
1896 self->raw_pos -= offset;
1897 }
1898
1899 /* Then write buf itself. At this point the buffer has been emptied. */
1900 remaining = buf.len;
1901 written = 0;
1902 while (remaining > self->buffer_size) {
1903 Py_ssize_t n = _bufferedwriter_raw_write(
1904 self, (char *) buf.buf + written, buf.len - written);
1905 if (n == -1) {
1906 goto error;
1907 } else if (n == -2) {
1908 /* Write failed because raw file is non-blocking */
1909 if (remaining > self->buffer_size) {
1910 /* Can't buffer everything, still buffer as much as possible */
1911 memcpy(self->buffer,
1912 (char *) buf.buf + written, self->buffer_size);
1913 self->raw_pos = 0;
1914 ADJUST_POSITION(self, self->buffer_size);
1915 self->write_end = self->buffer_size;
1916 written += self->buffer_size;
1917 _set_BlockingIOError("write could not complete without "
1918 "blocking", written);
1919 goto error;
1920 }
1921 PyErr_Clear();
1922 break;
1923 }
1924 written += n;
1925 remaining -= n;
1926 /* Partial writes can return successfully when interrupted by a
1927 signal (see write(2)). We must run signal handlers before
1928 blocking another time, possibly indefinitely. */
1929 if (PyErr_CheckSignals() < 0)
1930 goto error;
1931 }
1932 if (self->readable)
1933 _bufferedreader_reset_buf(self);
1934 if (remaining > 0) {
1935 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1936 written += remaining;
1937 }
1938 self->write_pos = 0;
1939 /* TODO: sanity check (remaining >= 0) */
1940 self->write_end = remaining;
1941 ADJUST_POSITION(self, remaining);
1942 self->raw_pos = 0;
1943
1944 end:
1945 res = PyLong_FromSsize_t(written);
1946
1947 error:
1948 LEAVE_BUFFERED(self)
1949 PyBuffer_Release(&buf);
1950 return res;
1951 }
1952
1953 static PyMethodDef bufferedwriter_methods[] = {
1954 /* BufferedIOMixin methods */
1955 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1956 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1957 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1958 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1959 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1960 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1961 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
1962
1963 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
1964 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1965 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
1966 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1967 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1968 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
1969 {NULL, NULL}
1970 };
1971
1972 static PyMemberDef bufferedwriter_members[] = {
1973 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
1974 {NULL}
1975 };
1976
1977 static PyGetSetDef bufferedwriter_getset[] = {
1978 {"closed", (getter)buffered_closed_get, NULL, NULL},
1979 {"name", (getter)buffered_name_get, NULL, NULL},
1980 {"mode", (getter)buffered_mode_get, NULL, NULL},
1981 {NULL}
1982 };
1983
1984
1985 PyTypeObject PyBufferedWriter_Type = {
1986 PyVarObject_HEAD_INIT(NULL, 0)
1987 "_io.BufferedWriter", /*tp_name*/
1988 sizeof(buffered), /*tp_basicsize*/
1989 0, /*tp_itemsize*/
1990 (destructor)buffered_dealloc, /*tp_dealloc*/
1991 0, /*tp_print*/
1992 0, /*tp_getattr*/
1993 0, /*tp_setattr*/
1994 0, /*tp_compare */
1995 (reprfunc)buffered_repr, /*tp_repr*/
1996 0, /*tp_as_number*/
1997 0, /*tp_as_sequence*/
1998 0, /*tp_as_mapping*/
1999 0, /*tp_hash */
2000 0, /*tp_call*/
2001 0, /*tp_str*/
2002 0, /*tp_getattro*/
2003 0, /*tp_setattro*/
2004 0, /*tp_as_buffer*/
2005 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2006 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2007 bufferedwriter_doc, /* tp_doc */
2008 (traverseproc)buffered_traverse, /* tp_traverse */
2009 (inquiry)buffered_clear, /* tp_clear */
2010 0, /* tp_richcompare */
2011 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2012 0, /* tp_iter */
2013 0, /* tp_iternext */
2014 bufferedwriter_methods, /* tp_methods */
2015 bufferedwriter_members, /* tp_members */
2016 bufferedwriter_getset, /* tp_getset */
2017 0, /* tp_base */
2018 0, /* tp_dict */
2019 0, /* tp_descr_get */
2020 0, /* tp_descr_set */
2021 offsetof(buffered, dict), /* tp_dictoffset */
2022 (initproc)bufferedwriter_init, /* tp_init */
2023 0, /* tp_alloc */
2024 PyType_GenericNew, /* tp_new */
2025 };
2026
2027
2028
2029 /*
2030 * BufferedRWPair
2031 */
2032
2033 PyDoc_STRVAR(bufferedrwpair_doc,
2034 "A buffered reader and writer object together.\n"
2035 "\n"
2036 "A buffered reader object and buffered writer object put together to\n"
2037 "form a sequential IO object that can read and write. This is typically\n"
2038 "used with a socket or two-way pipe.\n"
2039 "\n"
2040 "reader and writer are RawIOBase objects that are readable and\n"
2041 "writeable respectively. If the buffer_size is omitted it defaults to\n"
2042 "DEFAULT_BUFFER_SIZE.\n"
2043 );
2044
2045 /* XXX The usefulness of this (compared to having two separate IO objects) is
2046 * questionable.
2047 */
2048
2049 typedef struct {
2050 PyObject_HEAD
2051 buffered *reader;
2052 buffered *writer;
2053 PyObject *dict;
2054 PyObject *weakreflist;
2055 } rwpair;
2056
2057 static int
bufferedrwpair_init(rwpair * self,PyObject * args,PyObject * kwds)2058 bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
2059 {
2060 PyObject *reader, *writer;
2061 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
2062 Py_ssize_t max_buffer_size = -234;
2063
2064 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2065 &buffer_size, &max_buffer_size)) {
2066 return -1;
2067 }
2068
2069 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2070 return -1;
2071
2072 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
2073 return -1;
2074 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
2075 return -1;
2076
2077 self->reader = (buffered *) PyObject_CallFunction(
2078 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
2079 if (self->reader == NULL)
2080 return -1;
2081
2082 self->writer = (buffered *) PyObject_CallFunction(
2083 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
2084 if (self->writer == NULL) {
2085 Py_CLEAR(self->reader);
2086 return -1;
2087 }
2088
2089 return 0;
2090 }
2091
2092 static int
bufferedrwpair_traverse(rwpair * self,visitproc visit,void * arg)2093 bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
2094 {
2095 Py_VISIT(self->dict);
2096 return 0;
2097 }
2098
2099 static int
bufferedrwpair_clear(rwpair * self)2100 bufferedrwpair_clear(rwpair *self)
2101 {
2102 Py_CLEAR(self->reader);
2103 Py_CLEAR(self->writer);
2104 Py_CLEAR(self->dict);
2105 return 0;
2106 }
2107
2108 static void
bufferedrwpair_dealloc(rwpair * self)2109 bufferedrwpair_dealloc(rwpair *self)
2110 {
2111 _PyObject_GC_UNTRACK(self);
2112 if (self->weakreflist != NULL)
2113 PyObject_ClearWeakRefs((PyObject *)self);
2114 Py_CLEAR(self->reader);
2115 Py_CLEAR(self->writer);
2116 Py_CLEAR(self->dict);
2117 Py_TYPE(self)->tp_free((PyObject *) self);
2118 }
2119
2120 static PyObject *
_forward_call(buffered * self,const char * name,PyObject * args)2121 _forward_call(buffered *self, const char *name, PyObject *args)
2122 {
2123 PyObject *func, *ret;
2124 if (self == NULL) {
2125 PyErr_SetString(PyExc_ValueError,
2126 "I/O operation on uninitialized object");
2127 return NULL;
2128 }
2129
2130 func = PyObject_GetAttrString((PyObject *)self, name);
2131 if (func == NULL) {
2132 PyErr_SetString(PyExc_AttributeError, name);
2133 return NULL;
2134 }
2135
2136 ret = PyObject_CallObject(func, args);
2137 Py_DECREF(func);
2138 return ret;
2139 }
2140
2141 static PyObject *
bufferedrwpair_read(rwpair * self,PyObject * args)2142 bufferedrwpair_read(rwpair *self, PyObject *args)
2143 {
2144 return _forward_call(self->reader, "read", args);
2145 }
2146
2147 static PyObject *
bufferedrwpair_peek(rwpair * self,PyObject * args)2148 bufferedrwpair_peek(rwpair *self, PyObject *args)
2149 {
2150 return _forward_call(self->reader, "peek", args);
2151 }
2152
2153 static PyObject *
bufferedrwpair_read1(rwpair * self,PyObject * args)2154 bufferedrwpair_read1(rwpair *self, PyObject *args)
2155 {
2156 return _forward_call(self->reader, "read1", args);
2157 }
2158
2159 static PyObject *
bufferedrwpair_readinto(rwpair * self,PyObject * args)2160 bufferedrwpair_readinto(rwpair *self, PyObject *args)
2161 {
2162 return _forward_call(self->reader, "readinto", args);
2163 }
2164
2165 static PyObject *
bufferedrwpair_write(rwpair * self,PyObject * args)2166 bufferedrwpair_write(rwpair *self, PyObject *args)
2167 {
2168 return _forward_call(self->writer, "write", args);
2169 }
2170
2171 static PyObject *
bufferedrwpair_flush(rwpair * self,PyObject * args)2172 bufferedrwpair_flush(rwpair *self, PyObject *args)
2173 {
2174 return _forward_call(self->writer, "flush", args);
2175 }
2176
2177 static PyObject *
bufferedrwpair_readable(rwpair * self,PyObject * args)2178 bufferedrwpair_readable(rwpair *self, PyObject *args)
2179 {
2180 return _forward_call(self->reader, "readable", args);
2181 }
2182
2183 static PyObject *
bufferedrwpair_writable(rwpair * self,PyObject * args)2184 bufferedrwpair_writable(rwpair *self, PyObject *args)
2185 {
2186 return _forward_call(self->writer, "writable", args);
2187 }
2188
2189 static PyObject *
bufferedrwpair_close(rwpair * self,PyObject * args)2190 bufferedrwpair_close(rwpair *self, PyObject *args)
2191 {
2192 PyObject *exc = NULL, *val, *tb;
2193 PyObject *ret = _forward_call(self->writer, "close", args);
2194 if (ret == NULL)
2195 PyErr_Fetch(&exc, &val, &tb);
2196 else
2197 Py_DECREF(ret);
2198 ret = _forward_call(self->reader, "close", args);
2199 if (exc != NULL) {
2200 if (ret != NULL) {
2201 Py_CLEAR(ret);
2202 PyErr_Restore(exc, val, tb);
2203 }
2204 else {
2205 Py_DECREF(exc);
2206 Py_XDECREF(val);
2207 Py_XDECREF(tb);
2208 }
2209 }
2210 return ret;
2211 }
2212
2213 static PyObject *
bufferedrwpair_isatty(rwpair * self,PyObject * args)2214 bufferedrwpair_isatty(rwpair *self, PyObject *args)
2215 {
2216 PyObject *ret = _forward_call(self->writer, "isatty", args);
2217
2218 if (ret != Py_False) {
2219 /* either True or exception */
2220 return ret;
2221 }
2222 Py_DECREF(ret);
2223
2224 return _forward_call(self->reader, "isatty", args);
2225 }
2226
2227 static PyObject *
bufferedrwpair_closed_get(rwpair * self,void * context)2228 bufferedrwpair_closed_get(rwpair *self, void *context)
2229 {
2230 if (self->writer == NULL) {
2231 PyErr_SetString(PyExc_RuntimeError,
2232 "the BufferedRWPair object is being garbage-collected");
2233 return NULL;
2234 }
2235 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2236 }
2237
2238 static PyMethodDef bufferedrwpair_methods[] = {
2239 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2240 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2241 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2242 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
2243
2244 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2245 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
2246
2247 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2248 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
2249
2250 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2251 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
2252
2253 {NULL, NULL}
2254 };
2255
2256 static PyGetSetDef bufferedrwpair_getset[] = {
2257 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
2258 {NULL}
2259 };
2260
2261 PyTypeObject PyBufferedRWPair_Type = {
2262 PyVarObject_HEAD_INIT(NULL, 0)
2263 "_io.BufferedRWPair", /*tp_name*/
2264 sizeof(rwpair), /*tp_basicsize*/
2265 0, /*tp_itemsize*/
2266 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
2267 0, /*tp_print*/
2268 0, /*tp_getattr*/
2269 0, /*tp_setattr*/
2270 0, /*tp_compare */
2271 0, /*tp_repr*/
2272 0, /*tp_as_number*/
2273 0, /*tp_as_sequence*/
2274 0, /*tp_as_mapping*/
2275 0, /*tp_hash */
2276 0, /*tp_call*/
2277 0, /*tp_str*/
2278 0, /*tp_getattro*/
2279 0, /*tp_setattro*/
2280 0, /*tp_as_buffer*/
2281 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2282 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2283 bufferedrwpair_doc, /* tp_doc */
2284 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2285 (inquiry)bufferedrwpair_clear, /* tp_clear */
2286 0, /* tp_richcompare */
2287 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
2288 0, /* tp_iter */
2289 0, /* tp_iternext */
2290 bufferedrwpair_methods, /* tp_methods */
2291 0, /* tp_members */
2292 bufferedrwpair_getset, /* tp_getset */
2293 0, /* tp_base */
2294 0, /* tp_dict */
2295 0, /* tp_descr_get */
2296 0, /* tp_descr_set */
2297 offsetof(rwpair, dict), /* tp_dictoffset */
2298 (initproc)bufferedrwpair_init, /* tp_init */
2299 0, /* tp_alloc */
2300 PyType_GenericNew, /* tp_new */
2301 };
2302
2303
2304
2305 /*
2306 * BufferedRandom
2307 */
2308
2309 PyDoc_STRVAR(bufferedrandom_doc,
2310 "A buffered interface to random access streams.\n"
2311 "\n"
2312 "The constructor creates a reader and writer for a seekable stream,\n"
2313 "raw, given in the first argument. If the buffer_size is omitted it\n"
2314 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2315 );
2316
2317 static int
bufferedrandom_init(buffered * self,PyObject * args,PyObject * kwds)2318 bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
2319 {
2320 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2321 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
2322 Py_ssize_t max_buffer_size = -234;
2323 PyObject *raw;
2324
2325 self->ok = 0;
2326 self->detached = 0;
2327
2328 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedRandom", kwlist,
2329 &raw, &buffer_size, &max_buffer_size)) {
2330 return -1;
2331 }
2332
2333 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2334 return -1;
2335
2336 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2337 return -1;
2338 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2339 return -1;
2340 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2341 return -1;
2342
2343 Py_INCREF(raw);
2344 Py_XSETREF(self->raw, raw);
2345 self->buffer_size = buffer_size;
2346 self->readable = 1;
2347 self->writable = 1;
2348
2349 if (_buffered_init(self) < 0)
2350 return -1;
2351 _bufferedreader_reset_buf(self);
2352 _bufferedwriter_reset_buf(self);
2353 self->pos = 0;
2354
2355 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2356 Py_TYPE(raw) == &PyFileIO_Type);
2357
2358 self->ok = 1;
2359 return 0;
2360 }
2361
2362 static PyMethodDef bufferedrandom_methods[] = {
2363 /* BufferedIOMixin methods */
2364 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2365 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2366 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2367 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2368 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2369 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2370 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2371
2372 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2373
2374 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2375 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2376 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2377 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2378 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2379 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2380 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2381 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2382 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2383 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2384 {NULL, NULL}
2385 };
2386
2387 static PyMemberDef bufferedrandom_members[] = {
2388 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2389 {NULL}
2390 };
2391
2392 static PyGetSetDef bufferedrandom_getset[] = {
2393 {"closed", (getter)buffered_closed_get, NULL, NULL},
2394 {"name", (getter)buffered_name_get, NULL, NULL},
2395 {"mode", (getter)buffered_mode_get, NULL, NULL},
2396 {NULL}
2397 };
2398
2399
2400 PyTypeObject PyBufferedRandom_Type = {
2401 PyVarObject_HEAD_INIT(NULL, 0)
2402 "_io.BufferedRandom", /*tp_name*/
2403 sizeof(buffered), /*tp_basicsize*/
2404 0, /*tp_itemsize*/
2405 (destructor)buffered_dealloc, /*tp_dealloc*/
2406 0, /*tp_print*/
2407 0, /*tp_getattr*/
2408 0, /*tp_setattr*/
2409 0, /*tp_compare */
2410 (reprfunc)buffered_repr, /*tp_repr*/
2411 0, /*tp_as_number*/
2412 0, /*tp_as_sequence*/
2413 0, /*tp_as_mapping*/
2414 0, /*tp_hash */
2415 0, /*tp_call*/
2416 0, /*tp_str*/
2417 0, /*tp_getattro*/
2418 0, /*tp_setattro*/
2419 0, /*tp_as_buffer*/
2420 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2421 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2422 bufferedrandom_doc, /* tp_doc */
2423 (traverseproc)buffered_traverse, /* tp_traverse */
2424 (inquiry)buffered_clear, /* tp_clear */
2425 0, /* tp_richcompare */
2426 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2427 0, /* tp_iter */
2428 (iternextfunc)buffered_iternext, /* tp_iternext */
2429 bufferedrandom_methods, /* tp_methods */
2430 bufferedrandom_members, /* tp_members */
2431 bufferedrandom_getset, /* tp_getset */
2432 0, /* tp_base */
2433 0, /*tp_dict*/
2434 0, /* tp_descr_get */
2435 0, /* tp_descr_set */
2436 offsetof(buffered, dict), /*tp_dictoffset*/
2437 (initproc)bufferedrandom_init, /* tp_init */
2438 0, /* tp_alloc */
2439 PyType_GenericNew, /* tp_new */
2440 };
2441
2442