blob: 62a350b691f1a74e08f64e59613600473d7f4fef [file] [log] [blame]
Antoine Pitrou19690592009-06-12 20:14:08 +00001/*
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;
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000227 volatile long owner;
Antoine Pitrou19690592009-06-12 20:14:08 +0000228#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
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000263
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;
Antoine Pitroue50efaa2009-11-01 11:58:22 +0000276 }
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000277 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) )
Antoine Pitrou19690592009-06-12 20:14:08 +0000287
288#define LEAVE_BUFFERED(self) \
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000289 do { \
290 self->owner = 0; \
291 PyThread_release_lock(self->lock); \
292 } while(0);
293
Antoine Pitrou19690592009-06-12 20:14:08 +0000294#else
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000295#define ENTER_BUFFERED(self) 1
Antoine Pitrou19690592009-06-12 20:14:08 +0000296#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
Antoine Pitroubff5df02012-07-29 19:02:46 +0200389static 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
Antoine Pitrou19690592009-06-12 20:14:08 +0000400static 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{
Benjamin Petersona2d6d712012-12-20 12:24:10 -0600458 PyObject *res = NULL, *exc = NULL, *val, *tb;
Antoine Pitrou19690592009-06-12 20:14:08 +0000459 int r;
460
461 CHECK_INITIALIZED(self)
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000462 if (!ENTER_BUFFERED(self))
463 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +0000464
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);
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000476 if (!ENTER_BUFFERED(self))
477 return NULL;
Benjamin Petersona2d6d712012-12-20 12:24:10 -0600478 if (res == NULL)
479 PyErr_Fetch(&exc, &val, &tb);
480 else
481 Py_DECREF(res);
Antoine Pitrou19690592009-06-12 20:14:08 +0000482
483 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
484
Benjamin Petersona2d6d712012-12-20 12:24:10 -0600485 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
Antoine Pitrou19690592009-06-12 20:14:08 +0000497end:
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 *
Antoine Pitrou5aa7df32011-11-21 20:16:44 +0100576_bufferedwriter_flush_unlocked(buffered *);
Antoine Pitrou19690592009-06-12 20:14:08 +0000577static 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
Antoine Pitrou5aa7df32011-11-21 20:16:44 +0100597/* 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
Antoine Pitrou19690592009-06-12 20:14:08 +0000609/* 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,
Mark Dickinson889d96452009-11-24 20:51:48 +0000641 "Raw stream returned invalid position %" PY_PRIdOFF,
642 (PY_OFF_T_COMPAT)n);
Antoine Pitrou19690592009-06-12 20:14:08 +0000643 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,
Mark Dickinson889d96452009-11-24 20:51:48 +0000674 "Raw stream returned invalid position %" PY_PRIdOFF,
675 (PY_OFF_T_COMPAT)n);
Antoine Pitrou19690592009-06-12 20:14:08 +0000676 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
Antoine Pitrou607951d2010-08-01 16:57:17 +0000699 if (self->lock)
700 PyThread_free_lock(self->lock);
Antoine Pitrou19690592009-06-12 20:14:08 +0000701 self->lock = PyThread_allocate_lock();
702 if (self->lock == NULL) {
703 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
704 return -1;
705 }
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000706 self->owner = 0;
Antoine Pitrou19690592009-06-12 20:14:08 +0000707#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
Antoine Pitrou6439c002011-02-25 21:35:47 +0000721/* 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*/
Gregory P. Smith99716162012-10-12 13:02:06 -0700725int
726_PyIO_trap_eintr(void)
Antoine Pitrou6439c002011-02-25 21:35:47 +0000727{
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
Antoine Pitrou19690592009-06-12 20:14:08 +0000754/*
755 * Shared methods and wrappers
756 */
757
758static PyObject *
Antoine Pitrou808cec52011-08-20 15:40:58 +0200759buffered_flush_and_rewind_unlocked(buffered *self)
760{
761 PyObject *res;
762
Antoine Pitrou5aa7df32011-11-21 20:16:44 +0100763 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitrou808cec52011-08-20 15:40:58 +0200764 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 *
Antoine Pitrou19690592009-06-12 20:14:08 +0000781buffered_flush(buffered *self, PyObject *args)
782{
783 PyObject *res;
784
785 CHECK_INITIALIZED(self)
786 CHECK_CLOSED(self, "flush of closed file")
787
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000788 if (!ENTER_BUFFERED(self))
789 return NULL;
Antoine Pitrou808cec52011-08-20 15:40:58 +0200790 res = buffered_flush_and_rewind_unlocked(self);
Antoine Pitrou19690592009-06-12 20:14:08 +0000791 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
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000807 if (!ENTER_BUFFERED(self))
808 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +0000809
810 if (self->writable) {
Antoine Pitrou808cec52011-08-20 15:40:58 +0200811 res = buffered_flush_and_rewind_unlocked(self);
Antoine Pitrou19690592009-06-12 20:14:08 +0000812 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)
Benjamin Petersonddd392c2009-12-13 19:19:07 +0000830 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Antoine Pitrou19690592009-06-12 20:14:08 +0000831 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 */
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000843 if (!ENTER_BUFFERED(self))
844 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +0000845 res = _bufferedreader_read_all(self);
Antoine Pitrou19690592009-06-12 20:14:08 +0000846 }
847 else {
848 res = _bufferedreader_read_fast(self, n);
Antoine Pitrou808cec52011-08-20 15:40:58 +0200849 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);
Antoine Pitrou19690592009-06-12 20:14:08 +0000855 }
856
Antoine Pitrou808cec52011-08-20 15:40:58 +0200857 LEAVE_BUFFERED(self)
Antoine Pitrou19690592009-06-12 20:14:08 +0000858 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
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000880 if (!ENTER_BUFFERED(self))
881 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +0000882
Antoine Pitrou19690592009-06-12 20:14:08 +0000883 /* 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
Antoine Pitrou808cec52011-08-20 15:40:58 +0200902 if (self->writable) {
903 res = buffered_flush_and_rewind_unlocked(self);
904 if (res == NULL)
905 goto end;
906 Py_DECREF(res);
907 }
908
Antoine Pitrou19690592009-06-12 20:14:08 +0000909 /* 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{
Antoine Pitrou19690592009-06-12 20:14:08 +0000931 CHECK_INITIALIZED(self)
932
Antoine Pitrou808cec52011-08-20 15:40:58 +0200933 /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
934 return bufferediobase_readinto((PyObject *)self, args);
Antoine Pitrou19690592009-06-12 20:14:08 +0000935}
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
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +0000968 if (!ENTER_BUFFERED(self))
969 goto end_unlocked;
Antoine Pitrou19690592009-06-12 20:14:08 +0000970
971 /* Now we try to get some more from the raw stream */
Antoine Pitrou19690592009-06-12 20:14:08 +0000972 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;
Antoine Pitrou808cec52011-08-20 15:40:58 +0200985 self->pos += n;
Antoine Pitrou19690592009-06-12 20:14:08 +0000986 if (limit >= 0)
987 limit -= n;
988 }
Antoine Pitrou808cec52011-08-20 15:40:58 +0200989 if (self->writable) {
990 PyObject *r = buffered_flush_and_rewind_unlocked(self);
991 if (r == NULL)
992 goto end;
993 Py_DECREF(r);
994 }
Antoine Pitrou19690592009-06-12 20:14:08 +0000995
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{
Antoine Pitrou19690592009-06-12 20:14:08 +00001051 Py_ssize_t limit = -1;
1052
1053 CHECK_INITIALIZED(self)
Benjamin Petersonddd392c2009-12-13 19:19:07 +00001054 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Antoine Pitrou19690592009-06-12 20:14:08 +00001055 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +00001056 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
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +00001120 if (!ENTER_BUFFERED(self))
1121 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +00001122
1123 /* Fallback: invoke raw seek() method and clear buffer */
1124 if (self->writable) {
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001125 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001126 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
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +00001159 if (!ENTER_BUFFERED(self))
1160 return NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +00001161
1162 if (self->writable) {
Antoine Pitrou808cec52011-08-20 15:40:58 +02001163 res = buffered_flush_and_rewind_unlocked(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001164 if (res == NULL)
1165 goto end;
1166 Py_CLEAR(res);
1167 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001168 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;
Antoine Pitrou6439c002011-02-25 21:35:47 +00001304 /* 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);
Gregory P. Smith99716162012-10-12 13:02:06 -07001311 } while (res == NULL && _PyIO_trap_eintr());
Antoine Pitrou19690592009-06-12 20:14:08 +00001312 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 }
Antoine Pitrou808cec52011-08-20 15:40:58 +02001369 self->pos += current_size;
Antoine Pitrou19690592009-06-12 20:14:08 +00001370 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001371 /* We're going past the buffer's bounds, flush it */
1372 if (self->writable) {
Antoine Pitrou808cec52011-08-20 15:40:58 +02001373 res = buffered_flush_and_rewind_unlocked(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001374 if (res == NULL) {
1375 Py_DECREF(chunks);
1376 return NULL;
1377 }
1378 Py_CLEAR(res);
1379 }
Antoine Pitrou808cec52011-08-20 15:40:58 +02001380 _bufferedreader_reset_buf(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001381 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;
Antoine Pitrou808cec52011-08-20 15:40:58 +02001463 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);
Antoine Pitrou19690592009-06-12 20:14:08 +00001471 }
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;
Antoine Pitroucb4f47c2010-08-11 13:40:17 +00001500 /* 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) {
Antoine Pitrou19690592009-06-12 20:14:08 +00001504 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},
Antoine Pitroubff5df02012-07-29 19:02:46 +02001586 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Antoine Pitrou19690592009-06-12 20:14:08 +00001587 {NULL, NULL}
1588};
1589
1590static PyMemberDef bufferedreader_members[] = {
Antoine Pitroufc9ead62010-12-21 21:26:55 +00001591 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou19690592009-06-12 20:14:08 +00001592 {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
1647static int
1648complain_about_max_buffer_size(void)
1649{
1650 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1651 "max_buffer_size is deprecated", 1) < 0)
1652 return 0;
1653 return 1;
1654}
1655
1656/*
1657 * class BufferedWriter
1658 */
1659PyDoc_STRVAR(bufferedwriter_doc,
1660 "A buffer for a writeable sequential RawIO object.\n"
1661 "\n"
1662 "The constructor creates a BufferedWriter for the given writeable raw\n"
1663 "stream. If the buffer_size is not given, it defaults to\n"
1664 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1665 );
1666
1667static void
1668_bufferedwriter_reset_buf(buffered *self)
1669{
1670 self->write_pos = 0;
1671 self->write_end = -1;
1672}
1673
1674static int
1675bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
1676{
1677 /* TODO: properly deprecate max_buffer_size */
1678 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1679 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1680 Py_ssize_t max_buffer_size = -234;
1681 PyObject *raw;
1682
1683 self->ok = 0;
1684 self->detached = 0;
1685
R David Murray5b2cf5e2013-02-23 22:11:21 -05001686 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedWriter", kwlist,
Antoine Pitrou19690592009-06-12 20:14:08 +00001687 &raw, &buffer_size, &max_buffer_size)) {
1688 return -1;
1689 }
1690
1691 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1692 return -1;
1693
1694 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
1695 return -1;
1696
1697 Py_CLEAR(self->raw);
1698 Py_INCREF(raw);
1699 self->raw = raw;
1700 self->readable = 0;
1701 self->writable = 1;
1702
1703 self->buffer_size = buffer_size;
1704 if (_buffered_init(self) < 0)
1705 return -1;
1706 _bufferedwriter_reset_buf(self);
1707 self->pos = 0;
1708
1709 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1710 Py_TYPE(raw) == &PyFileIO_Type);
1711
1712 self->ok = 1;
1713 return 0;
1714}
1715
1716static Py_ssize_t
1717_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
1718{
1719 Py_buffer buf;
1720 PyObject *memobj, *res;
1721 Py_ssize_t n;
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001722 int errnum;
Antoine Pitrou19690592009-06-12 20:14:08 +00001723 /* NOTE: the buffer needn't be released as its object is NULL. */
1724 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1725 return -1;
1726 memobj = PyMemoryView_FromBuffer(&buf);
1727 if (memobj == NULL)
1728 return -1;
Antoine Pitrou6439c002011-02-25 21:35:47 +00001729 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1730 occurs so we needn't do it ourselves.
1731 We then retry writing, ignoring the signal if no handler has
1732 raised (see issue #10956).
1733 */
1734 do {
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001735 errno = 0;
Antoine Pitrou6439c002011-02-25 21:35:47 +00001736 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001737 errnum = errno;
Gregory P. Smith99716162012-10-12 13:02:06 -07001738 } while (res == NULL && _PyIO_trap_eintr());
Antoine Pitrou19690592009-06-12 20:14:08 +00001739 Py_DECREF(memobj);
1740 if (res == NULL)
1741 return -1;
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001742 if (res == Py_None) {
1743 /* Non-blocking stream would have blocked. Special return code!
1744 Being paranoid we reset errno in case it is changed by code
1745 triggered by a decref. errno is used by _set_BlockingIOError(). */
1746 Py_DECREF(res);
1747 errno = errnum;
1748 return -2;
1749 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001750 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1751 Py_DECREF(res);
1752 if (n < 0 || n > len) {
1753 PyErr_Format(PyExc_IOError,
1754 "raw write() returned invalid length %zd "
1755 "(should have been between 0 and %zd)", n, len);
1756 return -1;
1757 }
1758 if (n > 0 && self->abs_pos != -1)
1759 self->abs_pos += n;
1760 return n;
1761}
1762
1763/* `restore_pos` is 1 if we need to restore the raw stream position at
1764 the end, 0 otherwise. */
1765static PyObject *
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001766_bufferedwriter_flush_unlocked(buffered *self)
Antoine Pitrou19690592009-06-12 20:14:08 +00001767{
1768 Py_ssize_t written = 0;
1769 Py_off_t n, rewind;
1770
1771 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1772 goto end;
1773 /* First, rewind */
1774 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1775 if (rewind != 0) {
1776 n = _buffered_raw_seek(self, -rewind, 1);
1777 if (n < 0) {
1778 goto error;
1779 }
1780 self->raw_pos -= rewind;
1781 }
1782 while (self->write_pos < self->write_end) {
1783 n = _bufferedwriter_raw_write(self,
1784 self->buffer + self->write_pos,
1785 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1786 Py_off_t, Py_ssize_t));
1787 if (n == -1) {
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001788 goto error;
1789 }
1790 else if (n == -2) {
1791 _set_BlockingIOError("write could not complete without blocking",
1792 0);
Antoine Pitrou19690592009-06-12 20:14:08 +00001793 goto error;
1794 }
1795 self->write_pos += n;
1796 self->raw_pos = self->write_pos;
1797 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitrou3ebaed62010-08-21 19:17:25 +00001798 /* Partial writes can return successfully when interrupted by a
1799 signal (see write(2)). We must run signal handlers before
1800 blocking another time, possibly indefinitely. */
1801 if (PyErr_CheckSignals() < 0)
1802 goto error;
Antoine Pitrou19690592009-06-12 20:14:08 +00001803 }
1804
Antoine Pitrou19690592009-06-12 20:14:08 +00001805 _bufferedwriter_reset_buf(self);
1806
1807end:
1808 Py_RETURN_NONE;
1809
1810error:
1811 return NULL;
1812}
1813
1814static PyObject *
1815bufferedwriter_write(buffered *self, PyObject *args)
1816{
1817 PyObject *res = NULL;
1818 Py_buffer buf;
Amaury Forgeot d'Arc3de46472009-10-05 20:18:05 +00001819 Py_ssize_t written, avail, remaining;
1820 Py_off_t offset;
Antoine Pitrou19690592009-06-12 20:14:08 +00001821
1822 CHECK_INITIALIZED(self)
1823 if (!PyArg_ParseTuple(args, "s*:write", &buf)) {
1824 return NULL;
1825 }
1826
1827 if (IS_CLOSED(self)) {
1828 PyErr_SetString(PyExc_ValueError, "write to closed file");
1829 PyBuffer_Release(&buf);
1830 return NULL;
1831 }
1832
Antoine Pitrou4cb64ad2010-12-03 19:31:52 +00001833 if (!ENTER_BUFFERED(self)) {
1834 PyBuffer_Release(&buf);
1835 return NULL;
1836 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001837
1838 /* Fast path: the data to write can be fully buffered. */
1839 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1840 self->pos = 0;
1841 self->raw_pos = 0;
1842 }
1843 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1844 if (buf.len <= avail) {
1845 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrouee46a7b2011-05-13 00:31:52 +02001846 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Antoine Pitrou19690592009-06-12 20:14:08 +00001847 self->write_pos = self->pos;
1848 }
1849 ADJUST_POSITION(self, self->pos + buf.len);
1850 if (self->pos > self->write_end)
1851 self->write_end = self->pos;
1852 written = buf.len;
1853 goto end;
1854 }
1855
1856 /* First write the current buffer */
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001857 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001858 if (res == NULL) {
1859 Py_ssize_t *w = _buffered_check_blocking_error();
1860 if (w == NULL)
1861 goto error;
1862 if (self->readable)
1863 _bufferedreader_reset_buf(self);
1864 /* Make some place by shifting the buffer. */
1865 assert(VALID_WRITE_BUFFER(self));
1866 memmove(self->buffer, self->buffer + self->write_pos,
1867 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1868 Py_off_t, Py_ssize_t));
1869 self->write_end -= self->write_pos;
1870 self->raw_pos -= self->write_pos;
1871 self->pos -= self->write_pos;
1872 self->write_pos = 0;
1873 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1874 Py_off_t, Py_ssize_t);
1875 if (buf.len <= avail) {
1876 /* Everything can be buffered */
1877 PyErr_Clear();
1878 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1879 self->write_end += buf.len;
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001880 self->pos += buf.len;
Antoine Pitrou19690592009-06-12 20:14:08 +00001881 written = buf.len;
1882 goto end;
1883 }
1884 /* Buffer as much as possible. */
1885 memcpy(self->buffer + self->write_end, buf.buf, avail);
1886 self->write_end += avail;
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001887 self->pos += avail;
1888 /* XXX Modifying the existing exception e using the pointer w
1889 will change e.characters_written but not e.args[2].
1890 Therefore we just replace with a new error. */
1891 _set_BlockingIOError("write could not complete without blocking",
1892 avail);
Antoine Pitrou19690592009-06-12 20:14:08 +00001893 goto error;
1894 }
1895 Py_CLEAR(res);
1896
Antoine Pitrou20e1f932009-08-06 20:18:29 +00001897 /* Adjust the raw stream position if it is away from the logical stream
1898 position. This happens if the read buffer has been filled but not
1899 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1900 the raw stream by itself).
1901 Fixes issue #6629.
1902 */
Amaury Forgeot d'Arc3de46472009-10-05 20:18:05 +00001903 offset = RAW_OFFSET(self);
1904 if (offset != 0) {
1905 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitrou20e1f932009-08-06 20:18:29 +00001906 goto error;
Amaury Forgeot d'Arc3de46472009-10-05 20:18:05 +00001907 self->raw_pos -= offset;
Antoine Pitrou20e1f932009-08-06 20:18:29 +00001908 }
1909
Antoine Pitrou19690592009-06-12 20:14:08 +00001910 /* Then write buf itself. At this point the buffer has been emptied. */
1911 remaining = buf.len;
1912 written = 0;
1913 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arc3de46472009-10-05 20:18:05 +00001914 Py_ssize_t n = _bufferedwriter_raw_write(
Antoine Pitrou19690592009-06-12 20:14:08 +00001915 self, (char *) buf.buf + written, buf.len - written);
1916 if (n == -1) {
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001917 goto error;
1918 } else if (n == -2) {
1919 /* Write failed because raw file is non-blocking */
Antoine Pitrou19690592009-06-12 20:14:08 +00001920 if (remaining > self->buffer_size) {
1921 /* Can't buffer everything, still buffer as much as possible */
1922 memcpy(self->buffer,
1923 (char *) buf.buf + written, self->buffer_size);
1924 self->raw_pos = 0;
1925 ADJUST_POSITION(self, self->buffer_size);
1926 self->write_end = self->buffer_size;
Antoine Pitrou5aa7df32011-11-21 20:16:44 +01001927 written += self->buffer_size;
1928 _set_BlockingIOError("write could not complete without "
1929 "blocking", written);
Antoine Pitrou19690592009-06-12 20:14:08 +00001930 goto error;
1931 }
1932 PyErr_Clear();
1933 break;
1934 }
1935 written += n;
1936 remaining -= n;
Antoine Pitrou3ebaed62010-08-21 19:17:25 +00001937 /* Partial writes can return successfully when interrupted by a
1938 signal (see write(2)). We must run signal handlers before
1939 blocking another time, possibly indefinitely. */
1940 if (PyErr_CheckSignals() < 0)
1941 goto error;
Antoine Pitrou19690592009-06-12 20:14:08 +00001942 }
1943 if (self->readable)
1944 _bufferedreader_reset_buf(self);
1945 if (remaining > 0) {
1946 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1947 written += remaining;
1948 }
1949 self->write_pos = 0;
1950 /* TODO: sanity check (remaining >= 0) */
1951 self->write_end = remaining;
1952 ADJUST_POSITION(self, remaining);
1953 self->raw_pos = 0;
1954
1955end:
1956 res = PyLong_FromSsize_t(written);
1957
1958error:
1959 LEAVE_BUFFERED(self)
1960 PyBuffer_Release(&buf);
1961 return res;
1962}
1963
1964static PyMethodDef bufferedwriter_methods[] = {
1965 /* BufferedIOMixin methods */
1966 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1967 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1968 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1969 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1970 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1971 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1972 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
1973
1974 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
1975 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1976 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
1977 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1978 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitroubff5df02012-07-29 19:02:46 +02001979 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Antoine Pitrou19690592009-06-12 20:14:08 +00001980 {NULL, NULL}
1981};
1982
1983static PyMemberDef bufferedwriter_members[] = {
Antoine Pitroufc9ead62010-12-21 21:26:55 +00001984 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou19690592009-06-12 20:14:08 +00001985 {NULL}
1986};
1987
1988static PyGetSetDef bufferedwriter_getset[] = {
1989 {"closed", (getter)buffered_closed_get, NULL, NULL},
1990 {"name", (getter)buffered_name_get, NULL, NULL},
1991 {"mode", (getter)buffered_mode_get, NULL, NULL},
1992 {NULL}
1993};
1994
1995
1996PyTypeObject PyBufferedWriter_Type = {
1997 PyVarObject_HEAD_INIT(NULL, 0)
1998 "_io.BufferedWriter", /*tp_name*/
1999 sizeof(buffered), /*tp_basicsize*/
2000 0, /*tp_itemsize*/
2001 (destructor)buffered_dealloc, /*tp_dealloc*/
2002 0, /*tp_print*/
2003 0, /*tp_getattr*/
2004 0, /*tp_setattr*/
2005 0, /*tp_compare */
2006 (reprfunc)buffered_repr, /*tp_repr*/
2007 0, /*tp_as_number*/
2008 0, /*tp_as_sequence*/
2009 0, /*tp_as_mapping*/
2010 0, /*tp_hash */
2011 0, /*tp_call*/
2012 0, /*tp_str*/
2013 0, /*tp_getattro*/
2014 0, /*tp_setattro*/
2015 0, /*tp_as_buffer*/
2016 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2017 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2018 bufferedwriter_doc, /* tp_doc */
2019 (traverseproc)buffered_traverse, /* tp_traverse */
2020 (inquiry)buffered_clear, /* tp_clear */
2021 0, /* tp_richcompare */
2022 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2023 0, /* tp_iter */
2024 0, /* tp_iternext */
2025 bufferedwriter_methods, /* tp_methods */
2026 bufferedwriter_members, /* tp_members */
2027 bufferedwriter_getset, /* tp_getset */
2028 0, /* tp_base */
2029 0, /* tp_dict */
2030 0, /* tp_descr_get */
2031 0, /* tp_descr_set */
2032 offsetof(buffered, dict), /* tp_dictoffset */
2033 (initproc)bufferedwriter_init, /* tp_init */
2034 0, /* tp_alloc */
2035 PyType_GenericNew, /* tp_new */
2036};
2037
2038
2039
2040/*
2041 * BufferedRWPair
2042 */
2043
2044PyDoc_STRVAR(bufferedrwpair_doc,
2045 "A buffered reader and writer object together.\n"
2046 "\n"
2047 "A buffered reader object and buffered writer object put together to\n"
2048 "form a sequential IO object that can read and write. This is typically\n"
2049 "used with a socket or two-way pipe.\n"
2050 "\n"
2051 "reader and writer are RawIOBase objects that are readable and\n"
2052 "writeable respectively. If the buffer_size is omitted it defaults to\n"
2053 "DEFAULT_BUFFER_SIZE.\n"
2054 );
2055
2056/* XXX The usefulness of this (compared to having two separate IO objects) is
2057 * questionable.
2058 */
2059
2060typedef struct {
2061 PyObject_HEAD
2062 buffered *reader;
2063 buffered *writer;
2064 PyObject *dict;
2065 PyObject *weakreflist;
2066} rwpair;
2067
2068static int
2069bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
2070{
2071 PyObject *reader, *writer;
2072 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
2073 Py_ssize_t max_buffer_size = -234;
2074
2075 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2076 &buffer_size, &max_buffer_size)) {
2077 return -1;
2078 }
2079
2080 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2081 return -1;
2082
2083 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
2084 return -1;
2085 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
2086 return -1;
2087
2088 self->reader = (buffered *) PyObject_CallFunction(
2089 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
2090 if (self->reader == NULL)
2091 return -1;
2092
2093 self->writer = (buffered *) PyObject_CallFunction(
2094 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
2095 if (self->writer == NULL) {
2096 Py_CLEAR(self->reader);
2097 return -1;
2098 }
2099
2100 return 0;
2101}
2102
2103static int
2104bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
2105{
2106 Py_VISIT(self->dict);
2107 return 0;
2108}
2109
2110static int
2111bufferedrwpair_clear(rwpair *self)
2112{
2113 Py_CLEAR(self->reader);
2114 Py_CLEAR(self->writer);
2115 Py_CLEAR(self->dict);
2116 return 0;
2117}
2118
2119static void
2120bufferedrwpair_dealloc(rwpair *self)
2121{
2122 _PyObject_GC_UNTRACK(self);
Benjamin Peterson1c873bf2014-09-29 22:46:57 -04002123 if (self->weakreflist != NULL)
2124 PyObject_ClearWeakRefs((PyObject *)self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002125 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{
Serhiy Storchaka1d19f972014-02-12 10:52:07 +02002134 PyObject *func, *ret;
2135 if (self == NULL) {
2136 PyErr_SetString(PyExc_ValueError,
2137 "I/O operation on uninitialized object");
2138 return NULL;
2139 }
Antoine Pitrou19690592009-06-12 20:14:08 +00002140
Serhiy Storchaka1d19f972014-02-12 10:52:07 +02002141 func = PyObject_GetAttrString((PyObject *)self, name);
Antoine Pitrou19690592009-06-12 20:14:08 +00002142 if (func == NULL) {
2143 PyErr_SetString(PyExc_AttributeError, name);
2144 return NULL;
2145 }
2146
2147 ret = PyObject_CallObject(func, args);
2148 Py_DECREF(func);
2149 return ret;
2150}
2151
2152static PyObject *
2153bufferedrwpair_read(rwpair *self, PyObject *args)
2154{
2155 return _forward_call(self->reader, "read", args);
2156}
2157
2158static PyObject *
2159bufferedrwpair_peek(rwpair *self, PyObject *args)
2160{
2161 return _forward_call(self->reader, "peek", args);
2162}
2163
2164static PyObject *
2165bufferedrwpair_read1(rwpair *self, PyObject *args)
2166{
2167 return _forward_call(self->reader, "read1", args);
2168}
2169
2170static PyObject *
2171bufferedrwpair_readinto(rwpair *self, PyObject *args)
2172{
2173 return _forward_call(self->reader, "readinto", args);
2174}
2175
2176static PyObject *
2177bufferedrwpair_write(rwpair *self, PyObject *args)
2178{
2179 return _forward_call(self->writer, "write", args);
2180}
2181
2182static PyObject *
2183bufferedrwpair_flush(rwpair *self, PyObject *args)
2184{
2185 return _forward_call(self->writer, "flush", args);
2186}
2187
2188static PyObject *
2189bufferedrwpair_readable(rwpair *self, PyObject *args)
2190{
2191 return _forward_call(self->reader, "readable", args);
2192}
2193
2194static PyObject *
2195bufferedrwpair_writable(rwpair *self, PyObject *args)
2196{
2197 return _forward_call(self->writer, "writable", args);
2198}
2199
2200static PyObject *
2201bufferedrwpair_close(rwpair *self, PyObject *args)
2202{
2203 PyObject *ret = _forward_call(self->writer, "close", args);
2204 if (ret == NULL)
2205 return NULL;
2206 Py_DECREF(ret);
2207
2208 return _forward_call(self->reader, "close", args);
2209}
2210
2211static PyObject *
2212bufferedrwpair_isatty(rwpair *self, PyObject *args)
2213{
2214 PyObject *ret = _forward_call(self->writer, "isatty", args);
2215
2216 if (ret != Py_False) {
2217 /* either True or exception */
2218 return ret;
2219 }
2220 Py_DECREF(ret);
2221
2222 return _forward_call(self->reader, "isatty", args);
2223}
2224
2225static PyObject *
2226bufferedrwpair_closed_get(rwpair *self, void *context)
2227{
Charles-François Natali9ffcbf72011-10-06 19:09:45 +02002228 if (self->writer == NULL) {
2229 PyErr_SetString(PyExc_RuntimeError,
2230 "the BufferedRWPair object is being garbage-collected");
2231 return NULL;
2232 }
Antoine Pitrou19690592009-06-12 20:14:08 +00002233 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2234}
2235
2236static PyMethodDef bufferedrwpair_methods[] = {
2237 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2238 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2239 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2240 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
2241
2242 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2243 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
2244
2245 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2246 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
2247
2248 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2249 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
2250
2251 {NULL, NULL}
2252};
2253
2254static PyGetSetDef bufferedrwpair_getset[] = {
2255 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
2256 {NULL}
2257};
2258
2259PyTypeObject PyBufferedRWPair_Type = {
2260 PyVarObject_HEAD_INIT(NULL, 0)
2261 "_io.BufferedRWPair", /*tp_name*/
2262 sizeof(rwpair), /*tp_basicsize*/
2263 0, /*tp_itemsize*/
2264 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
2265 0, /*tp_print*/
2266 0, /*tp_getattr*/
2267 0, /*tp_setattr*/
2268 0, /*tp_compare */
2269 0, /*tp_repr*/
2270 0, /*tp_as_number*/
2271 0, /*tp_as_sequence*/
2272 0, /*tp_as_mapping*/
2273 0, /*tp_hash */
2274 0, /*tp_call*/
2275 0, /*tp_str*/
2276 0, /*tp_getattro*/
2277 0, /*tp_setattro*/
2278 0, /*tp_as_buffer*/
2279 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2280 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2281 bufferedrwpair_doc, /* tp_doc */
2282 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2283 (inquiry)bufferedrwpair_clear, /* tp_clear */
2284 0, /* tp_richcompare */
2285 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
2286 0, /* tp_iter */
2287 0, /* tp_iternext */
2288 bufferedrwpair_methods, /* tp_methods */
2289 0, /* tp_members */
2290 bufferedrwpair_getset, /* tp_getset */
2291 0, /* tp_base */
2292 0, /* tp_dict */
2293 0, /* tp_descr_get */
2294 0, /* tp_descr_set */
2295 offsetof(rwpair, dict), /* tp_dictoffset */
2296 (initproc)bufferedrwpair_init, /* tp_init */
2297 0, /* tp_alloc */
2298 PyType_GenericNew, /* tp_new */
2299};
2300
2301
2302
2303/*
2304 * BufferedRandom
2305 */
2306
2307PyDoc_STRVAR(bufferedrandom_doc,
2308 "A buffered interface to random access streams.\n"
2309 "\n"
2310 "The constructor creates a reader and writer for a seekable stream,\n"
2311 "raw, given in the first argument. If the buffer_size is omitted it\n"
2312 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2313 );
2314
2315static int
2316bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
2317{
2318 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2319 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
2320 Py_ssize_t max_buffer_size = -234;
2321 PyObject *raw;
2322
2323 self->ok = 0;
2324 self->detached = 0;
2325
R David Murray5b2cf5e2013-02-23 22:11:21 -05002326 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedRandom", kwlist,
Antoine Pitrou19690592009-06-12 20:14:08 +00002327 &raw, &buffer_size, &max_buffer_size)) {
2328 return -1;
2329 }
2330
2331 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2332 return -1;
2333
2334 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2335 return -1;
2336 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2337 return -1;
2338 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2339 return -1;
2340
2341 Py_CLEAR(self->raw);
2342 Py_INCREF(raw);
2343 self->raw = raw;
2344 self->buffer_size = buffer_size;
2345 self->readable = 1;
2346 self->writable = 1;
2347
2348 if (_buffered_init(self) < 0)
2349 return -1;
2350 _bufferedreader_reset_buf(self);
2351 _bufferedwriter_reset_buf(self);
2352 self->pos = 0;
2353
2354 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2355 Py_TYPE(raw) == &PyFileIO_Type);
2356
2357 self->ok = 1;
2358 return 0;
2359}
2360
2361static PyMethodDef bufferedrandom_methods[] = {
2362 /* BufferedIOMixin methods */
2363 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2364 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2365 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2366 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2367 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2368 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2369 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2370
2371 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2372
2373 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2374 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2375 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2376 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2377 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2378 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2379 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2380 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2381 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitroubff5df02012-07-29 19:02:46 +02002382 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Antoine Pitrou19690592009-06-12 20:14:08 +00002383 {NULL, NULL}
2384};
2385
2386static PyMemberDef bufferedrandom_members[] = {
Antoine Pitroufc9ead62010-12-21 21:26:55 +00002387 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou19690592009-06-12 20:14:08 +00002388 {NULL}
2389};
2390
2391static PyGetSetDef bufferedrandom_getset[] = {
2392 {"closed", (getter)buffered_closed_get, NULL, NULL},
2393 {"name", (getter)buffered_name_get, NULL, NULL},
2394 {"mode", (getter)buffered_mode_get, NULL, NULL},
2395 {NULL}
2396};
2397
2398
2399PyTypeObject PyBufferedRandom_Type = {
2400 PyVarObject_HEAD_INIT(NULL, 0)
2401 "_io.BufferedRandom", /*tp_name*/
2402 sizeof(buffered), /*tp_basicsize*/
2403 0, /*tp_itemsize*/
2404 (destructor)buffered_dealloc, /*tp_dealloc*/
2405 0, /*tp_print*/
2406 0, /*tp_getattr*/
2407 0, /*tp_setattr*/
2408 0, /*tp_compare */
2409 (reprfunc)buffered_repr, /*tp_repr*/
2410 0, /*tp_as_number*/
2411 0, /*tp_as_sequence*/
2412 0, /*tp_as_mapping*/
2413 0, /*tp_hash */
2414 0, /*tp_call*/
2415 0, /*tp_str*/
2416 0, /*tp_getattro*/
2417 0, /*tp_setattro*/
2418 0, /*tp_as_buffer*/
2419 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2420 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2421 bufferedrandom_doc, /* tp_doc */
2422 (traverseproc)buffered_traverse, /* tp_traverse */
2423 (inquiry)buffered_clear, /* tp_clear */
2424 0, /* tp_richcompare */
2425 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2426 0, /* tp_iter */
2427 (iternextfunc)buffered_iternext, /* tp_iternext */
2428 bufferedrandom_methods, /* tp_methods */
2429 bufferedrandom_members, /* tp_members */
2430 bufferedrandom_getset, /* tp_getset */
2431 0, /* tp_base */
2432 0, /*tp_dict*/
2433 0, /* tp_descr_get */
2434 0, /* tp_descr_set */
2435 offsetof(buffered, dict), /*tp_dictoffset*/
2436 (initproc)bufferedrandom_init, /* tp_init */
2437 0, /* tp_alloc */
2438 PyType_GenericNew, /* tp_new */
2439};
2440