source: python/trunk/Modules/_io/bufferedio.c

Last change on this file was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

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