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