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