blob: 6a885cf4bfb06e13fefbbfd67b78128b354cf44c [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 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
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020016_Py_IDENTIFIER(close);
17_Py_IDENTIFIER(_dealloc_warn);
18_Py_IDENTIFIER(flush);
19_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020020_Py_IDENTIFIER(mode);
21_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020022_Py_IDENTIFIER(peek);
23_Py_IDENTIFIER(read);
24_Py_IDENTIFIER(read1);
25_Py_IDENTIFIER(readable);
26_Py_IDENTIFIER(readinto);
27_Py_IDENTIFIER(writable);
28_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020029
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000030/*
31 * BufferedIOBase class, inherits from IOBase.
32 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000033PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034 "Base class for buffered IO objects.\n"
35 "\n"
36 "The main difference with RawIOBase is that the read() method\n"
37 "supports omitting the size argument, and does not have a default\n"
38 "implementation that defers to readinto().\n"
39 "\n"
40 "In addition, read(), readinto() and write() may raise\n"
41 "BlockingIOError if the underlying raw stream is in non-blocking\n"
42 "mode and not ready; unlike their raw counterparts, they will never\n"
43 "return None.\n"
44 "\n"
45 "A typical implementation should not inherit from a RawIOBase\n"
46 "implementation, but wrap one.\n"
47 );
48
49static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000050bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000051{
52 Py_buffer buf;
53 Py_ssize_t len;
54 PyObject *data;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020055 _Py_IDENTIFIER(read);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000056
57 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
58 return NULL;
59 }
60
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020061 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000062 if (data == NULL)
63 goto error;
64
65 if (!PyBytes_Check(data)) {
66 Py_DECREF(data);
67 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
68 goto error;
69 }
70
71 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030072 if (len > buf.len) {
73 PyErr_Format(PyExc_ValueError,
74 "read() returned too much data: "
75 "%zd bytes requested, %zd returned",
76 buf.len, len);
77 Py_DECREF(data);
78 goto error;
79 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
81
82 PyBuffer_Release(&buf);
83 Py_DECREF(data);
84
85 return PyLong_FromSsize_t(len);
86
87 error:
88 PyBuffer_Release(&buf);
89 return NULL;
90}
91
92static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000093bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094{
95 PyErr_SetString(IO_STATE->unsupported_operation, message);
96 return NULL;
97}
98
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000100 "Disconnect this buffer from its underlying raw stream and return it.\n"
101 "\n"
102 "After the raw stream has been detached, the buffer is in an unusable\n"
103 "state.\n");
104
105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000106bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000107{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000109}
110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000111PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000112 "Read and return up to n bytes.\n"
113 "\n"
114 "If the argument is omitted, None, or negative, reads and\n"
115 "returns all data until EOF.\n"
116 "\n"
117 "If the argument is positive, and the underlying raw stream is\n"
118 "not 'interactive', multiple raw reads may be issued to satisfy\n"
119 "the byte count (unless EOF is reached first). But for\n"
120 "interactive raw streams (as well as sockets and pipes), at most\n"
121 "one raw read will be issued, and a short result does not imply\n"
122 "that EOF is imminent.\n"
123 "\n"
124 "Returns an empty bytes object on EOF.\n"
125 "\n"
126 "Returns None if the underlying raw stream was open in non-blocking\n"
127 "mode and no data is available at the moment.\n");
128
129static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000130bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000131{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000132 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133}
134
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136 "Read and return up to n bytes, with at most one read() call\n"
137 "to the underlying raw stream. A short result does not imply\n"
138 "that EOF is imminent.\n"
139 "\n"
140 "Returns an empty bytes object on EOF.\n");
141
142static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000144{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000145 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000146}
147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149 "Write the given buffer to the IO stream.\n"
150 "\n"
151 "Returns the number of bytes written, which is never less than\n"
152 "len(b).\n"
153 "\n"
154 "Raises BlockingIOError if the buffer is full and the\n"
155 "underlying raw stream cannot accept more data at the moment.\n");
156
157static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000159{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000160 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000161}
162
163
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000164static PyMethodDef bufferediobase_methods[] = {
165 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
166 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
167 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
168 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
169 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000170 {NULL, NULL}
171};
172
173PyTypeObject PyBufferedIOBase_Type = {
174 PyVarObject_HEAD_INIT(NULL, 0)
175 "_io._BufferedIOBase", /*tp_name*/
176 0, /*tp_basicsize*/
177 0, /*tp_itemsize*/
178 0, /*tp_dealloc*/
179 0, /*tp_print*/
180 0, /*tp_getattr*/
181 0, /*tp_setattr*/
182 0, /*tp_compare */
183 0, /*tp_repr*/
184 0, /*tp_as_number*/
185 0, /*tp_as_sequence*/
186 0, /*tp_as_mapping*/
187 0, /*tp_hash */
188 0, /*tp_call*/
189 0, /*tp_str*/
190 0, /*tp_getattro*/
191 0, /*tp_setattro*/
192 0, /*tp_as_buffer*/
193 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 0, /* tp_traverse */
196 0, /* tp_clear */
197 0, /* tp_richcompare */
198 0, /* tp_weaklistoffset */
199 0, /* tp_iter */
200 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000201 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000202 0, /* tp_members */
203 0, /* tp_getset */
204 &PyIOBase_Type, /* tp_base */
205 0, /* tp_dict */
206 0, /* tp_descr_get */
207 0, /* tp_descr_set */
208 0, /* tp_dictoffset */
209 0, /* tp_init */
210 0, /* tp_alloc */
211 0, /* tp_new */
212};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000213
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000214
215typedef struct {
216 PyObject_HEAD
217
218 PyObject *raw;
219 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000220 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000221 int readable;
222 int writable;
Antoine Pitroue033e062010-10-29 10:38:18 +0000223 int deallocating;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200224
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000225 /* True if this is a vanilla Buffered object (rather than a user derived
226 class) *and* the raw stream is a vanilla FileIO object. */
227 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000228
229 /* Absolute position inside the raw stream (-1 if unknown). */
230 Py_off_t abs_pos;
231
232 /* A static buffer of size `buffer_size` */
233 char *buffer;
234 /* Current logical position in the buffer. */
235 Py_off_t pos;
236 /* Position of the raw stream in the buffer. */
237 Py_off_t raw_pos;
238
239 /* Just after the last buffered byte in the buffer, or -1 if the buffer
240 isn't ready for reading. */
241 Py_off_t read_end;
242
243 /* Just after the last byte actually written */
244 Py_off_t write_pos;
245 /* Just after the last byte waiting to be written, or -1 if the buffer
246 isn't ready for writing. */
247 Py_off_t write_end;
248
Georg Brandldfd73442009-04-05 11:47:34 +0000249#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000251 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000252#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000253
254 Py_ssize_t buffer_size;
255 Py_ssize_t buffer_mask;
256
257 PyObject *dict;
258 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000259} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260
261/*
262 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200263
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264 * BufferedReader, BufferedWriter and BufferedRandom try to share most
265 methods (this is helped by the members `readable` and `writable`, which
266 are initialized in the respective constructors)
267 * They also share a single buffer for reading and writing. This enables
268 interleaved reads and writes without flushing. It also makes the logic
269 a bit trickier to get right.
270 * The absolute position of the raw stream is cached, if possible, in the
271 `abs_pos` member. It must be updated every time an operation is done
272 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000273 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000274 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000275 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
276 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000277
278 NOTE: we should try to maintain block alignment of reads and writes to the
279 raw stream (according to the buffer size), but for now it is only done
280 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200281
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000282*/
283
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000284/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000285
Georg Brandldfd73442009-04-05 11:47:34 +0000286#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000287
288static int
289_enter_buffered_busy(buffered *self)
290{
291 if (self->owner == PyThread_get_thread_ident()) {
292 PyErr_Format(PyExc_RuntimeError,
293 "reentrant call inside %R", self);
294 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000295 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000296 Py_BEGIN_ALLOW_THREADS
297 PyThread_acquire_lock(self->lock, 1);
298 Py_END_ALLOW_THREADS
299 return 1;
300}
301
302#define ENTER_BUFFERED(self) \
303 ( (PyThread_acquire_lock(self->lock, 0) ? \
304 1 : _enter_buffered_busy(self)) \
305 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000306
307#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000308 do { \
309 self->owner = 0; \
310 PyThread_release_lock(self->lock); \
311 } while(0);
312
Georg Brandldfd73442009-04-05 11:47:34 +0000313#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000314#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000315#define LEAVE_BUFFERED(self)
316#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000317
318#define CHECK_INITIALIZED(self) \
319 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000320 if (self->detached) { \
321 PyErr_SetString(PyExc_ValueError, \
322 "raw stream has been detached"); \
323 } else { \
324 PyErr_SetString(PyExc_ValueError, \
325 "I/O operation on uninitialized object"); \
326 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000327 return NULL; \
328 }
329
330#define CHECK_INITIALIZED_INT(self) \
331 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000332 if (self->detached) { \
333 PyErr_SetString(PyExc_ValueError, \
334 "raw stream has been detached"); \
335 } else { \
336 PyErr_SetString(PyExc_ValueError, \
337 "I/O operation on uninitialized object"); \
338 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 return -1; \
340 }
341
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000342#define IS_CLOSED(self) \
343 (self->fast_closed_checks \
344 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000345 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000346
347#define CHECK_CLOSED(self, error_msg) \
348 if (IS_CLOSED(self)) { \
349 PyErr_SetString(PyExc_ValueError, error_msg); \
350 return NULL; \
351 }
352
353
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354#define VALID_READ_BUFFER(self) \
355 (self->readable && self->read_end != -1)
356
357#define VALID_WRITE_BUFFER(self) \
358 (self->writable && self->write_end != -1)
359
360#define ADJUST_POSITION(self, _new_pos) \
361 do { \
362 self->pos = _new_pos; \
363 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
364 self->read_end = self->pos; \
365 } while(0)
366
367#define READAHEAD(self) \
368 ((self->readable && VALID_READ_BUFFER(self)) \
369 ? (self->read_end - self->pos) : 0)
370
371#define RAW_OFFSET(self) \
372 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
373 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
374
375#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000376 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000377
378#define MINUS_LAST_BLOCK(self, size) \
379 (self->buffer_mask ? \
380 (size & ~self->buffer_mask) : \
381 (self->buffer_size * (size / self->buffer_size)))
382
383
384static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000385buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000386{
Antoine Pitroue033e062010-10-29 10:38:18 +0000387 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
389 return;
390 _PyObject_GC_UNTRACK(self);
391 self->ok = 0;
392 if (self->weakreflist != NULL)
393 PyObject_ClearWeakRefs((PyObject *)self);
394 Py_CLEAR(self->raw);
395 if (self->buffer) {
396 PyMem_Free(self->buffer);
397 self->buffer = NULL;
398 }
Georg Brandldfd73442009-04-05 11:47:34 +0000399#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000400 if (self->lock) {
401 PyThread_free_lock(self->lock);
402 self->lock = NULL;
403 }
Georg Brandldfd73442009-04-05 11:47:34 +0000404#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000405 Py_CLEAR(self->dict);
406 Py_TYPE(self)->tp_free((PyObject *)self);
407}
408
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200409static PyObject *
410buffered_sizeof(buffered *self, void *unused)
411{
412 Py_ssize_t res;
413
414 res = sizeof(buffered);
415 if (self->buffer)
416 res += self->buffer_size;
417 return PyLong_FromSsize_t(res);
418}
419
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000420static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000421buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422{
423 Py_VISIT(self->raw);
424 Py_VISIT(self->dict);
425 return 0;
426}
427
428static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000429buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000430{
431 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
432 return -1;
433 self->ok = 0;
434 Py_CLEAR(self->raw);
435 Py_CLEAR(self->dict);
436 return 0;
437}
438
Antoine Pitroue033e062010-10-29 10:38:18 +0000439/* Because this can call arbitrary code, it shouldn't be called when
440 the refcount is 0 (that is, not directly from tp_dealloc unless
441 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000442static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000443buffered_dealloc_warn(buffered *self, PyObject *source)
444{
445 if (self->ok && self->raw) {
446 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200447 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000448 if (r)
449 Py_DECREF(r);
450 else
451 PyErr_Clear();
452 }
453 Py_RETURN_NONE;
454}
455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456/*
457 * _BufferedIOMixin methods
458 * This is not a class, just a collection of methods that will be reused
459 * by BufferedReader and BufferedWriter
460 */
461
462/* Flush and close */
463
464static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000465buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466{
467 CHECK_INITIALIZED(self)
468 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
469}
470
471static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000472buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000473{
474 int closed;
475 PyObject *res;
476 CHECK_INITIALIZED_INT(self)
477 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
478 if (res == NULL)
479 return -1;
480 closed = PyObject_IsTrue(res);
481 Py_DECREF(res);
482 return closed;
483}
484
485static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000486buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487{
488 CHECK_INITIALIZED(self)
489 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
490}
491
492static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000493buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000494{
Benjamin Peterson68623612012-12-20 11:53:11 -0600495 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 int r;
497
498 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000499 if (!ENTER_BUFFERED(self))
500 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503 if (r < 0)
504 goto end;
505 if (r > 0) {
506 res = Py_None;
507 Py_INCREF(res);
508 goto end;
509 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000510
511 if (self->deallocating) {
512 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
513 if (r)
514 Py_DECREF(r);
515 else
516 PyErr_Clear();
517 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000518 /* flush() will most probably re-take the lock, so drop it first */
519 LEAVE_BUFFERED(self)
520 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000521 if (!ENTER_BUFFERED(self))
522 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600523 if (res == NULL)
524 PyErr_Fetch(&exc, &val, &tb);
525 else
526 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000527
528 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
529
Jesus Ceadc469452012-10-04 12:37:56 +0200530 if (self->buffer) {
531 PyMem_Free(self->buffer);
532 self->buffer = NULL;
533 }
534
Benjamin Peterson68623612012-12-20 11:53:11 -0600535 if (exc != NULL) {
536 if (res != NULL) {
537 Py_CLEAR(res);
538 PyErr_Restore(exc, val, tb);
539 }
540 else {
541 PyObject *val2;
542 Py_DECREF(exc);
543 Py_XDECREF(tb);
544 PyErr_Fetch(&exc, &val2, &tb);
545 PyErr_NormalizeException(&exc, &val2, &tb);
546 PyException_SetContext(val2, val);
547 PyErr_Restore(exc, val2, tb);
548 }
549 }
550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551end:
552 LEAVE_BUFFERED(self)
553 return res;
554}
555
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000556/* detach */
557
558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000560{
561 PyObject *raw, *res;
562 CHECK_INITIALIZED(self)
563 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
564 if (res == NULL)
565 return NULL;
566 Py_DECREF(res);
567 raw = self->raw;
568 self->raw = NULL;
569 self->detached = 1;
570 self->ok = 0;
571 return raw;
572}
573
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574/* Inquiries */
575
576static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000577buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578{
579 CHECK_INITIALIZED(self)
580 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
581}
582
583static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 CHECK_INITIALIZED(self)
587 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
588}
589
590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000591buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
594 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
595}
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200601 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200608 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609}
610
611/* Lower-level APIs */
612
613static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615{
616 CHECK_INITIALIZED(self)
617 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
618}
619
620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000621buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622{
623 CHECK_INITIALIZED(self)
624 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
625}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626
Antoine Pitrou243757e2010-11-05 21:15:39 +0000627/* Serialization */
628
629static PyObject *
630buffered_getstate(buffered *self, PyObject *args)
631{
632 PyErr_Format(PyExc_TypeError,
633 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
634 return NULL;
635}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000636
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637/* Forward decls */
638static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100639_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000645_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200647_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000650static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000652static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200654static Py_ssize_t
655_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
657/*
658 * Helpers
659 */
660
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100661/* Sets the current error to BlockingIOError */
662static void
663_set_BlockingIOError(char *msg, Py_ssize_t written)
664{
665 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200666#ifdef Py_DEBUG
667 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
668 if an exception is set when it is called */
669 PyErr_Clear();
670#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100671 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
672 errno, msg, written);
673 if (err)
674 PyErr_SetObject(PyExc_BlockingIOError, err);
675 Py_XDECREF(err);
676}
677
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678/* Returns the address of the `written` member if a BlockingIOError was
679 raised, NULL otherwise. The error is always re-raised. */
680static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000681_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682{
683 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200684 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000685
686 PyErr_Fetch(&t, &v, &tb);
687 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
688 PyErr_Restore(t, v, tb);
689 return NULL;
690 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200691 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 /* TODO: sanity check (err->written >= 0) */
693 PyErr_Restore(t, v, tb);
694 return &err->written;
695}
696
697static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000698_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000699{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000701 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
703 if (res == NULL)
704 return -1;
705 n = PyNumber_AsOff_t(res, PyExc_ValueError);
706 Py_DECREF(res);
707 if (n < 0) {
708 if (!PyErr_Occurred())
709 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000710 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200711 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712 return -1;
713 }
714 self->abs_pos = n;
715 return n;
716}
717
718static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000719_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000720{
721 PyObject *res, *posobj, *whenceobj;
722 Py_off_t n;
723
724 posobj = PyLong_FromOff_t(target);
725 if (posobj == NULL)
726 return -1;
727 whenceobj = PyLong_FromLong(whence);
728 if (whenceobj == NULL) {
729 Py_DECREF(posobj);
730 return -1;
731 }
732 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
733 posobj, whenceobj, NULL);
734 Py_DECREF(posobj);
735 Py_DECREF(whenceobj);
736 if (res == NULL)
737 return -1;
738 n = PyNumber_AsOff_t(res, PyExc_ValueError);
739 Py_DECREF(res);
740 if (n < 0) {
741 if (!PyErr_Occurred())
742 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000743 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200744 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000745 return -1;
746 }
747 self->abs_pos = n;
748 return n;
749}
750
751static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000752_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000753{
754 Py_ssize_t n;
755 if (self->buffer_size <= 0) {
756 PyErr_SetString(PyExc_ValueError,
757 "buffer size must be strictly positive");
758 return -1;
759 }
760 if (self->buffer)
761 PyMem_Free(self->buffer);
762 self->buffer = PyMem_Malloc(self->buffer_size);
763 if (self->buffer == NULL) {
764 PyErr_NoMemory();
765 return -1;
766 }
Georg Brandldfd73442009-04-05 11:47:34 +0000767#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000768 if (self->lock)
769 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000770 self->lock = PyThread_allocate_lock();
771 if (self->lock == NULL) {
772 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
773 return -1;
774 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000775 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000776#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000777 /* Find out whether buffer_size is a power of 2 */
778 /* XXX is this optimization useful? */
779 for (n = self->buffer_size - 1; n & 1; n >>= 1)
780 ;
781 if (n == 0)
782 self->buffer_mask = self->buffer_size - 1;
783 else
784 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000785 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000786 PyErr_Clear();
787 return 0;
788}
789
Antoine Pitrou707ce822011-02-25 21:24:11 +0000790/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
791 clears the error indicator), 0 otherwise.
792 Should only be called when PyErr_Occurred() is true.
793*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700794int
795_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000796{
797 static PyObject *eintr_int = NULL;
798 PyObject *typ, *val, *tb;
799 PyEnvironmentErrorObject *env_err;
800
801 if (eintr_int == NULL) {
802 eintr_int = PyLong_FromLong(EINTR);
803 assert(eintr_int != NULL);
804 }
805 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
806 return 0;
807 PyErr_Fetch(&typ, &val, &tb);
808 PyErr_NormalizeException(&typ, &val, &tb);
809 env_err = (PyEnvironmentErrorObject *) val;
810 assert(env_err != NULL);
811 if (env_err->myerrno != NULL &&
812 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
813 Py_DECREF(typ);
814 Py_DECREF(val);
815 Py_XDECREF(tb);
816 return 1;
817 }
818 /* This silences any error set by PyObject_RichCompareBool() */
819 PyErr_Restore(typ, val, tb);
820 return 0;
821}
822
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000823/*
824 * Shared methods and wrappers
825 */
826
827static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200828buffered_flush_and_rewind_unlocked(buffered *self)
829{
830 PyObject *res;
831
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100832 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200833 if (res == NULL)
834 return NULL;
835 Py_DECREF(res);
836
837 if (self->readable) {
838 /* Rewind the raw stream so that its position corresponds to
839 the current logical position. */
840 Py_off_t n;
841 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
842 _bufferedreader_reset_buf(self);
843 if (n == -1)
844 return NULL;
845 }
846 Py_RETURN_NONE;
847}
848
849static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000850buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851{
852 PyObject *res;
853
854 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000855 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000856
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000857 if (!ENTER_BUFFERED(self))
858 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200859 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860 LEAVE_BUFFERED(self)
861
862 return res;
863}
864
865static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000866buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000867{
868 Py_ssize_t n = 0;
869 PyObject *res = NULL;
870
871 CHECK_INITIALIZED(self)
872 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
873 return NULL;
874 }
875
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000876 if (!ENTER_BUFFERED(self))
877 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000878
879 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200880 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881 if (res == NULL)
882 goto end;
883 Py_CLEAR(res);
884 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200885 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886
887end:
888 LEAVE_BUFFERED(self)
889 return res;
890}
891
892static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000893buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000894{
895 Py_ssize_t n = -1;
896 PyObject *res;
897
898 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000899 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000900 return NULL;
901 }
902 if (n < -1) {
903 PyErr_SetString(PyExc_ValueError,
904 "read length must be positive or -1");
905 return NULL;
906 }
907
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000908 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000910 if (n == -1) {
911 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000912 if (!ENTER_BUFFERED(self))
913 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000914 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000915 }
916 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000917 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200918 if (res != Py_None)
919 return res;
920 Py_DECREF(res);
921 if (!ENTER_BUFFERED(self))
922 return NULL;
923 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000924 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000925
Antoine Pitroue05565e2011-08-20 14:39:23 +0200926 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927 return res;
928}
929
930static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000931buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932{
933 Py_ssize_t n, have, r;
934 PyObject *res = NULL;
935
936 CHECK_INITIALIZED(self)
937 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
938 return NULL;
939 }
940
941 if (n < 0) {
942 PyErr_SetString(PyExc_ValueError,
943 "read length must be positive");
944 return NULL;
945 }
946 if (n == 0)
947 return PyBytes_FromStringAndSize(NULL, 0);
948
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000949 /* Return up to n bytes. If at least one byte is buffered, we
950 only return buffered bytes. Otherwise, we do one raw read. */
951
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000952 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
953 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 n = Py_MIN(have, n);
955 res = _bufferedreader_read_fast(self, n);
956 assert(res != Py_None);
957 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100959 res = PyBytes_FromStringAndSize(NULL, n);
960 if (res == NULL)
961 return NULL;
962 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200963 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100964 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200965 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000966 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100967 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
968 LEAVE_BUFFERED(self)
969 if (r == -1) {
970 Py_DECREF(res);
971 return NULL;
972 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000973 if (r == -2)
974 r = 0;
975 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100976 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000977 return res;
978}
979
980static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000981buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983 Py_buffer buf;
984 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985 PyObject *res = NULL;
986
987 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988
989 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
990 return NULL;
991
992 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
993 if (n > 0) {
994 if (n >= buf.len) {
995 memcpy(buf.buf, self->buffer + self->pos, buf.len);
996 self->pos += buf.len;
997 res = PyLong_FromSsize_t(buf.len);
998 goto end_unlocked;
999 }
1000 memcpy(buf.buf, self->buffer + self->pos, n);
1001 self->pos += n;
1002 written = n;
1003 }
1004
1005 if (!ENTER_BUFFERED(self))
1006 goto end_unlocked;
1007
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001008 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001009 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001010 if (res == NULL)
1011 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001012 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001013 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001014
1015 _bufferedreader_reset_buf(self);
1016 self->pos = 0;
1017
1018 for (remaining = buf.len - written;
1019 remaining > 0;
1020 written += n, remaining -= n) {
1021 /* If remaining bytes is larger than internal buffer size, copy
1022 * directly into caller's buffer. */
1023 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001024 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1025 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001026 }
1027 else {
1028 n = _bufferedreader_fill_buffer(self);
1029 if (n > 0) {
1030 if (n > remaining)
1031 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001032 memcpy((char *) buf.buf + written,
1033 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001034 self->pos += n;
1035 continue; /* short circuit */
1036 }
1037 }
1038 if (n == 0 || (n == -2 && written > 0))
1039 break;
1040 if (n < 0) {
1041 if (n == -2) {
1042 Py_INCREF(Py_None);
1043 res = Py_None;
1044 }
1045 goto end;
1046 }
1047 }
1048 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049
1050end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001051 LEAVE_BUFFERED(self);
1052end_unlocked:
1053 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001054 return res;
1055}
1056
1057static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001058_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001059{
1060 PyObject *res = NULL;
1061 PyObject *chunks = NULL;
1062 Py_ssize_t n, written = 0;
1063 const char *start, *s, *end;
1064
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001065 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001066
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001067 /* First, try to find a line in the buffer. This can run unlocked because
1068 the calls to the C API are simple enough that they can't trigger
1069 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1071 if (limit >= 0 && n > limit)
1072 n = limit;
1073 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001074 s = memchr(start, '\n', n);
1075 if (s != NULL) {
1076 res = PyBytes_FromStringAndSize(start, s - start + 1);
1077 if (res != NULL)
1078 self->pos += s - start + 1;
1079 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001080 }
1081 if (n == limit) {
1082 res = PyBytes_FromStringAndSize(start, n);
1083 if (res != NULL)
1084 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001085 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001086 }
1087
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001088 if (!ENTER_BUFFERED(self))
1089 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001090
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001091 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001092 chunks = PyList_New(0);
1093 if (chunks == NULL)
1094 goto end;
1095 if (n > 0) {
1096 res = PyBytes_FromStringAndSize(start, n);
1097 if (res == NULL)
1098 goto end;
1099 if (PyList_Append(chunks, res) < 0) {
1100 Py_CLEAR(res);
1101 goto end;
1102 }
1103 Py_CLEAR(res);
1104 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001105 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106 if (limit >= 0)
1107 limit -= n;
1108 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001109 if (self->writable) {
1110 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1111 if (r == NULL)
1112 goto end;
1113 Py_DECREF(r);
1114 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001115
1116 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001117 _bufferedreader_reset_buf(self);
1118 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 if (n == -1)
1120 goto end;
1121 if (n <= 0)
1122 break;
1123 if (limit >= 0 && n > limit)
1124 n = limit;
1125 start = self->buffer;
1126 end = start + n;
1127 s = start;
1128 while (s < end) {
1129 if (*s++ == '\n') {
1130 res = PyBytes_FromStringAndSize(start, s - start);
1131 if (res == NULL)
1132 goto end;
1133 self->pos = s - start;
1134 goto found;
1135 }
1136 }
1137 res = PyBytes_FromStringAndSize(start, n);
1138 if (res == NULL)
1139 goto end;
1140 if (n == limit) {
1141 self->pos = n;
1142 break;
1143 }
1144 if (PyList_Append(chunks, res) < 0) {
1145 Py_CLEAR(res);
1146 goto end;
1147 }
1148 Py_CLEAR(res);
1149 written += n;
1150 if (limit >= 0)
1151 limit -= n;
1152 }
1153found:
1154 if (res != NULL && PyList_Append(chunks, res) < 0) {
1155 Py_CLEAR(res);
1156 goto end;
1157 }
1158 Py_CLEAR(res);
1159 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1160
1161end:
1162 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001163end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001164 Py_XDECREF(chunks);
1165 return res;
1166}
1167
1168static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001169buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001170{
1171 Py_ssize_t limit = -1;
1172
1173 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001174 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001175 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001176 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177}
1178
1179
1180static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001181buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001182{
1183 Py_off_t pos;
1184
1185 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001186 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001187 if (pos == -1)
1188 return NULL;
1189 pos -= RAW_OFFSET(self);
1190 /* TODO: sanity check (pos >= 0) */
1191 return PyLong_FromOff_t(pos);
1192}
1193
1194static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001195buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001196{
1197 Py_off_t target, n;
1198 int whence = 0;
1199 PyObject *targetobj, *res = NULL;
1200
1201 CHECK_INITIALIZED(self)
1202 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1203 return NULL;
1204 }
Jesus Cea94363612012-06-22 18:32:07 +02001205
1206 /* Do some error checking instead of trusting OS 'seek()'
1207 ** error detection, just in case.
1208 */
1209 if ((whence < 0 || whence >2)
1210#ifdef SEEK_HOLE
1211 && (whence != SEEK_HOLE)
1212#endif
1213#ifdef SEEK_DATA
1214 && (whence != SEEK_DATA)
1215#endif
1216 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001218 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219 return NULL;
1220 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001221
1222 CHECK_CLOSED(self, "seek of closed file")
1223
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001224 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1225 return NULL;
1226
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1228 if (target == -1 && PyErr_Occurred())
1229 return NULL;
1230
Jesus Cea94363612012-06-22 18:32:07 +02001231 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1232 buffer. Other whence values must be managed without this optimization.
1233 Some Operating Systems can provide additional values, like
1234 SEEK_HOLE/SEEK_DATA. */
1235 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 Py_off_t current, avail;
1237 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001238 so as to return quickly if possible. Also, we needn't take the
1239 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001240 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001241 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1242 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 current = RAW_TELL(self);
1244 avail = READAHEAD(self);
1245 if (avail > 0) {
1246 Py_off_t offset;
1247 if (whence == 0)
1248 offset = target - (current - RAW_OFFSET(self));
1249 else
1250 offset = target;
1251 if (offset >= -self->pos && offset <= avail) {
1252 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001253 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 }
1255 }
1256 }
1257
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001258 if (!ENTER_BUFFERED(self))
1259 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001260
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001261 /* Fallback: invoke raw seek() method and clear buffer */
1262 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001263 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 if (res == NULL)
1265 goto end;
1266 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001267 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001268 }
1269
1270 /* TODO: align on block boundary and read buffer if needed? */
1271 if (whence == 1)
1272 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001273 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 if (n == -1)
1275 goto end;
1276 self->raw_pos = -1;
1277 res = PyLong_FromOff_t(n);
1278 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001279 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001280
1281end:
1282 LEAVE_BUFFERED(self)
1283 return res;
1284}
1285
1286static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001287buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288{
1289 PyObject *pos = Py_None;
1290 PyObject *res = NULL;
1291
1292 CHECK_INITIALIZED(self)
1293 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1294 return NULL;
1295 }
1296
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001297 if (!ENTER_BUFFERED(self))
1298 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001299
1300 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001301 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001302 if (res == NULL)
1303 goto end;
1304 Py_CLEAR(res);
1305 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001306 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1307 if (res == NULL)
1308 goto end;
1309 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001310 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311 PyErr_Clear();
1312
1313end:
1314 LEAVE_BUFFERED(self)
1315 return res;
1316}
1317
1318static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001319buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320{
1321 PyObject *line;
1322 PyTypeObject *tp;
1323
1324 CHECK_INITIALIZED(self);
1325
1326 tp = Py_TYPE(self);
1327 if (tp == &PyBufferedReader_Type ||
1328 tp == &PyBufferedRandom_Type) {
1329 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001330 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331 }
1332 else {
1333 line = PyObject_CallMethodObjArgs((PyObject *)self,
1334 _PyIO_str_readline, NULL);
1335 if (line && !PyBytes_Check(line)) {
1336 PyErr_Format(PyExc_IOError,
1337 "readline() should have returned a bytes object, "
1338 "not '%.200s'", Py_TYPE(line)->tp_name);
1339 Py_DECREF(line);
1340 return NULL;
1341 }
1342 }
1343
1344 if (line == NULL)
1345 return NULL;
1346
1347 if (PyBytes_GET_SIZE(line) == 0) {
1348 /* Reached EOF or would have blocked */
1349 Py_DECREF(line);
1350 return NULL;
1351 }
1352
1353 return line;
1354}
1355
Antoine Pitrou716c4442009-05-23 19:04:03 +00001356static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001357buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001358{
1359 PyObject *nameobj, *res;
1360
Martin v. Löwis767046a2011-10-14 15:35:36 +02001361 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001362 if (nameobj == NULL) {
1363 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1364 PyErr_Clear();
1365 else
1366 return NULL;
1367 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1368 }
1369 else {
1370 res = PyUnicode_FromFormat("<%s name=%R>",
1371 Py_TYPE(self)->tp_name, nameobj);
1372 Py_DECREF(nameobj);
1373 }
1374 return res;
1375}
1376
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001377/*
1378 * class BufferedReader
1379 */
1380
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001381PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001382 "Create a new buffered reader using the given readable raw IO object.");
1383
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001384static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001385{
1386 self->read_end = -1;
1387}
1388
1389static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001390bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001391{
1392 char *kwlist[] = {"raw", "buffer_size", NULL};
1393 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1394 PyObject *raw;
1395
1396 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001397 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001398
1399 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1400 &raw, &buffer_size)) {
1401 return -1;
1402 }
1403
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001404 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001405 return -1;
1406
1407 Py_CLEAR(self->raw);
1408 Py_INCREF(raw);
1409 self->raw = raw;
1410 self->buffer_size = buffer_size;
1411 self->readable = 1;
1412 self->writable = 0;
1413
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001414 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001415 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001416 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001417
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001418 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1419 Py_TYPE(raw) == &PyFileIO_Type);
1420
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001421 self->ok = 1;
1422 return 0;
1423}
1424
1425static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001426_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001427{
1428 Py_buffer buf;
1429 PyObject *memobj, *res;
1430 Py_ssize_t n;
1431 /* NOTE: the buffer needn't be released as its object is NULL. */
1432 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1433 return -1;
1434 memobj = PyMemoryView_FromBuffer(&buf);
1435 if (memobj == NULL)
1436 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001437 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1438 occurs so we needn't do it ourselves.
1439 We then retry reading, ignoring the signal if no handler has
1440 raised (see issue #10956).
1441 */
1442 do {
1443 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001444 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001445 Py_DECREF(memobj);
1446 if (res == NULL)
1447 return -1;
1448 if (res == Py_None) {
1449 /* Non-blocking stream would have blocked. Special return code! */
1450 Py_DECREF(res);
1451 return -2;
1452 }
1453 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1454 Py_DECREF(res);
1455 if (n < 0 || n > len) {
1456 PyErr_Format(PyExc_IOError,
1457 "raw readinto() returned invalid length %zd "
1458 "(should have been between 0 and %zd)", n, len);
1459 return -1;
1460 }
1461 if (n > 0 && self->abs_pos != -1)
1462 self->abs_pos += n;
1463 return n;
1464}
1465
1466static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001467_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001468{
1469 Py_ssize_t start, len, n;
1470 if (VALID_READ_BUFFER(self))
1471 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1472 else
1473 start = 0;
1474 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001475 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001476 if (n <= 0)
1477 return n;
1478 self->read_end = start + n;
1479 self->raw_pos = start + n;
1480 return n;
1481}
1482
1483static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001484_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001485{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001486 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001487 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001488
1489 /* First copy what we have in the current buffer. */
1490 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1491 if (current_size) {
1492 data = PyBytes_FromStringAndSize(
1493 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001494 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001495 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001496 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001497 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001498 /* We're going past the buffer's bounds, flush it */
1499 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001500 tmp = buffered_flush_and_rewind_unlocked(self);
1501 if (tmp == NULL)
1502 goto cleanup;
1503 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001504 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001505 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001506
1507 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001508 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1509 if (tmp == NULL)
1510 goto cleanup;
1511 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001512 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001513 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001514 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001515 if (tmp == Py_None) {
1516 if (current_size == 0) {
1517 res = Py_None;
1518 goto cleanup;
1519 } else {
1520 res = data;
1521 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001522 }
1523 }
1524 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001525 PyBytes_Concat(&data, tmp);
1526 res = data;
1527 goto cleanup;
1528 }
1529 else {
1530 res = tmp;
1531 goto cleanup;
1532 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001533 }
1534
1535 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001536 if (chunks == NULL)
1537 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001538
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001539 while (1) {
1540 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001541 if (PyList_Append(chunks, data) < 0)
1542 goto cleanup;
1543 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001544 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001545
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001546 /* Read until EOF or until read() would block. */
1547 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001548 if (data == NULL)
1549 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001550 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001551 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001552 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001553 }
1554 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1555 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 res = data;
1557 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001558 }
1559 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001560 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1561 res = tmp;
1562 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001563 }
1564 }
1565 current_size += PyBytes_GET_SIZE(data);
1566 if (self->abs_pos != -1)
1567 self->abs_pos += PyBytes_GET_SIZE(data);
1568 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569cleanup:
1570 /* res is either NULL or a borrowed ref */
1571 Py_XINCREF(res);
1572 Py_XDECREF(data);
1573 Py_XDECREF(tmp);
1574 Py_XDECREF(chunks);
1575 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001576}
1577
1578/* Read n bytes from the buffer if it can, otherwise return None.
1579 This function is simple enough that it can run unlocked. */
1580static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001581_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001582{
1583 Py_ssize_t current_size;
1584
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001585 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1586 if (n <= current_size) {
1587 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001588 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1589 if (res != NULL)
1590 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001591 return res;
1592 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001593 Py_RETURN_NONE;
1594}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001595
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001596/* Generic read function: read from the stream until enough bytes are read,
1597 * or until an EOF occurs or until read() would block.
1598 */
1599static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001600_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001601{
1602 PyObject *res = NULL;
1603 Py_ssize_t current_size, remaining, written;
1604 char *out;
1605
1606 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1607 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001608 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001610 res = PyBytes_FromStringAndSize(NULL, n);
1611 if (res == NULL)
1612 goto error;
1613 out = PyBytes_AS_STRING(res);
1614 remaining = n;
1615 written = 0;
1616 if (current_size > 0) {
1617 memcpy(out, self->buffer + self->pos, current_size);
1618 remaining -= current_size;
1619 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001620 self->pos += current_size;
1621 }
1622 /* Flush the write buffer if necessary */
1623 if (self->writable) {
1624 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1625 if (r == NULL)
1626 goto error;
1627 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001628 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630 while (remaining > 0) {
1631 /* We want to read a whole block at the end into buffer.
1632 If we had readv() we could do this in one pass. */
1633 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1634 if (r == 0)
1635 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001636 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001637 if (r == -1)
1638 goto error;
1639 if (r == 0 || r == -2) {
1640 /* EOF occurred or read() would block. */
1641 if (r == 0 || written > 0) {
1642 if (_PyBytes_Resize(&res, written))
1643 goto error;
1644 return res;
1645 }
1646 Py_DECREF(res);
1647 Py_INCREF(Py_None);
1648 return Py_None;
1649 }
1650 remaining -= r;
1651 written += r;
1652 }
1653 assert(remaining <= self->buffer_size);
1654 self->pos = 0;
1655 self->raw_pos = 0;
1656 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001657 /* NOTE: when the read is satisfied, we avoid issuing any additional
1658 reads, which could block indefinitely (e.g. on a socket).
1659 See issue #9550. */
1660 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001661 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001662 if (r == -1)
1663 goto error;
1664 if (r == 0 || r == -2) {
1665 /* EOF occurred or read() would block. */
1666 if (r == 0 || written > 0) {
1667 if (_PyBytes_Resize(&res, written))
1668 goto error;
1669 return res;
1670 }
1671 Py_DECREF(res);
1672 Py_INCREF(Py_None);
1673 return Py_None;
1674 }
1675 if (remaining > r) {
1676 memcpy(out + written, self->buffer + self->pos, r);
1677 written += r;
1678 self->pos += r;
1679 remaining -= r;
1680 }
1681 else if (remaining > 0) {
1682 memcpy(out + written, self->buffer + self->pos, remaining);
1683 written += remaining;
1684 self->pos += remaining;
1685 remaining = 0;
1686 }
1687 if (remaining == 0)
1688 break;
1689 }
1690
1691 return res;
1692
1693error:
1694 Py_XDECREF(res);
1695 return NULL;
1696}
1697
1698static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001699_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700{
1701 Py_ssize_t have, r;
1702
1703 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1704 /* Constraints:
1705 1. we don't want to advance the file position.
1706 2. we don't want to lose block alignment, so we can't shift the buffer
1707 to make some place.
1708 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1709 */
1710 if (have > 0) {
1711 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1712 }
1713
1714 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001715 _bufferedreader_reset_buf(self);
1716 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001717 if (r == -1)
1718 return NULL;
1719 if (r == -2)
1720 r = 0;
1721 self->pos = 0;
1722 return PyBytes_FromStringAndSize(self->buffer, r);
1723}
1724
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001725static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001726 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001727 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1728 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1729 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1730 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1731 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1732 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1733 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1734 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001735 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001736 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001738 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1739 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1740 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001741 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001742 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1743 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1744 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1745 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001746 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001747 {NULL, NULL}
1748};
1749
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001750static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001751 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001752 {NULL}
1753};
1754
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001755static PyGetSetDef bufferedreader_getset[] = {
1756 {"closed", (getter)buffered_closed_get, NULL, NULL},
1757 {"name", (getter)buffered_name_get, NULL, NULL},
1758 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001759 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760};
1761
1762
1763PyTypeObject PyBufferedReader_Type = {
1764 PyVarObject_HEAD_INIT(NULL, 0)
1765 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001766 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001768 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769 0, /*tp_print*/
1770 0, /*tp_getattr*/
1771 0, /*tp_setattr*/
1772 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001773 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774 0, /*tp_as_number*/
1775 0, /*tp_as_sequence*/
1776 0, /*tp_as_mapping*/
1777 0, /*tp_hash */
1778 0, /*tp_call*/
1779 0, /*tp_str*/
1780 0, /*tp_getattro*/
1781 0, /*tp_setattro*/
1782 0, /*tp_as_buffer*/
1783 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1784 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001785 bufferedreader_doc, /* tp_doc */
1786 (traverseproc)buffered_traverse, /* tp_traverse */
1787 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001789 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001791 (iternextfunc)buffered_iternext, /* tp_iternext */
1792 bufferedreader_methods, /* tp_methods */
1793 bufferedreader_members, /* tp_members */
1794 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 0, /* tp_base */
1796 0, /* tp_dict */
1797 0, /* tp_descr_get */
1798 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 offsetof(buffered, dict), /* tp_dictoffset */
1800 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 0, /* tp_alloc */
1802 PyType_GenericNew, /* tp_new */
1803};
1804
1805
Benjamin Peterson59406a92009-03-26 17:10:29 +00001806
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807/*
1808 * class BufferedWriter
1809 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001810PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 "A buffer for a writeable sequential RawIO object.\n"
1812 "\n"
1813 "The constructor creates a BufferedWriter for the given writeable raw\n"
1814 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001815 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816 );
1817
1818static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001819_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820{
1821 self->write_pos = 0;
1822 self->write_end = -1;
1823}
1824
1825static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001826bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827{
Florent Xicluna109d5732012-07-07 17:03:22 +02001828 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001829 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830 PyObject *raw;
1831
1832 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001833 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834
R David Murray9f10f562013-02-23 22:07:55 -05001835 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001836 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001837 return -1;
1838 }
1839
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001840 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841 return -1;
1842
1843 Py_CLEAR(self->raw);
1844 Py_INCREF(raw);
1845 self->raw = raw;
1846 self->readable = 0;
1847 self->writable = 1;
1848
1849 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001850 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001852 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853 self->pos = 0;
1854
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001855 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1856 Py_TYPE(raw) == &PyFileIO_Type);
1857
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858 self->ok = 1;
1859 return 0;
1860}
1861
1862static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001863_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864{
1865 Py_buffer buf;
1866 PyObject *memobj, *res;
1867 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001868 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001869 /* NOTE: the buffer needn't be released as its object is NULL. */
1870 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1871 return -1;
1872 memobj = PyMemoryView_FromBuffer(&buf);
1873 if (memobj == NULL)
1874 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001875 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1876 occurs so we needn't do it ourselves.
1877 We then retry writing, ignoring the signal if no handler has
1878 raised (see issue #10956).
1879 */
1880 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001882 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001883 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001884 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885 Py_DECREF(memobj);
1886 if (res == NULL)
1887 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001888 if (res == Py_None) {
1889 /* Non-blocking stream would have blocked. Special return code!
1890 Being paranoid we reset errno in case it is changed by code
1891 triggered by a decref. errno is used by _set_BlockingIOError(). */
1892 Py_DECREF(res);
1893 errno = errnum;
1894 return -2;
1895 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001896 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1897 Py_DECREF(res);
1898 if (n < 0 || n > len) {
1899 PyErr_Format(PyExc_IOError,
1900 "raw write() returned invalid length %zd "
1901 "(should have been between 0 and %zd)", n, len);
1902 return -1;
1903 }
1904 if (n > 0 && self->abs_pos != -1)
1905 self->abs_pos += n;
1906 return n;
1907}
1908
1909/* `restore_pos` is 1 if we need to restore the raw stream position at
1910 the end, 0 otherwise. */
1911static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001912_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913{
1914 Py_ssize_t written = 0;
1915 Py_off_t n, rewind;
1916
1917 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1918 goto end;
1919 /* First, rewind */
1920 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1921 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001922 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923 if (n < 0) {
1924 goto error;
1925 }
1926 self->raw_pos -= rewind;
1927 }
1928 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001929 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001930 self->buffer + self->write_pos,
1931 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1932 Py_off_t, Py_ssize_t));
1933 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001934 goto error;
1935 }
1936 else if (n == -2) {
1937 _set_BlockingIOError("write could not complete without blocking",
1938 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939 goto error;
1940 }
1941 self->write_pos += n;
1942 self->raw_pos = self->write_pos;
1943 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001944 /* Partial writes can return successfully when interrupted by a
1945 signal (see write(2)). We must run signal handlers before
1946 blocking another time, possibly indefinitely. */
1947 if (PyErr_CheckSignals() < 0)
1948 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 }
1950
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952
1953end:
1954 Py_RETURN_NONE;
1955
1956error:
1957 return NULL;
1958}
1959
1960static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001961bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001962{
1963 PyObject *res = NULL;
1964 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001965 Py_ssize_t written, avail, remaining;
1966 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967
1968 CHECK_INITIALIZED(self)
1969 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1970 return NULL;
1971 }
1972
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001973 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001974 PyErr_SetString(PyExc_ValueError, "write to closed file");
1975 PyBuffer_Release(&buf);
1976 return NULL;
1977 }
1978
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001979 if (!ENTER_BUFFERED(self)) {
1980 PyBuffer_Release(&buf);
1981 return NULL;
1982 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983
1984 /* Fast path: the data to write can be fully buffered. */
1985 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1986 self->pos = 0;
1987 self->raw_pos = 0;
1988 }
1989 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1990 if (buf.len <= avail) {
1991 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001992 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993 self->write_pos = self->pos;
1994 }
1995 ADJUST_POSITION(self, self->pos + buf.len);
1996 if (self->pos > self->write_end)
1997 self->write_end = self->pos;
1998 written = buf.len;
1999 goto end;
2000 }
2001
2002 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002003 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002005 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002006 if (w == NULL)
2007 goto error;
2008 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002009 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 /* Make some place by shifting the buffer. */
2011 assert(VALID_WRITE_BUFFER(self));
2012 memmove(self->buffer, self->buffer + self->write_pos,
2013 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2014 Py_off_t, Py_ssize_t));
2015 self->write_end -= self->write_pos;
2016 self->raw_pos -= self->write_pos;
2017 self->pos -= self->write_pos;
2018 self->write_pos = 0;
2019 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2020 Py_off_t, Py_ssize_t);
2021 if (buf.len <= avail) {
2022 /* Everything can be buffered */
2023 PyErr_Clear();
2024 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2025 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002026 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002027 written = buf.len;
2028 goto end;
2029 }
2030 /* Buffer as much as possible. */
2031 memcpy(self->buffer + self->write_end, buf.buf, avail);
2032 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002033 self->pos += avail;
2034 /* XXX Modifying the existing exception e using the pointer w
2035 will change e.characters_written but not e.args[2].
2036 Therefore we just replace with a new error. */
2037 _set_BlockingIOError("write could not complete without blocking",
2038 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002039 goto error;
2040 }
2041 Py_CLEAR(res);
2042
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002043 /* Adjust the raw stream position if it is away from the logical stream
2044 position. This happens if the read buffer has been filled but not
2045 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2046 the raw stream by itself).
2047 Fixes issue #6629.
2048 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002049 offset = RAW_OFFSET(self);
2050 if (offset != 0) {
2051 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002052 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002053 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002054 }
2055
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 /* Then write buf itself. At this point the buffer has been emptied. */
2057 remaining = buf.len;
2058 written = 0;
2059 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002060 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 self, (char *) buf.buf + written, buf.len - written);
2062 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002063 goto error;
2064 } else if (n == -2) {
2065 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 if (remaining > self->buffer_size) {
2067 /* Can't buffer everything, still buffer as much as possible */
2068 memcpy(self->buffer,
2069 (char *) buf.buf + written, self->buffer_size);
2070 self->raw_pos = 0;
2071 ADJUST_POSITION(self, self->buffer_size);
2072 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002073 written += self->buffer_size;
2074 _set_BlockingIOError("write could not complete without "
2075 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076 goto error;
2077 }
2078 PyErr_Clear();
2079 break;
2080 }
2081 written += n;
2082 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002083 /* Partial writes can return successfully when interrupted by a
2084 signal (see write(2)). We must run signal handlers before
2085 blocking another time, possibly indefinitely. */
2086 if (PyErr_CheckSignals() < 0)
2087 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002088 }
2089 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002090 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002091 if (remaining > 0) {
2092 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2093 written += remaining;
2094 }
2095 self->write_pos = 0;
2096 /* TODO: sanity check (remaining >= 0) */
2097 self->write_end = remaining;
2098 ADJUST_POSITION(self, remaining);
2099 self->raw_pos = 0;
2100
2101end:
2102 res = PyLong_FromSsize_t(written);
2103
2104error:
2105 LEAVE_BUFFERED(self)
2106 PyBuffer_Release(&buf);
2107 return res;
2108}
2109
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2113 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2114 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2115 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2116 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2117 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2118 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002119 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002120 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002122 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2123 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2124 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2125 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2126 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002127 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128 {NULL, NULL}
2129};
2130
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002132 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133 {NULL}
2134};
2135
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002136static PyGetSetDef bufferedwriter_getset[] = {
2137 {"closed", (getter)buffered_closed_get, NULL, NULL},
2138 {"name", (getter)buffered_name_get, NULL, NULL},
2139 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002140 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141};
2142
2143
2144PyTypeObject PyBufferedWriter_Type = {
2145 PyVarObject_HEAD_INIT(NULL, 0)
2146 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002149 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150 0, /*tp_print*/
2151 0, /*tp_getattr*/
2152 0, /*tp_setattr*/
2153 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002154 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155 0, /*tp_as_number*/
2156 0, /*tp_as_sequence*/
2157 0, /*tp_as_mapping*/
2158 0, /*tp_hash */
2159 0, /*tp_call*/
2160 0, /*tp_str*/
2161 0, /*tp_getattro*/
2162 0, /*tp_setattro*/
2163 0, /*tp_as_buffer*/
2164 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2165 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002166 bufferedwriter_doc, /* tp_doc */
2167 (traverseproc)buffered_traverse, /* tp_traverse */
2168 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 0, /* tp_iter */
2172 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002173 bufferedwriter_methods, /* tp_methods */
2174 bufferedwriter_members, /* tp_members */
2175 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002176 0, /* tp_base */
2177 0, /* tp_dict */
2178 0, /* tp_descr_get */
2179 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180 offsetof(buffered, dict), /* tp_dictoffset */
2181 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182 0, /* tp_alloc */
2183 PyType_GenericNew, /* tp_new */
2184};
2185
2186
2187
2188/*
2189 * BufferedRWPair
2190 */
2191
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193 "A buffered reader and writer object together.\n"
2194 "\n"
2195 "A buffered reader object and buffered writer object put together to\n"
2196 "form a sequential IO object that can read and write. This is typically\n"
2197 "used with a socket or two-way pipe.\n"
2198 "\n"
2199 "reader and writer are RawIOBase objects that are readable and\n"
2200 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002201 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 );
2203
2204/* XXX The usefulness of this (compared to having two separate IO objects) is
2205 * questionable.
2206 */
2207
2208typedef struct {
2209 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210 buffered *reader;
2211 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002212 PyObject *dict;
2213 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002214} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215
2216static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218{
2219 PyObject *reader, *writer;
2220 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221
Florent Xicluna109d5732012-07-07 17:03:22 +02002222 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2223 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 return -1;
2225 }
2226
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002228 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002229 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230 return -1;
2231
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002232 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002233 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234 if (self->reader == NULL)
2235 return -1;
2236
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002237 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002238 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239 if (self->writer == NULL) {
2240 Py_CLEAR(self->reader);
2241 return -1;
2242 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002243
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244 return 0;
2245}
2246
2247static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002248bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249{
2250 Py_VISIT(self->dict);
2251 return 0;
2252}
2253
2254static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002255bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002256{
2257 Py_CLEAR(self->reader);
2258 Py_CLEAR(self->writer);
2259 Py_CLEAR(self->dict);
2260 return 0;
2261}
2262
2263static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002264bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265{
2266 _PyObject_GC_UNTRACK(self);
2267 Py_CLEAR(self->reader);
2268 Py_CLEAR(self->writer);
2269 Py_CLEAR(self->dict);
2270 Py_TYPE(self)->tp_free((PyObject *) self);
2271}
2272
2273static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002274_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002275{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002276 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277 PyObject *ret;
2278
2279 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002280 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281 return NULL;
2282 }
2283
2284 ret = PyObject_CallObject(func, args);
2285 Py_DECREF(func);
2286 return ret;
2287}
2288
2289static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002290bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002292 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293}
2294
2295static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002296bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002298 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299}
2300
2301static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002302bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002304 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305}
2306
2307static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002308bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002309{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002310 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002311}
2312
2313static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002314bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002315{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002316 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317}
2318
2319static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002320bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002321{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002322 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323}
2324
2325static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002326bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002327{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002328 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329}
2330
2331static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002332bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002333{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002334 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002335}
2336
2337static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002338bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002340 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002341 if (ret == NULL)
2342 return NULL;
2343 Py_DECREF(ret);
2344
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002345 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002346}
2347
2348static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002349bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002350{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002351 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002352
2353 if (ret != Py_False) {
2354 /* either True or exception */
2355 return ret;
2356 }
2357 Py_DECREF(ret);
2358
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002359 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002360}
2361
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002362static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002363bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002364{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002365 if (self->writer == NULL) {
2366 PyErr_SetString(PyExc_RuntimeError,
2367 "the BufferedRWPair object is being garbage-collected");
2368 return NULL;
2369 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002370 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2371}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002372
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002373static PyMethodDef bufferedrwpair_methods[] = {
2374 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2375 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2376 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2377 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002378
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002379 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2380 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002381
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002382 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2383 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002384
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002385 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2386 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002387
Antoine Pitrou243757e2010-11-05 21:15:39 +00002388 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2389
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002390 {NULL, NULL}
2391};
2392
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002393static PyGetSetDef bufferedrwpair_getset[] = {
2394 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002395 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002396};
2397
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002398PyTypeObject PyBufferedRWPair_Type = {
2399 PyVarObject_HEAD_INIT(NULL, 0)
2400 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002401 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002402 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002403 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002404 0, /*tp_print*/
2405 0, /*tp_getattr*/
2406 0, /*tp_setattr*/
2407 0, /*tp_compare */
2408 0, /*tp_repr*/
2409 0, /*tp_as_number*/
2410 0, /*tp_as_sequence*/
2411 0, /*tp_as_mapping*/
2412 0, /*tp_hash */
2413 0, /*tp_call*/
2414 0, /*tp_str*/
2415 0, /*tp_getattro*/
2416 0, /*tp_setattro*/
2417 0, /*tp_as_buffer*/
2418 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2419 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002420 bufferedrwpair_doc, /* tp_doc */
2421 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2422 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002423 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002424 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002425 0, /* tp_iter */
2426 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002427 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430 0, /* tp_base */
2431 0, /* tp_dict */
2432 0, /* tp_descr_get */
2433 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002434 offsetof(rwpair, dict), /* tp_dictoffset */
2435 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436 0, /* tp_alloc */
2437 PyType_GenericNew, /* tp_new */
2438};
2439
2440
2441
2442/*
2443 * BufferedRandom
2444 */
2445
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002446PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002447 "A buffered interface to random access streams.\n"
2448 "\n"
2449 "The constructor creates a reader and writer for a seekable stream,\n"
2450 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002451 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002452 );
2453
2454static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002455bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456{
Florent Xicluna109d5732012-07-07 17:03:22 +02002457 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459 PyObject *raw;
2460
2461 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002462 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002463
R David Murray9f10f562013-02-23 22:07:55 -05002464 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002465 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466 return -1;
2467 }
2468
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002469 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002470 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002471 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002472 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002473 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002474 return -1;
2475
2476 Py_CLEAR(self->raw);
2477 Py_INCREF(raw);
2478 self->raw = raw;
2479 self->buffer_size = buffer_size;
2480 self->readable = 1;
2481 self->writable = 1;
2482
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002483 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002484 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002485 _bufferedreader_reset_buf(self);
2486 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002487 self->pos = 0;
2488
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002489 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2490 Py_TYPE(raw) == &PyFileIO_Type);
2491
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002492 self->ok = 1;
2493 return 0;
2494}
2495
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002496static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002497 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002498 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2499 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2500 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2501 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2502 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2503 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2504 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002505 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002506 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002508 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002509
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002510 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2511 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2512 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2513 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2514 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2515 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2516 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2517 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2518 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002519 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002520 {NULL, NULL}
2521};
2522
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002523static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002524 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002525 {NULL}
2526};
2527
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002528static PyGetSetDef bufferedrandom_getset[] = {
2529 {"closed", (getter)buffered_closed_get, NULL, NULL},
2530 {"name", (getter)buffered_name_get, NULL, NULL},
2531 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002532 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002533};
2534
2535
2536PyTypeObject PyBufferedRandom_Type = {
2537 PyVarObject_HEAD_INIT(NULL, 0)
2538 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002539 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002540 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002541 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002542 0, /*tp_print*/
2543 0, /*tp_getattr*/
2544 0, /*tp_setattr*/
2545 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002546 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002547 0, /*tp_as_number*/
2548 0, /*tp_as_sequence*/
2549 0, /*tp_as_mapping*/
2550 0, /*tp_hash */
2551 0, /*tp_call*/
2552 0, /*tp_str*/
2553 0, /*tp_getattro*/
2554 0, /*tp_setattro*/
2555 0, /*tp_as_buffer*/
2556 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2557 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002558 bufferedrandom_doc, /* tp_doc */
2559 (traverseproc)buffered_traverse, /* tp_traverse */
2560 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002561 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002562 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002563 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002564 (iternextfunc)buffered_iternext, /* tp_iternext */
2565 bufferedrandom_methods, /* tp_methods */
2566 bufferedrandom_members, /* tp_members */
2567 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002568 0, /* tp_base */
2569 0, /*tp_dict*/
2570 0, /* tp_descr_get */
2571 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002572 offsetof(buffered, dict), /*tp_dictoffset*/
2573 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002574 0, /* tp_alloc */
2575 PyType_GenericNew, /* tp_new */
2576};