]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/Modules/_io/bufferedio.c
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 2/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Modules / _io / bufferedio.c
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 *
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 *
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 *
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 *
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 *
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 never less than\n"
129 "len(b).\n"
130 "\n"
131 "Raises BlockingIOError if the buffer is full and the\n"
132 "underlying raw stream cannot accept more data at the moment.\n");
133
134 static PyObject *
135 bufferediobase_write(PyObject *self, PyObject *args)
136 {
137 return bufferediobase_unsupported("write");
138 }
139
140
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},
147 {NULL, NULL}
148 };
149
150 PyTypeObject PyBufferedIOBase_Type = {
151 PyVarObject_HEAD_INIT(NULL, 0)
152 "_io._BufferedIOBase", /*tp_name*/
153 0, /*tp_basicsize*/
154 0, /*tp_itemsize*/
155 0, /*tp_dealloc*/
156 0, /*tp_print*/
157 0, /*tp_getattr*/
158 0, /*tp_setattr*/
159 0, /*tp_compare */
160 0, /*tp_repr*/
161 0, /*tp_as_number*/
162 0, /*tp_as_sequence*/
163 0, /*tp_as_mapping*/
164 0, /*tp_hash */
165 0, /*tp_call*/
166 0, /*tp_str*/
167 0, /*tp_getattro*/
168 0, /*tp_setattro*/
169 0, /*tp_as_buffer*/
170 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
171 bufferediobase_doc, /* tp_doc */
172 0, /* tp_traverse */
173 0, /* tp_clear */
174 0, /* tp_richcompare */
175 0, /* tp_weaklistoffset */
176 0, /* tp_iter */
177 0, /* tp_iternext */
178 bufferediobase_methods, /* tp_methods */
179 0, /* tp_members */
180 0, /* tp_getset */
181 &PyIOBase_Type, /* tp_base */
182 0, /* tp_dict */
183 0, /* tp_descr_get */
184 0, /* tp_descr_set */
185 0, /* tp_dictoffset */
186 0, /* tp_init */
187 0, /* tp_alloc */
188 0, /* tp_new */
189 };
190
191
192 typedef struct {
193 PyObject_HEAD
194
195 PyObject *raw;
196 int ok; /* Initialized? */
197 int detached;
198 int readable;
199 int writable;
200
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;
204
205 /* Absolute position inside the raw stream (-1 if unknown). */
206 Py_off_t abs_pos;
207
208 /* A static buffer of size `buffer_size` */
209 char *buffer;
210 /* Current logical position in the buffer. */
211 Py_off_t pos;
212 /* Position of the raw stream in the buffer. */
213 Py_off_t raw_pos;
214
215 /* Just after the last buffered byte in the buffer, or -1 if the buffer
216 isn't ready for reading. */
217 Py_off_t read_end;
218
219 /* Just after the last byte actually written */
220 Py_off_t write_pos;
221 /* Just after the last byte waiting to be written, or -1 if the buffer
222 isn't ready for writing. */
223 Py_off_t write_end;
224
225 #ifdef WITH_THREAD
226 PyThread_type_lock lock;
227 volatile long owner;
228 #endif
229
230 Py_ssize_t buffer_size;
231 Py_ssize_t buffer_mask;
232
233 PyObject *dict;
234 PyObject *weakreflist;
235 } buffered;
236
237 /*
238 Implementation notes:
239
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.
253
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.
257
258 */
259
260 /* These macros protect the buffered object against concurrent operations. */
261
262 #ifdef WITH_THREAD
263
264 static int
265 _enter_buffered_busy(buffered *self)
266 {
267 if (self->owner == PyThread_get_thread_ident()) {
268 PyObject *r = PyObject_Repr((PyObject *) self);
269 if (r != NULL) {
270 PyErr_Format(PyExc_RuntimeError,
271 "reentrant call inside %s",
272 PyString_AS_STRING(r));
273 Py_DECREF(r);
274 }
275 return 0;
276 }
277 Py_BEGIN_ALLOW_THREADS
278 PyThread_acquire_lock(self->lock, 1);
279 Py_END_ALLOW_THREADS
280 return 1;
281 }
282
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) )
287
288 #define LEAVE_BUFFERED(self) \
289 do { \
290 self->owner = 0; \
291 PyThread_release_lock(self->lock); \
292 } while(0);
293
294 #else
295 #define ENTER_BUFFERED(self) 1
296 #define LEAVE_BUFFERED(self)
297 #endif
298
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"); \
304 } else { \
305 PyErr_SetString(PyExc_ValueError, \
306 "I/O operation on uninitialized object"); \
307 } \
308 return NULL; \
309 }
310
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"); \
316 } else { \
317 PyErr_SetString(PyExc_ValueError, \
318 "I/O operation on uninitialized object"); \
319 } \
320 return -1; \
321 }
322
323 #define IS_CLOSED(self) \
324 (self->fast_closed_checks \
325 ? _PyFileIO_closed(self->raw) \
326 : buffered_closed(self))
327
328 #define CHECK_CLOSED(self, error_msg) \
329 if (IS_CLOSED(self)) { \
330 PyErr_SetString(PyExc_ValueError, error_msg); \
331 return NULL; \
332 }
333
334
335 #define VALID_READ_BUFFER(self) \
336 (self->readable && self->read_end != -1)
337
338 #define VALID_WRITE_BUFFER(self) \
339 (self->writable && self->write_end != -1)
340
341 #define ADJUST_POSITION(self, _new_pos) \
342 do { \
343 self->pos = _new_pos; \
344 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
345 self->read_end = self->pos; \
346 } while(0)
347
348 #define READAHEAD(self) \
349 ((self->readable && VALID_READ_BUFFER(self)) \
350 ? (self->read_end - self->pos) : 0)
351
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)
355
356 #define RAW_TELL(self) \
357 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
358
359 #define MINUS_LAST_BLOCK(self, size) \
360 (self->buffer_mask ? \
361 (size & ~self->buffer_mask) : \
362 (self->buffer_size * (size / self->buffer_size)))
363
364
365 static void
366 buffered_dealloc(buffered *self)
367 {
368 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
369 return;
370 _PyObject_GC_UNTRACK(self);
371 self->ok = 0;
372 if (self->weakreflist != NULL)
373 PyObject_ClearWeakRefs((PyObject *)self);
374 Py_CLEAR(self->raw);
375 if (self->buffer) {
376 PyMem_Free(self->buffer);
377 self->buffer = NULL;
378 }
379 #ifdef WITH_THREAD
380 if (self->lock) {
381 PyThread_free_lock(self->lock);
382 self->lock = NULL;
383 }
384 #endif
385 Py_CLEAR(self->dict);
386 Py_TYPE(self)->tp_free((PyObject *)self);
387 }
388
389 static PyObject *
390 buffered_sizeof(buffered *self, void *unused)
391 {
392 Py_ssize_t res;
393
394 res = sizeof(buffered);
395 if (self->buffer)
396 res += self->buffer_size;
397 return PyLong_FromSsize_t(res);
398 }
399
400 static int
401 buffered_traverse(buffered *self, visitproc visit, void *arg)
402 {
403 Py_VISIT(self->raw);
404 Py_VISIT(self->dict);
405 return 0;
406 }
407
408 static int
409 buffered_clear(buffered *self)
410 {
411 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
412 return -1;
413 self->ok = 0;
414 Py_CLEAR(self->raw);
415 Py_CLEAR(self->dict);
416 return 0;
417 }
418
419 /*
420 * _BufferedIOMixin methods
421 * This is not a class, just a collection of methods that will be reused
422 * by BufferedReader and BufferedWriter
423 */
424
425 /* Flush and close */
426
427 static PyObject *
428 buffered_simple_flush(buffered *self, PyObject *args)
429 {
430 CHECK_INITIALIZED(self)
431 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
432 }
433
434 static int
435 buffered_closed(buffered *self)
436 {
437 int closed;
438 PyObject *res;
439 CHECK_INITIALIZED_INT(self)
440 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
441 if (res == NULL)
442 return -1;
443 closed = PyObject_IsTrue(res);
444 Py_DECREF(res);
445 return closed;
446 }
447
448 static PyObject *
449 buffered_closed_get(buffered *self, void *context)
450 {
451 CHECK_INITIALIZED(self)
452 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
453 }
454
455 static PyObject *
456 buffered_close(buffered *self, PyObject *args)
457 {
458 PyObject *res = NULL, *exc = NULL, *val, *tb;
459 int r;
460
461 CHECK_INITIALIZED(self)
462 if (!ENTER_BUFFERED(self))
463 return NULL;
464
465 r = buffered_closed(self);
466 if (r < 0)
467 goto end;
468 if (r > 0) {
469 res = Py_None;
470 Py_INCREF(res);
471 goto end;
472 }
473 /* flush() will most probably re-take the lock, so drop it first */
474 LEAVE_BUFFERED(self)
475 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
476 if (!ENTER_BUFFERED(self))
477 return NULL;
478 if (res == NULL)
479 PyErr_Fetch(&exc, &val, &tb);
480 else
481 Py_DECREF(res);
482
483 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
484
485 if (exc != NULL) {
486 _PyErr_ReplaceException(exc, val, tb);
487 Py_CLEAR(res);
488 }
489
490 end:
491 LEAVE_BUFFERED(self)
492 return res;
493 }
494
495 /* detach */
496
497 static PyObject *
498 buffered_detach(buffered *self, PyObject *args)
499 {
500 PyObject *raw, *res;
501 CHECK_INITIALIZED(self)
502 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
503 if (res == NULL)
504 return NULL;
505 Py_DECREF(res);
506 raw = self->raw;
507 self->raw = NULL;
508 self->detached = 1;
509 self->ok = 0;
510 return raw;
511 }
512
513 /* Inquiries */
514
515 static PyObject *
516 buffered_seekable(buffered *self, PyObject *args)
517 {
518 CHECK_INITIALIZED(self)
519 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
520 }
521
522 static PyObject *
523 buffered_readable(buffered *self, PyObject *args)
524 {
525 CHECK_INITIALIZED(self)
526 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
527 }
528
529 static PyObject *
530 buffered_writable(buffered *self, PyObject *args)
531 {
532 CHECK_INITIALIZED(self)
533 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
534 }
535
536 static PyObject *
537 buffered_name_get(buffered *self, void *context)
538 {
539 CHECK_INITIALIZED(self)
540 return PyObject_GetAttrString(self->raw, "name");
541 }
542
543 static PyObject *
544 buffered_mode_get(buffered *self, void *context)
545 {
546 CHECK_INITIALIZED(self)
547 return PyObject_GetAttrString(self->raw, "mode");
548 }
549
550 /* Lower-level APIs */
551
552 static PyObject *
553 buffered_fileno(buffered *self, PyObject *args)
554 {
555 CHECK_INITIALIZED(self)
556 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
557 }
558
559 static PyObject *
560 buffered_isatty(buffered *self, PyObject *args)
561 {
562 CHECK_INITIALIZED(self)
563 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
564 }
565
566
567 /* Forward decls */
568 static PyObject *
569 _bufferedwriter_flush_unlocked(buffered *);
570 static Py_ssize_t
571 _bufferedreader_fill_buffer(buffered *self);
572 static void
573 _bufferedreader_reset_buf(buffered *self);
574 static void
575 _bufferedwriter_reset_buf(buffered *self);
576 static PyObject *
577 _bufferedreader_peek_unlocked(buffered *self, Py_ssize_t);
578 static PyObject *
579 _bufferedreader_read_all(buffered *self);
580 static PyObject *
581 _bufferedreader_read_fast(buffered *self, Py_ssize_t);
582 static PyObject *
583 _bufferedreader_read_generic(buffered *self, Py_ssize_t);
584
585
586 /*
587 * Helpers
588 */
589
590 /* Sets the current error to BlockingIOError */
591 static void
592 _set_BlockingIOError(char *msg, Py_ssize_t written)
593 {
594 PyObject *err;
595 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
596 errno, msg, written);
597 if (err)
598 PyErr_SetObject(PyExc_BlockingIOError, err);
599 Py_XDECREF(err);
600 }
601
602 /* Returns the address of the `written` member if a BlockingIOError was
603 raised, NULL otherwise. The error is always re-raised. */
604 static Py_ssize_t *
605 _buffered_check_blocking_error(void)
606 {
607 PyObject *t, *v, *tb;
608 PyBlockingIOErrorObject *err;
609
610 PyErr_Fetch(&t, &v, &tb);
611 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
612 PyErr_Restore(t, v, tb);
613 return NULL;
614 }
615 err = (PyBlockingIOErrorObject *) v;
616 /* TODO: sanity check (err->written >= 0) */
617 PyErr_Restore(t, v, tb);
618 return &err->written;
619 }
620
621 static Py_off_t
622 _buffered_raw_tell(buffered *self)
623 {
624 Py_off_t n;
625 PyObject *res;
626 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
627 if (res == NULL)
628 return -1;
629 n = PyNumber_AsOff_t(res, PyExc_ValueError);
630 Py_DECREF(res);
631 if (n < 0) {
632 if (!PyErr_Occurred())
633 PyErr_Format(PyExc_IOError,
634 "Raw stream returned invalid position %" PY_PRIdOFF,
635 (PY_OFF_T_COMPAT)n);
636 return -1;
637 }
638 self->abs_pos = n;
639 return n;
640 }
641
642 static Py_off_t
643 _buffered_raw_seek(buffered *self, Py_off_t target, int whence)
644 {
645 PyObject *res, *posobj, *whenceobj;
646 Py_off_t n;
647
648 posobj = PyLong_FromOff_t(target);
649 if (posobj == NULL)
650 return -1;
651 whenceobj = PyLong_FromLong(whence);
652 if (whenceobj == NULL) {
653 Py_DECREF(posobj);
654 return -1;
655 }
656 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
657 posobj, whenceobj, NULL);
658 Py_DECREF(posobj);
659 Py_DECREF(whenceobj);
660 if (res == NULL)
661 return -1;
662 n = PyNumber_AsOff_t(res, PyExc_ValueError);
663 Py_DECREF(res);
664 if (n < 0) {
665 if (!PyErr_Occurred())
666 PyErr_Format(PyExc_IOError,
667 "Raw stream returned invalid position %" PY_PRIdOFF,
668 (PY_OFF_T_COMPAT)n);
669 return -1;
670 }
671 self->abs_pos = n;
672 return n;
673 }
674
675 static int
676 _buffered_init(buffered *self)
677 {
678 Py_ssize_t n;
679 if (self->buffer_size <= 0) {
680 PyErr_SetString(PyExc_ValueError,
681 "buffer size must be strictly positive");
682 return -1;
683 }
684 if (self->buffer)
685 PyMem_Free(self->buffer);
686 self->buffer = PyMem_Malloc(self->buffer_size);
687 if (self->buffer == NULL) {
688 PyErr_NoMemory();
689 return -1;
690 }
691 #ifdef WITH_THREAD
692 if (self->lock)
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");
697 return -1;
698 }
699 self->owner = 0;
700 #endif
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)
704 ;
705 if (n == 0)
706 self->buffer_mask = self->buffer_size - 1;
707 else
708 self->buffer_mask = 0;
709 if (_buffered_raw_tell(self) == -1)
710 PyErr_Clear();
711 return 0;
712 }
713
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.
717 */
718 int
719 _PyIO_trap_eintr(void)
720 {
721 static PyObject *eintr_int = NULL;
722 PyObject *typ, *val, *tb;
723 PyEnvironmentErrorObject *env_err;
724
725 if (eintr_int == NULL) {
726 eintr_int = PyLong_FromLong(EINTR);
727 assert(eintr_int != NULL);
728 }
729 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
730 return 0;
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) {
737 Py_DECREF(typ);
738 Py_DECREF(val);
739 Py_XDECREF(tb);
740 return 1;
741 }
742 /* This silences any error set by PyObject_RichCompareBool() */
743 PyErr_Restore(typ, val, tb);
744 return 0;
745 }
746
747 /*
748 * Shared methods and wrappers
749 */
750
751 static PyObject *
752 buffered_flush_and_rewind_unlocked(buffered *self)
753 {
754 PyObject *res;
755
756 res = _bufferedwriter_flush_unlocked(self);
757 if (res == NULL)
758 return NULL;
759 Py_DECREF(res);
760
761 if (self->readable) {
762 /* Rewind the raw stream so that its position corresponds to
763 the current logical position. */
764 Py_off_t n;
765 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
766 _bufferedreader_reset_buf(self);
767 if (n == -1)
768 return NULL;
769 }
770 Py_RETURN_NONE;
771 }
772
773 static PyObject *
774 buffered_flush(buffered *self, PyObject *args)
775 {
776 PyObject *res;
777
778 CHECK_INITIALIZED(self)
779 CHECK_CLOSED(self, "flush of closed file")
780
781 if (!ENTER_BUFFERED(self))
782 return NULL;
783 res = buffered_flush_and_rewind_unlocked(self);
784 LEAVE_BUFFERED(self)
785
786 return res;
787 }
788
789 static PyObject *
790 buffered_peek(buffered *self, PyObject *args)
791 {
792 Py_ssize_t n = 0;
793 PyObject *res = NULL;
794
795 CHECK_INITIALIZED(self)
796 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
797 return NULL;
798 }
799
800 if (!ENTER_BUFFERED(self))
801 return NULL;
802
803 if (self->writable) {
804 res = buffered_flush_and_rewind_unlocked(self);
805 if (res == NULL)
806 goto end;
807 Py_CLEAR(res);
808 }
809 res = _bufferedreader_peek_unlocked(self, n);
810
811 end:
812 LEAVE_BUFFERED(self)
813 return res;
814 }
815
816 static PyObject *
817 buffered_read(buffered *self, PyObject *args)
818 {
819 Py_ssize_t n = -1;
820 PyObject *res;
821
822 CHECK_INITIALIZED(self)
823 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
824 return NULL;
825 }
826 if (n < -1) {
827 PyErr_SetString(PyExc_ValueError,
828 "read length must be positive or -1");
829 return NULL;
830 }
831
832 CHECK_CLOSED(self, "read of closed file")
833
834 if (n == -1) {
835 /* The number of bytes is unspecified, read until the end of stream */
836 if (!ENTER_BUFFERED(self))
837 return NULL;
838 res = _bufferedreader_read_all(self);
839 }
840 else {
841 res = _bufferedreader_read_fast(self, n);
842 if (res != Py_None)
843 return res;
844 Py_DECREF(res);
845 if (!ENTER_BUFFERED(self))
846 return NULL;
847 res = _bufferedreader_read_generic(self, n);
848 }
849
850 LEAVE_BUFFERED(self)
851 return res;
852 }
853
854 static PyObject *
855 buffered_read1(buffered *self, PyObject *args)
856 {
857 Py_ssize_t n, have, r;
858 PyObject *res = NULL;
859
860 CHECK_INITIALIZED(self)
861 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
862 return NULL;
863 }
864
865 if (n < 0) {
866 PyErr_SetString(PyExc_ValueError,
867 "read length must be positive");
868 return NULL;
869 }
870 if (n == 0)
871 return PyBytes_FromStringAndSize(NULL, 0);
872
873 if (!ENTER_BUFFERED(self))
874 return NULL;
875
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. */
878
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). */
883
884 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
885 if (have > 0) {
886 if (n > have)
887 n = have;
888 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
889 if (res == NULL)
890 goto end;
891 self->pos += n;
892 goto end;
893 }
894
895 if (self->writable) {
896 res = buffered_flush_and_rewind_unlocked(self);
897 if (res == NULL)
898 goto end;
899 Py_DECREF(res);
900 }
901
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);
905 if (r == -1)
906 goto end;
907 if (r == -2)
908 r = 0;
909 if (n > r)
910 n = r;
911 res = PyBytes_FromStringAndSize(self->buffer, n);
912 if (res == NULL)
913 goto end;
914 self->pos = n;
915
916 end:
917 LEAVE_BUFFERED(self)
918 return res;
919 }
920
921 static PyObject *
922 buffered_readinto(buffered *self, PyObject *args)
923 {
924 CHECK_INITIALIZED(self)
925
926 /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
927 return bufferediobase_readinto((PyObject *)self, args);
928 }
929
930 static PyObject *
931 _buffered_readline(buffered *self, Py_ssize_t limit)
932 {
933 PyObject *res = NULL;
934 PyObject *chunks = NULL;
935 Py_ssize_t n, written = 0;
936 const char *start, *s, *end;
937
938 CHECK_CLOSED(self, "readline of closed file")
939
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)
945 n = limit;
946 start = self->buffer + self->pos;
947 s = memchr(start, '\n', n);
948 if (s != NULL) {
949 res = PyBytes_FromStringAndSize(start, s - start + 1);
950 if (res != NULL)
951 self->pos += s - start + 1;
952 goto end_unlocked;
953 }
954 if (n == limit) {
955 res = PyBytes_FromStringAndSize(start, n);
956 if (res != NULL)
957 self->pos += n;
958 goto end_unlocked;
959 }
960
961 if (!ENTER_BUFFERED(self))
962 goto end_unlocked;
963
964 /* Now we try to get some more from the raw stream */
965 chunks = PyList_New(0);
966 if (chunks == NULL)
967 goto end;
968 if (n > 0) {
969 res = PyBytes_FromStringAndSize(start, n);
970 if (res == NULL)
971 goto end;
972 if (PyList_Append(chunks, res) < 0) {
973 Py_CLEAR(res);
974 goto end;
975 }
976 Py_CLEAR(res);
977 written += n;
978 self->pos += n;
979 if (limit >= 0)
980 limit -= n;
981 }
982 if (self->writable) {
983 PyObject *r = buffered_flush_and_rewind_unlocked(self);
984 if (r == NULL)
985 goto end;
986 Py_DECREF(r);
987 }
988
989 for (;;) {
990 _bufferedreader_reset_buf(self);
991 n = _bufferedreader_fill_buffer(self);
992 if (n == -1)
993 goto end;
994 if (n <= 0)
995 break;
996 if (limit >= 0 && n > limit)
997 n = limit;
998 start = self->buffer;
999 end = start + n;
1000 s = start;
1001 while (s < end) {
1002 if (*s++ == '\n') {
1003 res = PyBytes_FromStringAndSize(start, s - start);
1004 if (res == NULL)
1005 goto end;
1006 self->pos = s - start;
1007 goto found;
1008 }
1009 }
1010 res = PyBytes_FromStringAndSize(start, n);
1011 if (res == NULL)
1012 goto end;
1013 if (n == limit) {
1014 self->pos = n;
1015 break;
1016 }
1017 if (PyList_Append(chunks, res) < 0) {
1018 Py_CLEAR(res);
1019 goto end;
1020 }
1021 Py_CLEAR(res);
1022 written += n;
1023 if (limit >= 0)
1024 limit -= n;
1025 }
1026 found:
1027 if (res != NULL && PyList_Append(chunks, res) < 0) {
1028 Py_CLEAR(res);
1029 goto end;
1030 }
1031 Py_CLEAR(res);
1032 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1033
1034 end:
1035 LEAVE_BUFFERED(self)
1036 end_unlocked:
1037 Py_XDECREF(chunks);
1038 return res;
1039 }
1040
1041 static PyObject *
1042 buffered_readline(buffered *self, PyObject *args)
1043 {
1044 Py_ssize_t limit = -1;
1045
1046 CHECK_INITIALIZED(self)
1047 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
1048 return NULL;
1049 return _buffered_readline(self, limit);
1050 }
1051
1052
1053 static PyObject *
1054 buffered_tell(buffered *self, PyObject *args)
1055 {
1056 Py_off_t pos;
1057
1058 CHECK_INITIALIZED(self)
1059 pos = _buffered_raw_tell(self);
1060 if (pos == -1)
1061 return NULL;
1062 pos -= RAW_OFFSET(self);
1063 /* TODO: sanity check (pos >= 0) */
1064 return PyLong_FromOff_t(pos);
1065 }
1066
1067 static PyObject *
1068 buffered_seek(buffered *self, PyObject *args)
1069 {
1070 Py_off_t target, n;
1071 int whence = 0;
1072 PyObject *targetobj, *res = NULL;
1073
1074 CHECK_INITIALIZED(self)
1075 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1076 return NULL;
1077 }
1078 if (whence < 0 || whence > 2) {
1079 PyErr_Format(PyExc_ValueError,
1080 "whence must be between 0 and 2, not %d", whence);
1081 return NULL;
1082 }
1083
1084 CHECK_CLOSED(self, "seek of closed file")
1085
1086 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1087 if (target == -1 && PyErr_Occurred())
1088 return NULL;
1089
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);
1100 if (avail > 0) {
1101 Py_off_t offset;
1102 if (whence == 0)
1103 offset = target - (current - RAW_OFFSET(self));
1104 else
1105 offset = target;
1106 if (offset >= -self->pos && offset <= avail) {
1107 self->pos += offset;
1108 return PyLong_FromOff_t(current - avail + offset);
1109 }
1110 }
1111 }
1112
1113 if (!ENTER_BUFFERED(self))
1114 return NULL;
1115
1116 /* Fallback: invoke raw seek() method and clear buffer */
1117 if (self->writable) {
1118 res = _bufferedwriter_flush_unlocked(self);
1119 if (res == NULL)
1120 goto end;
1121 Py_CLEAR(res);
1122 _bufferedwriter_reset_buf(self);
1123 }
1124
1125 /* TODO: align on block boundary and read buffer if needed? */
1126 if (whence == 1)
1127 target -= RAW_OFFSET(self);
1128 n = _buffered_raw_seek(self, target, whence);
1129 if (n == -1)
1130 goto end;
1131 self->raw_pos = -1;
1132 res = PyLong_FromOff_t(n);
1133 if (res != NULL && self->readable)
1134 _bufferedreader_reset_buf(self);
1135
1136 end:
1137 LEAVE_BUFFERED(self)
1138 return res;
1139 }
1140
1141 static PyObject *
1142 buffered_truncate(buffered *self, PyObject *args)
1143 {
1144 PyObject *pos = Py_None;
1145 PyObject *res = NULL;
1146
1147 CHECK_INITIALIZED(self)
1148 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1149 return NULL;
1150 }
1151
1152 if (!ENTER_BUFFERED(self))
1153 return NULL;
1154
1155 if (self->writable) {
1156 res = buffered_flush_and_rewind_unlocked(self);
1157 if (res == NULL)
1158 goto end;
1159 Py_CLEAR(res);
1160 }
1161 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1162 if (res == NULL)
1163 goto end;
1164 /* Reset cached position */
1165 if (_buffered_raw_tell(self) == -1)
1166 PyErr_Clear();
1167
1168 end:
1169 LEAVE_BUFFERED(self)
1170 return res;
1171 }
1172
1173 static PyObject *
1174 buffered_iternext(buffered *self)
1175 {
1176 PyObject *line;
1177 PyTypeObject *tp;
1178
1179 CHECK_INITIALIZED(self);
1180
1181 tp = Py_TYPE(self);
1182 if (tp == &PyBufferedReader_Type ||
1183 tp == &PyBufferedRandom_Type) {
1184 /* Skip method call overhead for speed */
1185 line = _buffered_readline(self, -1);
1186 }
1187 else {
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);
1194 Py_DECREF(line);
1195 return NULL;
1196 }
1197 }
1198
1199 if (line == NULL)
1200 return NULL;
1201
1202 if (PyBytes_GET_SIZE(line) == 0) {
1203 /* Reached EOF or would have blocked */
1204 Py_DECREF(line);
1205 return NULL;
1206 }
1207
1208 return line;
1209 }
1210
1211 static PyObject *
1212 buffered_repr(buffered *self)
1213 {
1214 PyObject *nameobj, *res;
1215
1216 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1217 if (nameobj == NULL) {
1218 if (PyErr_ExceptionMatches(PyExc_Exception))
1219 PyErr_Clear();
1220 else
1221 return NULL;
1222 res = PyString_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1223 }
1224 else {
1225 PyObject *repr = PyObject_Repr(nameobj);
1226 Py_DECREF(nameobj);
1227 if (repr == NULL)
1228 return NULL;
1229 res = PyString_FromFormat("<%s name=%s>",
1230 Py_TYPE(self)->tp_name,
1231 PyString_AS_STRING(repr));
1232 Py_DECREF(repr);
1233 }
1234 return res;
1235 }
1236
1237 /*
1238 * class BufferedReader
1239 */
1240
1241 PyDoc_STRVAR(bufferedreader_doc,
1242 "Create a new buffered reader using the given readable raw IO object.");
1243
1244 static void _bufferedreader_reset_buf(buffered *self)
1245 {
1246 self->read_end = -1;
1247 }
1248
1249 static int
1250 bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
1251 {
1252 char *kwlist[] = {"raw", "buffer_size", NULL};
1253 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1254 PyObject *raw;
1255
1256 self->ok = 0;
1257 self->detached = 0;
1258
1259 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1260 &raw, &buffer_size)) {
1261 return -1;
1262 }
1263
1264 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
1265 return -1;
1266
1267 Py_CLEAR(self->raw);
1268 Py_INCREF(raw);
1269 self->raw = raw;
1270 self->buffer_size = buffer_size;
1271 self->readable = 1;
1272 self->writable = 0;
1273
1274 if (_buffered_init(self) < 0)
1275 return -1;
1276 _bufferedreader_reset_buf(self);
1277
1278 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1279 Py_TYPE(raw) == &PyFileIO_Type);
1280
1281 self->ok = 1;
1282 return 0;
1283 }
1284
1285 static Py_ssize_t
1286 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
1287 {
1288 Py_buffer buf;
1289 PyObject *memobj, *res;
1290 Py_ssize_t n;
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)
1293 return -1;
1294 memobj = PyMemoryView_FromBuffer(&buf);
1295 if (memobj == NULL)
1296 return -1;
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).
1301 */
1302 do {
1303 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1304 } while (res == NULL && _PyIO_trap_eintr());
1305 Py_DECREF(memobj);
1306 if (res == NULL)
1307 return -1;
1308 if (res == Py_None) {
1309 /* Non-blocking stream would have blocked. Special return code! */
1310 Py_DECREF(res);
1311 return -2;
1312 }
1313 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1314 Py_DECREF(res);
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);
1319 return -1;
1320 }
1321 if (n > 0 && self->abs_pos != -1)
1322 self->abs_pos += n;
1323 return n;
1324 }
1325
1326 static Py_ssize_t
1327 _bufferedreader_fill_buffer(buffered *self)
1328 {
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);
1332 else
1333 start = 0;
1334 len = self->buffer_size - start;
1335 n = _bufferedreader_raw_read(self, self->buffer + start, len);
1336 if (n <= 0)
1337 return n;
1338 self->read_end = start + n;
1339 self->raw_pos = start + n;
1340 return n;
1341 }
1342
1343 static PyObject *
1344 _bufferedreader_read_all(buffered *self)
1345 {
1346 Py_ssize_t current_size;
1347 PyObject *res, *data = NULL;
1348 PyObject *chunks = PyList_New(0);
1349
1350 if (chunks == NULL)
1351 return NULL;
1352
1353 /* First copy what we have in the current buffer. */
1354 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1355 if (current_size) {
1356 data = PyBytes_FromStringAndSize(
1357 self->buffer + self->pos, current_size);
1358 if (data == NULL) {
1359 Py_DECREF(chunks);
1360 return NULL;
1361 }
1362 self->pos += current_size;
1363 }
1364 /* We're going past the buffer's bounds, flush it */
1365 if (self->writable) {
1366 res = buffered_flush_and_rewind_unlocked(self);
1367 if (res == NULL) {
1368 Py_DECREF(chunks);
1369 return NULL;
1370 }
1371 Py_CLEAR(res);
1372 }
1373 _bufferedreader_reset_buf(self);
1374 while (1) {
1375 if (data) {
1376 if (PyList_Append(chunks, data) < 0) {
1377 Py_DECREF(data);
1378 Py_DECREF(chunks);
1379 return NULL;
1380 }
1381 Py_DECREF(data);
1382 }
1383
1384 /* Read until EOF or until read() would block. */
1385 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1386 if (data == NULL) {
1387 Py_DECREF(chunks);
1388 return NULL;
1389 }
1390 if (data != Py_None && !PyBytes_Check(data)) {
1391 Py_DECREF(data);
1392 Py_DECREF(chunks);
1393 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1394 return NULL;
1395 }
1396 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1397 if (current_size == 0) {
1398 Py_DECREF(chunks);
1399 return data;
1400 }
1401 else {
1402 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1403 Py_DECREF(data);
1404 Py_DECREF(chunks);
1405 return res;
1406 }
1407 }
1408 current_size += PyBytes_GET_SIZE(data);
1409 if (self->abs_pos != -1)
1410 self->abs_pos += PyBytes_GET_SIZE(data);
1411 }
1412 }
1413
1414 /* Read n bytes from the buffer if it can, otherwise return None.
1415 This function is simple enough that it can run unlocked. */
1416 static PyObject *
1417 _bufferedreader_read_fast(buffered *self, Py_ssize_t n)
1418 {
1419 Py_ssize_t current_size;
1420
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);
1425 if (res != NULL)
1426 self->pos += n;
1427 return res;
1428 }
1429 Py_RETURN_NONE;
1430 }
1431
1432 /* Generic read function: read from the stream until enough bytes are read,
1433 * or until an EOF occurs or until read() would block.
1434 */
1435 static PyObject *
1436 _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
1437 {
1438 PyObject *res = NULL;
1439 Py_ssize_t current_size, remaining, written;
1440 char *out;
1441
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);
1445
1446 res = PyBytes_FromStringAndSize(NULL, n);
1447 if (res == NULL)
1448 goto error;
1449 out = PyBytes_AS_STRING(res);
1450 remaining = n;
1451 written = 0;
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;
1457 }
1458 /* Flush the write buffer if necessary */
1459 if (self->writable) {
1460 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1461 if (r == NULL)
1462 goto error;
1463 Py_DECREF(r);
1464 }
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);
1470 if (r == 0)
1471 break;
1472 r = _bufferedreader_raw_read(self, out + written, r);
1473 if (r == -1)
1474 goto error;
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))
1479 goto error;
1480 return res;
1481 }
1482 Py_DECREF(res);
1483 Py_INCREF(Py_None);
1484 return Py_None;
1485 }
1486 remaining -= r;
1487 written += r;
1488 }
1489 assert(remaining <= self->buffer_size);
1490 self->pos = 0;
1491 self->raw_pos = 0;
1492 self->read_end = 0;
1493 /* NOTE: when the read is satisfied, we avoid issuing any additional
1494 reads, which could block indefinitely (e.g. on a socket).
1495 See issue #9550. */
1496 while (remaining > 0 && self->read_end < self->buffer_size) {
1497 Py_ssize_t r = _bufferedreader_fill_buffer(self);
1498 if (r == -1)
1499 goto error;
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))
1504 goto error;
1505 return res;
1506 }
1507 Py_DECREF(res);
1508 Py_INCREF(Py_None);
1509 return Py_None;
1510 }
1511 if (remaining > r) {
1512 memcpy(out + written, self->buffer + self->pos, r);
1513 written += r;
1514 self->pos += r;
1515 remaining -= r;
1516 }
1517 else if (remaining > 0) {
1518 memcpy(out + written, self->buffer + self->pos, remaining);
1519 written += remaining;
1520 self->pos += remaining;
1521 remaining = 0;
1522 }
1523 if (remaining == 0)
1524 break;
1525 }
1526
1527 return res;
1528
1529 error:
1530 Py_XDECREF(res);
1531 return NULL;
1532 }
1533
1534 static PyObject *
1535 _bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
1536 {
1537 Py_ssize_t have, r;
1538
1539 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1540 /* Constraints:
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
1543 to make some place.
1544 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1545 */
1546 if (have > 0) {
1547 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1548 }
1549
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);
1553 if (r == -1)
1554 return NULL;
1555 if (r == -2)
1556 r = 0;
1557 self->pos = 0;
1558 return PyBytes_FromStringAndSize(self->buffer, r);
1559 }
1560
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},
1571
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},
1580 {NULL, NULL}
1581 };
1582
1583 static PyMemberDef bufferedreader_members[] = {
1584 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
1585 {NULL}
1586 };
1587
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},
1592 {NULL}
1593 };
1594
1595
1596 PyTypeObject PyBufferedReader_Type = {
1597 PyVarObject_HEAD_INIT(NULL, 0)
1598 "_io.BufferedReader", /*tp_name*/
1599 sizeof(buffered), /*tp_basicsize*/
1600 0, /*tp_itemsize*/
1601 (destructor)buffered_dealloc, /*tp_dealloc*/
1602 0, /*tp_print*/
1603 0, /*tp_getattr*/
1604 0, /*tp_setattr*/
1605 0, /*tp_compare */
1606 (reprfunc)buffered_repr, /*tp_repr*/
1607 0, /*tp_as_number*/
1608 0, /*tp_as_sequence*/
1609 0, /*tp_as_mapping*/
1610 0, /*tp_hash */
1611 0, /*tp_call*/
1612 0, /*tp_str*/
1613 0, /*tp_getattro*/
1614 0, /*tp_setattro*/
1615 0, /*tp_as_buffer*/
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*/
1623 0, /* tp_iter */
1624 (iternextfunc)buffered_iternext, /* tp_iternext */
1625 bufferedreader_methods, /* tp_methods */
1626 bufferedreader_members, /* tp_members */
1627 bufferedreader_getset, /* tp_getset */
1628 0, /* tp_base */
1629 0, /* tp_dict */
1630 0, /* tp_descr_get */
1631 0, /* tp_descr_set */
1632 offsetof(buffered, dict), /* tp_dictoffset */
1633 (initproc)bufferedreader_init, /* tp_init */
1634 0, /* tp_alloc */
1635 PyType_GenericNew, /* tp_new */
1636 };
1637 \f
1638
1639
1640 static int
1641 complain_about_max_buffer_size(void)
1642 {
1643 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1644 "max_buffer_size is deprecated", 1) < 0)
1645 return 0;
1646 return 1;
1647 }
1648
1649 /*
1650 * class BufferedWriter
1651 */
1652 PyDoc_STRVAR(bufferedwriter_doc,
1653 "A buffer for a writeable sequential RawIO object.\n"
1654 "\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"
1658 );
1659
1660 static void
1661 _bufferedwriter_reset_buf(buffered *self)
1662 {
1663 self->write_pos = 0;
1664 self->write_end = -1;
1665 }
1666
1667 static int
1668 bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
1669 {
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;
1674 PyObject *raw;
1675
1676 self->ok = 0;
1677 self->detached = 0;
1678
1679 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedWriter", kwlist,
1680 &raw, &buffer_size, &max_buffer_size)) {
1681 return -1;
1682 }
1683
1684 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1685 return -1;
1686
1687 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
1688 return -1;
1689
1690 Py_CLEAR(self->raw);
1691 Py_INCREF(raw);
1692 self->raw = raw;
1693 self->readable = 0;
1694 self->writable = 1;
1695
1696 self->buffer_size = buffer_size;
1697 if (_buffered_init(self) < 0)
1698 return -1;
1699 _bufferedwriter_reset_buf(self);
1700 self->pos = 0;
1701
1702 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1703 Py_TYPE(raw) == &PyFileIO_Type);
1704
1705 self->ok = 1;
1706 return 0;
1707 }
1708
1709 static Py_ssize_t
1710 _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
1711 {
1712 Py_buffer buf;
1713 PyObject *memobj, *res;
1714 Py_ssize_t n;
1715 int errnum;
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)
1718 return -1;
1719 memobj = PyMemoryView_FromBuffer(&buf);
1720 if (memobj == NULL)
1721 return -1;
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).
1726 */
1727 do {
1728 errno = 0;
1729 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1730 errnum = errno;
1731 } while (res == NULL && _PyIO_trap_eintr());
1732 Py_DECREF(memobj);
1733 if (res == NULL)
1734 return -1;
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(). */
1739 Py_DECREF(res);
1740 errno = errnum;
1741 return -2;
1742 }
1743 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1744 Py_DECREF(res);
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);
1749 return -1;
1750 }
1751 if (n > 0 && self->abs_pos != -1)
1752 self->abs_pos += n;
1753 return n;
1754 }
1755
1756 /* `restore_pos` is 1 if we need to restore the raw stream position at
1757 the end, 0 otherwise. */
1758 static PyObject *
1759 _bufferedwriter_flush_unlocked(buffered *self)
1760 {
1761 Py_ssize_t written = 0;
1762 Py_off_t n, rewind;
1763
1764 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1765 goto end;
1766 /* First, rewind */
1767 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1768 if (rewind != 0) {
1769 n = _buffered_raw_seek(self, -rewind, 1);
1770 if (n < 0) {
1771 goto error;
1772 }
1773 self->raw_pos -= rewind;
1774 }
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));
1780 if (n == -1) {
1781 goto error;
1782 }
1783 else if (n == -2) {
1784 _set_BlockingIOError("write could not complete without blocking",
1785 0);
1786 goto error;
1787 }
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)
1795 goto error;
1796 }
1797
1798 _bufferedwriter_reset_buf(self);
1799
1800 end:
1801 Py_RETURN_NONE;
1802
1803 error:
1804 return NULL;
1805 }
1806
1807 static PyObject *
1808 bufferedwriter_write(buffered *self, PyObject *args)
1809 {
1810 PyObject *res = NULL;
1811 Py_buffer buf;
1812 Py_ssize_t written, avail, remaining;
1813 Py_off_t offset;
1814
1815 CHECK_INITIALIZED(self)
1816 if (!PyArg_ParseTuple(args, "s*:write", &buf)) {
1817 return NULL;
1818 }
1819
1820 if (IS_CLOSED(self)) {
1821 PyErr_SetString(PyExc_ValueError, "write to closed file");
1822 PyBuffer_Release(&buf);
1823 return NULL;
1824 }
1825
1826 if (!ENTER_BUFFERED(self)) {
1827 PyBuffer_Release(&buf);
1828 return NULL;
1829 }
1830
1831 /* Fast path: the data to write can be fully buffered. */
1832 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1833 self->pos = 0;
1834 self->raw_pos = 0;
1835 }
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;
1841 }
1842 ADJUST_POSITION(self, self->pos + buf.len);
1843 if (self->pos > self->write_end)
1844 self->write_end = self->pos;
1845 written = buf.len;
1846 goto end;
1847 }
1848
1849 /* First write the current buffer */
1850 res = _bufferedwriter_flush_unlocked(self);
1851 if (res == NULL) {
1852 Py_ssize_t *w = _buffered_check_blocking_error();
1853 if (w == NULL)
1854 goto error;
1855 if (self->readable)
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 */
1870 PyErr_Clear();
1871 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1872 self->write_end += buf.len;
1873 self->pos += buf.len;
1874 written = buf.len;
1875 goto end;
1876 }
1877 /* Buffer as much as possible. */
1878 memcpy(self->buffer + self->write_end, buf.buf, avail);
1879 self->write_end += avail;
1880 self->pos += 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",
1885 avail);
1886 goto error;
1887 }
1888 Py_CLEAR(res);
1889
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).
1894 Fixes issue #6629.
1895 */
1896 offset = RAW_OFFSET(self);
1897 if (offset != 0) {
1898 if (_buffered_raw_seek(self, -offset, 1) < 0)
1899 goto error;
1900 self->raw_pos -= offset;
1901 }
1902
1903 /* Then write buf itself. At this point the buffer has been emptied. */
1904 remaining = buf.len;
1905 written = 0;
1906 while (remaining > self->buffer_size) {
1907 Py_ssize_t n = _bufferedwriter_raw_write(
1908 self, (char *) buf.buf + written, buf.len - written);
1909 if (n == -1) {
1910 goto error;
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);
1917 self->raw_pos = 0;
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);
1923 goto error;
1924 }
1925 PyErr_Clear();
1926 break;
1927 }
1928 written += n;
1929 remaining -= n;
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)
1934 goto error;
1935 }
1936 if (self->readable)
1937 _bufferedreader_reset_buf(self);
1938 if (remaining > 0) {
1939 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1940 written += remaining;
1941 }
1942 self->write_pos = 0;
1943 /* TODO: sanity check (remaining >= 0) */
1944 self->write_end = remaining;
1945 ADJUST_POSITION(self, remaining);
1946 self->raw_pos = 0;
1947
1948 end:
1949 res = PyLong_FromSsize_t(written);
1950
1951 error:
1952 LEAVE_BUFFERED(self)
1953 PyBuffer_Release(&buf);
1954 return res;
1955 }
1956
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},
1966
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},
1973 {NULL, NULL}
1974 };
1975
1976 static PyMemberDef bufferedwriter_members[] = {
1977 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
1978 {NULL}
1979 };
1980
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},
1985 {NULL}
1986 };
1987
1988
1989 PyTypeObject PyBufferedWriter_Type = {
1990 PyVarObject_HEAD_INIT(NULL, 0)
1991 "_io.BufferedWriter", /*tp_name*/
1992 sizeof(buffered), /*tp_basicsize*/
1993 0, /*tp_itemsize*/
1994 (destructor)buffered_dealloc, /*tp_dealloc*/
1995 0, /*tp_print*/
1996 0, /*tp_getattr*/
1997 0, /*tp_setattr*/
1998 0, /*tp_compare */
1999 (reprfunc)buffered_repr, /*tp_repr*/
2000 0, /*tp_as_number*/
2001 0, /*tp_as_sequence*/
2002 0, /*tp_as_mapping*/
2003 0, /*tp_hash */
2004 0, /*tp_call*/
2005 0, /*tp_str*/
2006 0, /*tp_getattro*/
2007 0, /*tp_setattro*/
2008 0, /*tp_as_buffer*/
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*/
2016 0, /* tp_iter */
2017 0, /* tp_iternext */
2018 bufferedwriter_methods, /* tp_methods */
2019 bufferedwriter_members, /* tp_members */
2020 bufferedwriter_getset, /* tp_getset */
2021 0, /* tp_base */
2022 0, /* tp_dict */
2023 0, /* tp_descr_get */
2024 0, /* tp_descr_set */
2025 offsetof(buffered, dict), /* tp_dictoffset */
2026 (initproc)bufferedwriter_init, /* tp_init */
2027 0, /* tp_alloc */
2028 PyType_GenericNew, /* tp_new */
2029 };
2030 \f
2031
2032
2033 /*
2034 * BufferedRWPair
2035 */
2036
2037 PyDoc_STRVAR(bufferedrwpair_doc,
2038 "A buffered reader and writer object together.\n"
2039 "\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"
2043 "\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"
2047 );
2048
2049 /* XXX The usefulness of this (compared to having two separate IO objects) is
2050 * questionable.
2051 */
2052
2053 typedef struct {
2054 PyObject_HEAD
2055 buffered *reader;
2056 buffered *writer;
2057 PyObject *dict;
2058 PyObject *weakreflist;
2059 } rwpair;
2060
2061 static int
2062 bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
2063 {
2064 PyObject *reader, *writer;
2065 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
2066 Py_ssize_t max_buffer_size = -234;
2067
2068 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2069 &buffer_size, &max_buffer_size)) {
2070 return -1;
2071 }
2072
2073 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2074 return -1;
2075
2076 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
2077 return -1;
2078 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
2079 return -1;
2080
2081 self->reader = (buffered *) PyObject_CallFunction(
2082 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
2083 if (self->reader == NULL)
2084 return -1;
2085
2086 self->writer = (buffered *) PyObject_CallFunction(
2087 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
2088 if (self->writer == NULL) {
2089 Py_CLEAR(self->reader);
2090 return -1;
2091 }
2092
2093 return 0;
2094 }
2095
2096 static int
2097 bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
2098 {
2099 Py_VISIT(self->dict);
2100 return 0;
2101 }
2102
2103 static int
2104 bufferedrwpair_clear(rwpair *self)
2105 {
2106 Py_CLEAR(self->reader);
2107 Py_CLEAR(self->writer);
2108 Py_CLEAR(self->dict);
2109 return 0;
2110 }
2111
2112 static void
2113 bufferedrwpair_dealloc(rwpair *self)
2114 {
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);
2122 }
2123
2124 static PyObject *
2125 _forward_call(buffered *self, const char *name, PyObject *args)
2126 {
2127 PyObject *func, *ret;
2128 if (self == NULL) {
2129 PyErr_SetString(PyExc_ValueError,
2130 "I/O operation on uninitialized object");
2131 return NULL;
2132 }
2133
2134 func = PyObject_GetAttrString((PyObject *)self, name);
2135 if (func == NULL) {
2136 PyErr_SetString(PyExc_AttributeError, name);
2137 return NULL;
2138 }
2139
2140 ret = PyObject_CallObject(func, args);
2141 Py_DECREF(func);
2142 return ret;
2143 }
2144
2145 static PyObject *
2146 bufferedrwpair_read(rwpair *self, PyObject *args)
2147 {
2148 return _forward_call(self->reader, "read", args);
2149 }
2150
2151 static PyObject *
2152 bufferedrwpair_peek(rwpair *self, PyObject *args)
2153 {
2154 return _forward_call(self->reader, "peek", args);
2155 }
2156
2157 static PyObject *
2158 bufferedrwpair_read1(rwpair *self, PyObject *args)
2159 {
2160 return _forward_call(self->reader, "read1", args);
2161 }
2162
2163 static PyObject *
2164 bufferedrwpair_readinto(rwpair *self, PyObject *args)
2165 {
2166 return _forward_call(self->reader, "readinto", args);
2167 }
2168
2169 static PyObject *
2170 bufferedrwpair_write(rwpair *self, PyObject *args)
2171 {
2172 return _forward_call(self->writer, "write", args);
2173 }
2174
2175 static PyObject *
2176 bufferedrwpair_flush(rwpair *self, PyObject *args)
2177 {
2178 return _forward_call(self->writer, "flush", args);
2179 }
2180
2181 static PyObject *
2182 bufferedrwpair_readable(rwpair *self, PyObject *args)
2183 {
2184 return _forward_call(self->reader, "readable", args);
2185 }
2186
2187 static PyObject *
2188 bufferedrwpair_writable(rwpair *self, PyObject *args)
2189 {
2190 return _forward_call(self->writer, "writable", args);
2191 }
2192
2193 static PyObject *
2194 bufferedrwpair_close(rwpair *self, PyObject *args)
2195 {
2196 PyObject *exc = NULL, *val, *tb;
2197 PyObject *ret = _forward_call(self->writer, "close", args);
2198 if (ret == NULL)
2199 PyErr_Fetch(&exc, &val, &tb);
2200 else
2201 Py_DECREF(ret);
2202 ret = _forward_call(self->reader, "close", args);
2203 if (exc != NULL) {
2204 if (ret != NULL) {
2205 Py_CLEAR(ret);
2206 PyErr_Restore(exc, val, tb);
2207 }
2208 else {
2209 Py_DECREF(exc);
2210 Py_XDECREF(val);
2211 Py_XDECREF(tb);
2212 }
2213 }
2214 return ret;
2215 }
2216
2217 static PyObject *
2218 bufferedrwpair_isatty(rwpair *self, PyObject *args)
2219 {
2220 PyObject *ret = _forward_call(self->writer, "isatty", args);
2221
2222 if (ret != Py_False) {
2223 /* either True or exception */
2224 return ret;
2225 }
2226 Py_DECREF(ret);
2227
2228 return _forward_call(self->reader, "isatty", args);
2229 }
2230
2231 static PyObject *
2232 bufferedrwpair_closed_get(rwpair *self, void *context)
2233 {
2234 if (self->writer == NULL) {
2235 PyErr_SetString(PyExc_RuntimeError,
2236 "the BufferedRWPair object is being garbage-collected");
2237 return NULL;
2238 }
2239 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2240 }
2241
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},
2247
2248 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2249 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
2250
2251 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2252 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
2253
2254 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2255 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
2256
2257 {NULL, NULL}
2258 };
2259
2260 static PyGetSetDef bufferedrwpair_getset[] = {
2261 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
2262 {NULL}
2263 };
2264
2265 PyTypeObject PyBufferedRWPair_Type = {
2266 PyVarObject_HEAD_INIT(NULL, 0)
2267 "_io.BufferedRWPair", /*tp_name*/
2268 sizeof(rwpair), /*tp_basicsize*/
2269 0, /*tp_itemsize*/
2270 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
2271 0, /*tp_print*/
2272 0, /*tp_getattr*/
2273 0, /*tp_setattr*/
2274 0, /*tp_compare */
2275 0, /*tp_repr*/
2276 0, /*tp_as_number*/
2277 0, /*tp_as_sequence*/
2278 0, /*tp_as_mapping*/
2279 0, /*tp_hash */
2280 0, /*tp_call*/
2281 0, /*tp_str*/
2282 0, /*tp_getattro*/
2283 0, /*tp_setattro*/
2284 0, /*tp_as_buffer*/
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*/
2292 0, /* tp_iter */
2293 0, /* tp_iternext */
2294 bufferedrwpair_methods, /* tp_methods */
2295 0, /* tp_members */
2296 bufferedrwpair_getset, /* tp_getset */
2297 0, /* tp_base */
2298 0, /* tp_dict */
2299 0, /* tp_descr_get */
2300 0, /* tp_descr_set */
2301 offsetof(rwpair, dict), /* tp_dictoffset */
2302 (initproc)bufferedrwpair_init, /* tp_init */
2303 0, /* tp_alloc */
2304 PyType_GenericNew, /* tp_new */
2305 };
2306 \f
2307
2308
2309 /*
2310 * BufferedRandom
2311 */
2312
2313 PyDoc_STRVAR(bufferedrandom_doc,
2314 "A buffered interface to random access streams.\n"
2315 "\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"
2319 );
2320
2321 static int
2322 bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
2323 {
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;
2327 PyObject *raw;
2328
2329 self->ok = 0;
2330 self->detached = 0;
2331
2332 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedRandom", kwlist,
2333 &raw, &buffer_size, &max_buffer_size)) {
2334 return -1;
2335 }
2336
2337 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2338 return -1;
2339
2340 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2341 return -1;
2342 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2343 return -1;
2344 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2345 return -1;
2346
2347 Py_CLEAR(self->raw);
2348 Py_INCREF(raw);
2349 self->raw = raw;
2350 self->buffer_size = buffer_size;
2351 self->readable = 1;
2352 self->writable = 1;
2353
2354 if (_buffered_init(self) < 0)
2355 return -1;
2356 _bufferedreader_reset_buf(self);
2357 _bufferedwriter_reset_buf(self);
2358 self->pos = 0;
2359
2360 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2361 Py_TYPE(raw) == &PyFileIO_Type);
2362
2363 self->ok = 1;
2364 return 0;
2365 }
2366
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},
2376
2377 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2378
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},
2389 {NULL, NULL}
2390 };
2391
2392 static PyMemberDef bufferedrandom_members[] = {
2393 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2394 {NULL}
2395 };
2396
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},
2401 {NULL}
2402 };
2403
2404
2405 PyTypeObject PyBufferedRandom_Type = {
2406 PyVarObject_HEAD_INIT(NULL, 0)
2407 "_io.BufferedRandom", /*tp_name*/
2408 sizeof(buffered), /*tp_basicsize*/
2409 0, /*tp_itemsize*/
2410 (destructor)buffered_dealloc, /*tp_dealloc*/
2411 0, /*tp_print*/
2412 0, /*tp_getattr*/
2413 0, /*tp_setattr*/
2414 0, /*tp_compare */
2415 (reprfunc)buffered_repr, /*tp_repr*/
2416 0, /*tp_as_number*/
2417 0, /*tp_as_sequence*/
2418 0, /*tp_as_mapping*/
2419 0, /*tp_hash */
2420 0, /*tp_call*/
2421 0, /*tp_str*/
2422 0, /*tp_getattro*/
2423 0, /*tp_setattro*/
2424 0, /*tp_as_buffer*/
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*/
2432 0, /* tp_iter */
2433 (iternextfunc)buffered_iternext, /* tp_iternext */
2434 bufferedrandom_methods, /* tp_methods */
2435 bufferedrandom_members, /* tp_members */
2436 bufferedrandom_getset, /* tp_getset */
2437 0, /* tp_base */
2438 0, /*tp_dict*/
2439 0, /* tp_descr_get */
2440 0, /* tp_descr_set */
2441 offsetof(buffered, dict), /*tp_dictoffset*/
2442 (initproc)bufferedrandom_init, /* tp_init */
2443 0, /* tp_alloc */
2444 PyType_GenericNew, /* tp_new */
2445 };
2446