blob: 3afe7b17f87db17f68fc0692094c23795809ea29 [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
Benjamin Peterson68623612012-12-20 11:53:11 -0600530 if (exc != NULL) {
531 if (res != NULL) {
532 Py_CLEAR(res);
533 PyErr_Restore(exc, val, tb);
534 }
535 else {
536 PyObject *val2;
537 Py_DECREF(exc);
538 Py_XDECREF(tb);
539 PyErr_Fetch(&exc, &val2, &tb);
540 PyErr_NormalizeException(&exc, &val2, &tb);
541 PyException_SetContext(val2, val);
542 PyErr_Restore(exc, val2, tb);
543 }
544 }
545
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000546end:
547 LEAVE_BUFFERED(self)
548 return res;
549}
550
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000551/* detach */
552
553static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000554buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000555{
556 PyObject *raw, *res;
557 CHECK_INITIALIZED(self)
558 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
559 if (res == NULL)
560 return NULL;
561 Py_DECREF(res);
562 raw = self->raw;
563 self->raw = NULL;
564 self->detached = 1;
565 self->ok = 0;
566 return raw;
567}
568
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569/* Inquiries */
570
571static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000572buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573{
574 CHECK_INITIALIZED(self)
575 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
576}
577
578static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000579buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580{
581 CHECK_INITIALIZED(self)
582 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
583}
584
585static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000586buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000587{
588 CHECK_INITIALIZED(self)
589 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
590}
591
592static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000593buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594{
595 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200596 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597}
598
599static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000600buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601{
602 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200603 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604}
605
606/* Lower-level APIs */
607
608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000610{
611 CHECK_INITIALIZED(self)
612 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
613}
614
615static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000616buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617{
618 CHECK_INITIALIZED(self)
619 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
620}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000621
Antoine Pitrou243757e2010-11-05 21:15:39 +0000622/* Serialization */
623
624static PyObject *
625buffered_getstate(buffered *self, PyObject *args)
626{
627 PyErr_Format(PyExc_TypeError,
628 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
629 return NULL;
630}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000631
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000632/* Forward decls */
633static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100634_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000638_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200642_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000644_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000645static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000646_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000647static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000648_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200649static Py_ssize_t
650_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651
652/*
653 * Helpers
654 */
655
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100656/* Sets the current error to BlockingIOError */
657static void
658_set_BlockingIOError(char *msg, Py_ssize_t written)
659{
660 PyObject *err;
661 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
662 errno, msg, written);
663 if (err)
664 PyErr_SetObject(PyExc_BlockingIOError, err);
665 Py_XDECREF(err);
666}
667
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668/* Returns the address of the `written` member if a BlockingIOError was
669 raised, NULL otherwise. The error is always re-raised. */
670static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000671_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672{
673 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200674 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675
676 PyErr_Fetch(&t, &v, &tb);
677 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
678 PyErr_Restore(t, v, tb);
679 return NULL;
680 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200681 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 /* TODO: sanity check (err->written >= 0) */
683 PyErr_Restore(t, v, tb);
684 return &err->written;
685}
686
687static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000688_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000691 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
693 if (res == NULL)
694 return -1;
695 n = PyNumber_AsOff_t(res, PyExc_ValueError);
696 Py_DECREF(res);
697 if (n < 0) {
698 if (!PyErr_Occurred())
699 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000700 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200701 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 return -1;
703 }
704 self->abs_pos = n;
705 return n;
706}
707
708static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000709_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710{
711 PyObject *res, *posobj, *whenceobj;
712 Py_off_t n;
713
714 posobj = PyLong_FromOff_t(target);
715 if (posobj == NULL)
716 return -1;
717 whenceobj = PyLong_FromLong(whence);
718 if (whenceobj == NULL) {
719 Py_DECREF(posobj);
720 return -1;
721 }
722 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
723 posobj, whenceobj, NULL);
724 Py_DECREF(posobj);
725 Py_DECREF(whenceobj);
726 if (res == NULL)
727 return -1;
728 n = PyNumber_AsOff_t(res, PyExc_ValueError);
729 Py_DECREF(res);
730 if (n < 0) {
731 if (!PyErr_Occurred())
732 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000733 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200734 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000735 return -1;
736 }
737 self->abs_pos = n;
738 return n;
739}
740
741static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000742_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000743{
744 Py_ssize_t n;
745 if (self->buffer_size <= 0) {
746 PyErr_SetString(PyExc_ValueError,
747 "buffer size must be strictly positive");
748 return -1;
749 }
750 if (self->buffer)
751 PyMem_Free(self->buffer);
752 self->buffer = PyMem_Malloc(self->buffer_size);
753 if (self->buffer == NULL) {
754 PyErr_NoMemory();
755 return -1;
756 }
Georg Brandldfd73442009-04-05 11:47:34 +0000757#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000758 if (self->lock)
759 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000760 self->lock = PyThread_allocate_lock();
761 if (self->lock == NULL) {
762 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
763 return -1;
764 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000765 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000766#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000767 /* Find out whether buffer_size is a power of 2 */
768 /* XXX is this optimization useful? */
769 for (n = self->buffer_size - 1; n & 1; n >>= 1)
770 ;
771 if (n == 0)
772 self->buffer_mask = self->buffer_size - 1;
773 else
774 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000775 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000776 PyErr_Clear();
777 return 0;
778}
779
Antoine Pitrou707ce822011-02-25 21:24:11 +0000780/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
781 clears the error indicator), 0 otherwise.
782 Should only be called when PyErr_Occurred() is true.
783*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700784int
785_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000786{
787 static PyObject *eintr_int = NULL;
788 PyObject *typ, *val, *tb;
789 PyEnvironmentErrorObject *env_err;
790
791 if (eintr_int == NULL) {
792 eintr_int = PyLong_FromLong(EINTR);
793 assert(eintr_int != NULL);
794 }
795 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
796 return 0;
797 PyErr_Fetch(&typ, &val, &tb);
798 PyErr_NormalizeException(&typ, &val, &tb);
799 env_err = (PyEnvironmentErrorObject *) val;
800 assert(env_err != NULL);
801 if (env_err->myerrno != NULL &&
802 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
803 Py_DECREF(typ);
804 Py_DECREF(val);
805 Py_XDECREF(tb);
806 return 1;
807 }
808 /* This silences any error set by PyObject_RichCompareBool() */
809 PyErr_Restore(typ, val, tb);
810 return 0;
811}
812
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000813/*
814 * Shared methods and wrappers
815 */
816
817static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200818buffered_flush_and_rewind_unlocked(buffered *self)
819{
820 PyObject *res;
821
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100822 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200823 if (res == NULL)
824 return NULL;
825 Py_DECREF(res);
826
827 if (self->readable) {
828 /* Rewind the raw stream so that its position corresponds to
829 the current logical position. */
830 Py_off_t n;
831 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
832 _bufferedreader_reset_buf(self);
833 if (n == -1)
834 return NULL;
835 }
836 Py_RETURN_NONE;
837}
838
839static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000840buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841{
842 PyObject *res;
843
844 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000845 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000846
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000847 if (!ENTER_BUFFERED(self))
848 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200849 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850 LEAVE_BUFFERED(self)
851
852 return res;
853}
854
855static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000856buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000857{
858 Py_ssize_t n = 0;
859 PyObject *res = NULL;
860
861 CHECK_INITIALIZED(self)
862 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
863 return NULL;
864 }
865
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000866 if (!ENTER_BUFFERED(self))
867 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868
869 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200870 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871 if (res == NULL)
872 goto end;
873 Py_CLEAR(res);
874 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200875 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876
877end:
878 LEAVE_BUFFERED(self)
879 return res;
880}
881
882static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000883buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000884{
885 Py_ssize_t n = -1;
886 PyObject *res;
887
888 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000889 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890 return NULL;
891 }
892 if (n < -1) {
893 PyErr_SetString(PyExc_ValueError,
894 "read length must be positive or -1");
895 return NULL;
896 }
897
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000898 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000900 if (n == -1) {
901 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000902 if (!ENTER_BUFFERED(self))
903 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000904 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000905 }
906 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000907 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200908 if (res != Py_None)
909 return res;
910 Py_DECREF(res);
911 if (!ENTER_BUFFERED(self))
912 return NULL;
913 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000914 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915
Antoine Pitroue05565e2011-08-20 14:39:23 +0200916 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 return res;
918}
919
920static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000921buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922{
923 Py_ssize_t n, have, r;
924 PyObject *res = NULL;
925
926 CHECK_INITIALIZED(self)
927 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
928 return NULL;
929 }
930
931 if (n < 0) {
932 PyErr_SetString(PyExc_ValueError,
933 "read length must be positive");
934 return NULL;
935 }
936 if (n == 0)
937 return PyBytes_FromStringAndSize(NULL, 0);
938
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 /* Return up to n bytes. If at least one byte is buffered, we
940 only return buffered bytes. Otherwise, we do one raw read. */
941
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
943 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100944 n = Py_MIN(have, n);
945 res = _bufferedreader_read_fast(self, n);
946 assert(res != Py_None);
947 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100949 res = PyBytes_FromStringAndSize(NULL, n);
950 if (res == NULL)
951 return NULL;
952 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200953 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200955 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000956 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100957 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
958 LEAVE_BUFFERED(self)
959 if (r == -1) {
960 Py_DECREF(res);
961 return NULL;
962 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 if (r == -2)
964 r = 0;
965 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100966 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 return res;
968}
969
970static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000971buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200973 Py_buffer buf;
974 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000975 PyObject *res = NULL;
976
977 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200978
979 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
980 return NULL;
981
982 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
983 if (n > 0) {
984 if (n >= buf.len) {
985 memcpy(buf.buf, self->buffer + self->pos, buf.len);
986 self->pos += buf.len;
987 res = PyLong_FromSsize_t(buf.len);
988 goto end_unlocked;
989 }
990 memcpy(buf.buf, self->buffer + self->pos, n);
991 self->pos += n;
992 written = n;
993 }
994
995 if (!ENTER_BUFFERED(self))
996 goto end_unlocked;
997
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000998 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200999 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001000 if (res == NULL)
1001 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001004
1005 _bufferedreader_reset_buf(self);
1006 self->pos = 0;
1007
1008 for (remaining = buf.len - written;
1009 remaining > 0;
1010 written += n, remaining -= n) {
1011 /* If remaining bytes is larger than internal buffer size, copy
1012 * directly into caller's buffer. */
1013 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001014 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1015 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016 }
1017 else {
1018 n = _bufferedreader_fill_buffer(self);
1019 if (n > 0) {
1020 if (n > remaining)
1021 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001022 memcpy((char *) buf.buf + written,
1023 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001024 self->pos += n;
1025 continue; /* short circuit */
1026 }
1027 }
1028 if (n == 0 || (n == -2 && written > 0))
1029 break;
1030 if (n < 0) {
1031 if (n == -2) {
1032 Py_INCREF(Py_None);
1033 res = Py_None;
1034 }
1035 goto end;
1036 }
1037 }
1038 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001039
1040end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001041 LEAVE_BUFFERED(self);
1042end_unlocked:
1043 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044 return res;
1045}
1046
1047static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001048_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049{
1050 PyObject *res = NULL;
1051 PyObject *chunks = NULL;
1052 Py_ssize_t n, written = 0;
1053 const char *start, *s, *end;
1054
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001055 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001056
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001057 /* First, try to find a line in the buffer. This can run unlocked because
1058 the calls to the C API are simple enough that they can't trigger
1059 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001060 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1061 if (limit >= 0 && n > limit)
1062 n = limit;
1063 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001064 s = memchr(start, '\n', n);
1065 if (s != NULL) {
1066 res = PyBytes_FromStringAndSize(start, s - start + 1);
1067 if (res != NULL)
1068 self->pos += s - start + 1;
1069 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070 }
1071 if (n == limit) {
1072 res = PyBytes_FromStringAndSize(start, n);
1073 if (res != NULL)
1074 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001075 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001076 }
1077
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001078 if (!ENTER_BUFFERED(self))
1079 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001080
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001082 chunks = PyList_New(0);
1083 if (chunks == NULL)
1084 goto end;
1085 if (n > 0) {
1086 res = PyBytes_FromStringAndSize(start, n);
1087 if (res == NULL)
1088 goto end;
1089 if (PyList_Append(chunks, res) < 0) {
1090 Py_CLEAR(res);
1091 goto end;
1092 }
1093 Py_CLEAR(res);
1094 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001095 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001096 if (limit >= 0)
1097 limit -= n;
1098 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001099 if (self->writable) {
1100 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1101 if (r == NULL)
1102 goto end;
1103 Py_DECREF(r);
1104 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105
1106 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001107 _bufferedreader_reset_buf(self);
1108 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001109 if (n == -1)
1110 goto end;
1111 if (n <= 0)
1112 break;
1113 if (limit >= 0 && n > limit)
1114 n = limit;
1115 start = self->buffer;
1116 end = start + n;
1117 s = start;
1118 while (s < end) {
1119 if (*s++ == '\n') {
1120 res = PyBytes_FromStringAndSize(start, s - start);
1121 if (res == NULL)
1122 goto end;
1123 self->pos = s - start;
1124 goto found;
1125 }
1126 }
1127 res = PyBytes_FromStringAndSize(start, n);
1128 if (res == NULL)
1129 goto end;
1130 if (n == limit) {
1131 self->pos = n;
1132 break;
1133 }
1134 if (PyList_Append(chunks, res) < 0) {
1135 Py_CLEAR(res);
1136 goto end;
1137 }
1138 Py_CLEAR(res);
1139 written += n;
1140 if (limit >= 0)
1141 limit -= n;
1142 }
1143found:
1144 if (res != NULL && PyList_Append(chunks, res) < 0) {
1145 Py_CLEAR(res);
1146 goto end;
1147 }
1148 Py_CLEAR(res);
1149 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1150
1151end:
1152 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001153end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001154 Py_XDECREF(chunks);
1155 return res;
1156}
1157
1158static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001159buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001160{
1161 Py_ssize_t limit = -1;
1162
1163 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001164 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001165 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001166 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001167}
1168
1169
1170static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001171buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172{
1173 Py_off_t pos;
1174
1175 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001176 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177 if (pos == -1)
1178 return NULL;
1179 pos -= RAW_OFFSET(self);
1180 /* TODO: sanity check (pos >= 0) */
1181 return PyLong_FromOff_t(pos);
1182}
1183
1184static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001185buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186{
1187 Py_off_t target, n;
1188 int whence = 0;
1189 PyObject *targetobj, *res = NULL;
1190
1191 CHECK_INITIALIZED(self)
1192 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1193 return NULL;
1194 }
Jesus Cea94363612012-06-22 18:32:07 +02001195
1196 /* Do some error checking instead of trusting OS 'seek()'
1197 ** error detection, just in case.
1198 */
1199 if ((whence < 0 || whence >2)
1200#ifdef SEEK_HOLE
1201 && (whence != SEEK_HOLE)
1202#endif
1203#ifdef SEEK_DATA
1204 && (whence != SEEK_DATA)
1205#endif
1206 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001208 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209 return NULL;
1210 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001211
1212 CHECK_CLOSED(self, "seek of closed file")
1213
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001214 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1215 return NULL;
1216
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1218 if (target == -1 && PyErr_Occurred())
1219 return NULL;
1220
Jesus Cea94363612012-06-22 18:32:07 +02001221 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1222 buffer. Other whence values must be managed without this optimization.
1223 Some Operating Systems can provide additional values, like
1224 SEEK_HOLE/SEEK_DATA. */
1225 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226 Py_off_t current, avail;
1227 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001228 so as to return quickly if possible. Also, we needn't take the
1229 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001231 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1232 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001233 current = RAW_TELL(self);
1234 avail = READAHEAD(self);
1235 if (avail > 0) {
1236 Py_off_t offset;
1237 if (whence == 0)
1238 offset = target - (current - RAW_OFFSET(self));
1239 else
1240 offset = target;
1241 if (offset >= -self->pos && offset <= avail) {
1242 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001243 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244 }
1245 }
1246 }
1247
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001248 if (!ENTER_BUFFERED(self))
1249 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001250
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 /* Fallback: invoke raw seek() method and clear buffer */
1252 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001253 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 if (res == NULL)
1255 goto end;
1256 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001257 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001258 }
1259
1260 /* TODO: align on block boundary and read buffer if needed? */
1261 if (whence == 1)
1262 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001263 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 if (n == -1)
1265 goto end;
1266 self->raw_pos = -1;
1267 res = PyLong_FromOff_t(n);
1268 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001269 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270
1271end:
1272 LEAVE_BUFFERED(self)
1273 return res;
1274}
1275
1276static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001277buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278{
1279 PyObject *pos = Py_None;
1280 PyObject *res = NULL;
1281
1282 CHECK_INITIALIZED(self)
1283 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1284 return NULL;
1285 }
1286
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001287 if (!ENTER_BUFFERED(self))
1288 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289
1290 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001291 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 if (res == NULL)
1293 goto end;
1294 Py_CLEAR(res);
1295 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1297 if (res == NULL)
1298 goto end;
1299 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001300 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 PyErr_Clear();
1302
1303end:
1304 LEAVE_BUFFERED(self)
1305 return res;
1306}
1307
1308static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001309buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310{
1311 PyObject *line;
1312 PyTypeObject *tp;
1313
1314 CHECK_INITIALIZED(self);
1315
1316 tp = Py_TYPE(self);
1317 if (tp == &PyBufferedReader_Type ||
1318 tp == &PyBufferedRandom_Type) {
1319 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001320 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321 }
1322 else {
1323 line = PyObject_CallMethodObjArgs((PyObject *)self,
1324 _PyIO_str_readline, NULL);
1325 if (line && !PyBytes_Check(line)) {
1326 PyErr_Format(PyExc_IOError,
1327 "readline() should have returned a bytes object, "
1328 "not '%.200s'", Py_TYPE(line)->tp_name);
1329 Py_DECREF(line);
1330 return NULL;
1331 }
1332 }
1333
1334 if (line == NULL)
1335 return NULL;
1336
1337 if (PyBytes_GET_SIZE(line) == 0) {
1338 /* Reached EOF or would have blocked */
1339 Py_DECREF(line);
1340 return NULL;
1341 }
1342
1343 return line;
1344}
1345
Antoine Pitrou716c4442009-05-23 19:04:03 +00001346static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001347buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001348{
1349 PyObject *nameobj, *res;
1350
Martin v. Löwis767046a2011-10-14 15:35:36 +02001351 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001352 if (nameobj == NULL) {
1353 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1354 PyErr_Clear();
1355 else
1356 return NULL;
1357 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1358 }
1359 else {
1360 res = PyUnicode_FromFormat("<%s name=%R>",
1361 Py_TYPE(self)->tp_name, nameobj);
1362 Py_DECREF(nameobj);
1363 }
1364 return res;
1365}
1366
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367/*
1368 * class BufferedReader
1369 */
1370
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372 "Create a new buffered reader using the given readable raw IO object.");
1373
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001374static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001375{
1376 self->read_end = -1;
1377}
1378
1379static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001380bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381{
1382 char *kwlist[] = {"raw", "buffer_size", NULL};
1383 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1384 PyObject *raw;
1385
1386 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001387 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388
1389 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1390 &raw, &buffer_size)) {
1391 return -1;
1392 }
1393
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001394 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001395 return -1;
1396
1397 Py_CLEAR(self->raw);
1398 Py_INCREF(raw);
1399 self->raw = raw;
1400 self->buffer_size = buffer_size;
1401 self->readable = 1;
1402 self->writable = 0;
1403
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001404 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001405 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001406 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001407
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001408 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1409 Py_TYPE(raw) == &PyFileIO_Type);
1410
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411 self->ok = 1;
1412 return 0;
1413}
1414
1415static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001416_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001417{
1418 Py_buffer buf;
1419 PyObject *memobj, *res;
1420 Py_ssize_t n;
1421 /* NOTE: the buffer needn't be released as its object is NULL. */
1422 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1423 return -1;
1424 memobj = PyMemoryView_FromBuffer(&buf);
1425 if (memobj == NULL)
1426 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001427 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1428 occurs so we needn't do it ourselves.
1429 We then retry reading, ignoring the signal if no handler has
1430 raised (see issue #10956).
1431 */
1432 do {
1433 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001434 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 Py_DECREF(memobj);
1436 if (res == NULL)
1437 return -1;
1438 if (res == Py_None) {
1439 /* Non-blocking stream would have blocked. Special return code! */
1440 Py_DECREF(res);
1441 return -2;
1442 }
1443 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1444 Py_DECREF(res);
1445 if (n < 0 || n > len) {
1446 PyErr_Format(PyExc_IOError,
1447 "raw readinto() returned invalid length %zd "
1448 "(should have been between 0 and %zd)", n, len);
1449 return -1;
1450 }
1451 if (n > 0 && self->abs_pos != -1)
1452 self->abs_pos += n;
1453 return n;
1454}
1455
1456static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001457_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458{
1459 Py_ssize_t start, len, n;
1460 if (VALID_READ_BUFFER(self))
1461 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1462 else
1463 start = 0;
1464 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001465 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 if (n <= 0)
1467 return n;
1468 self->read_end = start + n;
1469 self->raw_pos = start + n;
1470 return n;
1471}
1472
1473static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001474_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001475{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001476 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001477 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001478
1479 /* First copy what we have in the current buffer. */
1480 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1481 if (current_size) {
1482 data = PyBytes_FromStringAndSize(
1483 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001484 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001485 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001486 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001487 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001488 /* We're going past the buffer's bounds, flush it */
1489 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001490 tmp = buffered_flush_and_rewind_unlocked(self);
1491 if (tmp == NULL)
1492 goto cleanup;
1493 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001494 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001495 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001496
1497 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001498 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1499 if (tmp == NULL)
1500 goto cleanup;
1501 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001502 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001503 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001504 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001505 if (tmp == Py_None) {
1506 if (current_size == 0) {
1507 res = Py_None;
1508 goto cleanup;
1509 } else {
1510 res = data;
1511 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001512 }
1513 }
1514 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001515 PyBytes_Concat(&data, tmp);
1516 res = data;
1517 goto cleanup;
1518 }
1519 else {
1520 res = tmp;
1521 goto cleanup;
1522 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001523 }
1524
1525 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001526 if (chunks == NULL)
1527 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001528
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001529 while (1) {
1530 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001531 if (PyList_Append(chunks, data) < 0)
1532 goto cleanup;
1533 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001534 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001535
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001536 /* Read until EOF or until read() would block. */
1537 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001538 if (data == NULL)
1539 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001540 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001541 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001542 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001543 }
1544 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1545 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001546 res = data;
1547 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001548 }
1549 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001550 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1551 res = tmp;
1552 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001553 }
1554 }
1555 current_size += PyBytes_GET_SIZE(data);
1556 if (self->abs_pos != -1)
1557 self->abs_pos += PyBytes_GET_SIZE(data);
1558 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001559cleanup:
1560 /* res is either NULL or a borrowed ref */
1561 Py_XINCREF(res);
1562 Py_XDECREF(data);
1563 Py_XDECREF(tmp);
1564 Py_XDECREF(chunks);
1565 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001566}
1567
1568/* Read n bytes from the buffer if it can, otherwise return None.
1569 This function is simple enough that it can run unlocked. */
1570static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001571_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572{
1573 Py_ssize_t current_size;
1574
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001575 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1576 if (n <= current_size) {
1577 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1579 if (res != NULL)
1580 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001581 return res;
1582 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 Py_RETURN_NONE;
1584}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001585
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586/* Generic read function: read from the stream until enough bytes are read,
1587 * or until an EOF occurs or until read() would block.
1588 */
1589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001590_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591{
1592 PyObject *res = NULL;
1593 Py_ssize_t current_size, remaining, written;
1594 char *out;
1595
1596 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1597 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001598 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001600 res = PyBytes_FromStringAndSize(NULL, n);
1601 if (res == NULL)
1602 goto error;
1603 out = PyBytes_AS_STRING(res);
1604 remaining = n;
1605 written = 0;
1606 if (current_size > 0) {
1607 memcpy(out, self->buffer + self->pos, current_size);
1608 remaining -= current_size;
1609 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001610 self->pos += current_size;
1611 }
1612 /* Flush the write buffer if necessary */
1613 if (self->writable) {
1614 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1615 if (r == NULL)
1616 goto error;
1617 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001618 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001619 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620 while (remaining > 0) {
1621 /* We want to read a whole block at the end into buffer.
1622 If we had readv() we could do this in one pass. */
1623 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1624 if (r == 0)
1625 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001626 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001627 if (r == -1)
1628 goto error;
1629 if (r == 0 || r == -2) {
1630 /* EOF occurred or read() would block. */
1631 if (r == 0 || written > 0) {
1632 if (_PyBytes_Resize(&res, written))
1633 goto error;
1634 return res;
1635 }
1636 Py_DECREF(res);
1637 Py_INCREF(Py_None);
1638 return Py_None;
1639 }
1640 remaining -= r;
1641 written += r;
1642 }
1643 assert(remaining <= self->buffer_size);
1644 self->pos = 0;
1645 self->raw_pos = 0;
1646 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001647 /* NOTE: when the read is satisfied, we avoid issuing any additional
1648 reads, which could block indefinitely (e.g. on a socket).
1649 See issue #9550. */
1650 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001651 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001652 if (r == -1)
1653 goto error;
1654 if (r == 0 || r == -2) {
1655 /* EOF occurred or read() would block. */
1656 if (r == 0 || written > 0) {
1657 if (_PyBytes_Resize(&res, written))
1658 goto error;
1659 return res;
1660 }
1661 Py_DECREF(res);
1662 Py_INCREF(Py_None);
1663 return Py_None;
1664 }
1665 if (remaining > r) {
1666 memcpy(out + written, self->buffer + self->pos, r);
1667 written += r;
1668 self->pos += r;
1669 remaining -= r;
1670 }
1671 else if (remaining > 0) {
1672 memcpy(out + written, self->buffer + self->pos, remaining);
1673 written += remaining;
1674 self->pos += remaining;
1675 remaining = 0;
1676 }
1677 if (remaining == 0)
1678 break;
1679 }
1680
1681 return res;
1682
1683error:
1684 Py_XDECREF(res);
1685 return NULL;
1686}
1687
1688static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001689_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001690{
1691 Py_ssize_t have, r;
1692
1693 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1694 /* Constraints:
1695 1. we don't want to advance the file position.
1696 2. we don't want to lose block alignment, so we can't shift the buffer
1697 to make some place.
1698 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1699 */
1700 if (have > 0) {
1701 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1702 }
1703
1704 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 _bufferedreader_reset_buf(self);
1706 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001707 if (r == -1)
1708 return NULL;
1709 if (r == -2)
1710 r = 0;
1711 self->pos = 0;
1712 return PyBytes_FromStringAndSize(self->buffer, r);
1713}
1714
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001715static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001716 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001717 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1718 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1719 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1720 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1721 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1722 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1723 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1724 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001725 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001726 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001727
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001728 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1729 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1730 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001731 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001732 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1733 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1734 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1735 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001736 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 {NULL, NULL}
1738};
1739
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001740static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001741 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001742 {NULL}
1743};
1744
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001745static PyGetSetDef bufferedreader_getset[] = {
1746 {"closed", (getter)buffered_closed_get, NULL, NULL},
1747 {"name", (getter)buffered_name_get, NULL, NULL},
1748 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001749 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750};
1751
1752
1753PyTypeObject PyBufferedReader_Type = {
1754 PyVarObject_HEAD_INIT(NULL, 0)
1755 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001756 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759 0, /*tp_print*/
1760 0, /*tp_getattr*/
1761 0, /*tp_setattr*/
1762 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001763 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 0, /*tp_as_number*/
1765 0, /*tp_as_sequence*/
1766 0, /*tp_as_mapping*/
1767 0, /*tp_hash */
1768 0, /*tp_call*/
1769 0, /*tp_str*/
1770 0, /*tp_getattro*/
1771 0, /*tp_setattro*/
1772 0, /*tp_as_buffer*/
1773 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1774 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001775 bufferedreader_doc, /* tp_doc */
1776 (traverseproc)buffered_traverse, /* tp_traverse */
1777 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001779 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001781 (iternextfunc)buffered_iternext, /* tp_iternext */
1782 bufferedreader_methods, /* tp_methods */
1783 bufferedreader_members, /* tp_members */
1784 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 0, /* tp_base */
1786 0, /* tp_dict */
1787 0, /* tp_descr_get */
1788 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001789 offsetof(buffered, dict), /* tp_dictoffset */
1790 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791 0, /* tp_alloc */
1792 PyType_GenericNew, /* tp_new */
1793};
1794
1795
Benjamin Peterson59406a92009-03-26 17:10:29 +00001796
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797/*
1798 * class BufferedWriter
1799 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 "A buffer for a writeable sequential RawIO object.\n"
1802 "\n"
1803 "The constructor creates a BufferedWriter for the given writeable raw\n"
1804 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001805 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 );
1807
1808static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810{
1811 self->write_pos = 0;
1812 self->write_end = -1;
1813}
1814
1815static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001816bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001817{
Florent Xicluna109d5732012-07-07 17:03:22 +02001818 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001819 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 PyObject *raw;
1821
1822 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001823 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001824
R David Murray9f10f562013-02-23 22:07:55 -05001825 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001826 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 return -1;
1828 }
1829
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001830 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 return -1;
1832
1833 Py_CLEAR(self->raw);
1834 Py_INCREF(raw);
1835 self->raw = raw;
1836 self->readable = 0;
1837 self->writable = 1;
1838
1839 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001840 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001842 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001843 self->pos = 0;
1844
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001845 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1846 Py_TYPE(raw) == &PyFileIO_Type);
1847
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848 self->ok = 1;
1849 return 0;
1850}
1851
1852static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001853_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854{
1855 Py_buffer buf;
1856 PyObject *memobj, *res;
1857 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001858 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859 /* NOTE: the buffer needn't be released as its object is NULL. */
1860 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1861 return -1;
1862 memobj = PyMemoryView_FromBuffer(&buf);
1863 if (memobj == NULL)
1864 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001865 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1866 occurs so we needn't do it ourselves.
1867 We then retry writing, ignoring the signal if no handler has
1868 raised (see issue #10956).
1869 */
1870 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001871 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001872 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001873 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001874 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875 Py_DECREF(memobj);
1876 if (res == NULL)
1877 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001878 if (res == Py_None) {
1879 /* Non-blocking stream would have blocked. Special return code!
1880 Being paranoid we reset errno in case it is changed by code
1881 triggered by a decref. errno is used by _set_BlockingIOError(). */
1882 Py_DECREF(res);
1883 errno = errnum;
1884 return -2;
1885 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001886 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1887 Py_DECREF(res);
1888 if (n < 0 || n > len) {
1889 PyErr_Format(PyExc_IOError,
1890 "raw write() returned invalid length %zd "
1891 "(should have been between 0 and %zd)", n, len);
1892 return -1;
1893 }
1894 if (n > 0 && self->abs_pos != -1)
1895 self->abs_pos += n;
1896 return n;
1897}
1898
1899/* `restore_pos` is 1 if we need to restore the raw stream position at
1900 the end, 0 otherwise. */
1901static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001902_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001903{
1904 Py_ssize_t written = 0;
1905 Py_off_t n, rewind;
1906
1907 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1908 goto end;
1909 /* First, rewind */
1910 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1911 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001912 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913 if (n < 0) {
1914 goto error;
1915 }
1916 self->raw_pos -= rewind;
1917 }
1918 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001919 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001920 self->buffer + self->write_pos,
1921 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1922 Py_off_t, Py_ssize_t));
1923 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001924 goto error;
1925 }
1926 else if (n == -2) {
1927 _set_BlockingIOError("write could not complete without blocking",
1928 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929 goto error;
1930 }
1931 self->write_pos += n;
1932 self->raw_pos = self->write_pos;
1933 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001934 /* Partial writes can return successfully when interrupted by a
1935 signal (see write(2)). We must run signal handlers before
1936 blocking another time, possibly indefinitely. */
1937 if (PyErr_CheckSignals() < 0)
1938 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939 }
1940
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001941 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942
1943end:
1944 Py_RETURN_NONE;
1945
1946error:
1947 return NULL;
1948}
1949
1950static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952{
1953 PyObject *res = NULL;
1954 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001955 Py_ssize_t written, avail, remaining;
1956 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957
1958 CHECK_INITIALIZED(self)
1959 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1960 return NULL;
1961 }
1962
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001963 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 PyErr_SetString(PyExc_ValueError, "write to closed file");
1965 PyBuffer_Release(&buf);
1966 return NULL;
1967 }
1968
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001969 if (!ENTER_BUFFERED(self)) {
1970 PyBuffer_Release(&buf);
1971 return NULL;
1972 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973
1974 /* Fast path: the data to write can be fully buffered. */
1975 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1976 self->pos = 0;
1977 self->raw_pos = 0;
1978 }
1979 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1980 if (buf.len <= avail) {
1981 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001982 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983 self->write_pos = self->pos;
1984 }
1985 ADJUST_POSITION(self, self->pos + buf.len);
1986 if (self->pos > self->write_end)
1987 self->write_end = self->pos;
1988 written = buf.len;
1989 goto end;
1990 }
1991
1992 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001993 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001994 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001995 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 if (w == NULL)
1997 goto error;
1998 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001999 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000 /* Make some place by shifting the buffer. */
2001 assert(VALID_WRITE_BUFFER(self));
2002 memmove(self->buffer, self->buffer + self->write_pos,
2003 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2004 Py_off_t, Py_ssize_t));
2005 self->write_end -= self->write_pos;
2006 self->raw_pos -= self->write_pos;
2007 self->pos -= self->write_pos;
2008 self->write_pos = 0;
2009 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2010 Py_off_t, Py_ssize_t);
2011 if (buf.len <= avail) {
2012 /* Everything can be buffered */
2013 PyErr_Clear();
2014 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2015 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002016 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 written = buf.len;
2018 goto end;
2019 }
2020 /* Buffer as much as possible. */
2021 memcpy(self->buffer + self->write_end, buf.buf, avail);
2022 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002023 self->pos += avail;
2024 /* XXX Modifying the existing exception e using the pointer w
2025 will change e.characters_written but not e.args[2].
2026 Therefore we just replace with a new error. */
2027 _set_BlockingIOError("write could not complete without blocking",
2028 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 goto error;
2030 }
2031 Py_CLEAR(res);
2032
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002033 /* Adjust the raw stream position if it is away from the logical stream
2034 position. This happens if the read buffer has been filled but not
2035 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2036 the raw stream by itself).
2037 Fixes issue #6629.
2038 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002039 offset = RAW_OFFSET(self);
2040 if (offset != 0) {
2041 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002042 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002043 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002044 }
2045
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 /* Then write buf itself. At this point the buffer has been emptied. */
2047 remaining = buf.len;
2048 written = 0;
2049 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002050 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 self, (char *) buf.buf + written, buf.len - written);
2052 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002053 goto error;
2054 } else if (n == -2) {
2055 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 if (remaining > self->buffer_size) {
2057 /* Can't buffer everything, still buffer as much as possible */
2058 memcpy(self->buffer,
2059 (char *) buf.buf + written, self->buffer_size);
2060 self->raw_pos = 0;
2061 ADJUST_POSITION(self, self->buffer_size);
2062 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002063 written += self->buffer_size;
2064 _set_BlockingIOError("write could not complete without "
2065 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 goto error;
2067 }
2068 PyErr_Clear();
2069 break;
2070 }
2071 written += n;
2072 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002073 /* Partial writes can return successfully when interrupted by a
2074 signal (see write(2)). We must run signal handlers before
2075 blocking another time, possibly indefinitely. */
2076 if (PyErr_CheckSignals() < 0)
2077 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078 }
2079 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002080 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 if (remaining > 0) {
2082 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2083 written += remaining;
2084 }
2085 self->write_pos = 0;
2086 /* TODO: sanity check (remaining >= 0) */
2087 self->write_end = remaining;
2088 ADJUST_POSITION(self, remaining);
2089 self->raw_pos = 0;
2090
2091end:
2092 res = PyLong_FromSsize_t(written);
2093
2094error:
2095 LEAVE_BUFFERED(self)
2096 PyBuffer_Release(&buf);
2097 return res;
2098}
2099
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002102 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2103 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2104 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2105 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2106 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2107 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2108 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002109 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002110 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2113 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2114 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2115 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2116 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002117 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118 {NULL, NULL}
2119};
2120
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002122 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123 {NULL}
2124};
2125
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126static PyGetSetDef bufferedwriter_getset[] = {
2127 {"closed", (getter)buffered_closed_get, NULL, NULL},
2128 {"name", (getter)buffered_name_get, NULL, NULL},
2129 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002130 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131};
2132
2133
2134PyTypeObject PyBufferedWriter_Type = {
2135 PyVarObject_HEAD_INIT(NULL, 0)
2136 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002137 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140 0, /*tp_print*/
2141 0, /*tp_getattr*/
2142 0, /*tp_setattr*/
2143 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002144 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145 0, /*tp_as_number*/
2146 0, /*tp_as_sequence*/
2147 0, /*tp_as_mapping*/
2148 0, /*tp_hash */
2149 0, /*tp_call*/
2150 0, /*tp_str*/
2151 0, /*tp_getattro*/
2152 0, /*tp_setattro*/
2153 0, /*tp_as_buffer*/
2154 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2155 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002156 bufferedwriter_doc, /* tp_doc */
2157 (traverseproc)buffered_traverse, /* tp_traverse */
2158 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002160 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161 0, /* tp_iter */
2162 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002163 bufferedwriter_methods, /* tp_methods */
2164 bufferedwriter_members, /* tp_members */
2165 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 0, /* tp_base */
2167 0, /* tp_dict */
2168 0, /* tp_descr_get */
2169 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 offsetof(buffered, dict), /* tp_dictoffset */
2171 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172 0, /* tp_alloc */
2173 PyType_GenericNew, /* tp_new */
2174};
2175
2176
2177
2178/*
2179 * BufferedRWPair
2180 */
2181
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002182PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183 "A buffered reader and writer object together.\n"
2184 "\n"
2185 "A buffered reader object and buffered writer object put together to\n"
2186 "form a sequential IO object that can read and write. This is typically\n"
2187 "used with a socket or two-way pipe.\n"
2188 "\n"
2189 "reader and writer are RawIOBase objects that are readable and\n"
2190 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002191 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 );
2193
2194/* XXX The usefulness of this (compared to having two separate IO objects) is
2195 * questionable.
2196 */
2197
2198typedef struct {
2199 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002200 buffered *reader;
2201 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 PyObject *dict;
2203 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002204} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205
2206static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002207bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208{
2209 PyObject *reader, *writer;
2210 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211
Florent Xicluna109d5732012-07-07 17:03:22 +02002212 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2213 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214 return -1;
2215 }
2216
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002219 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220 return -1;
2221
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002223 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 if (self->reader == NULL)
2225 return -1;
2226
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002228 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 if (self->writer == NULL) {
2230 Py_CLEAR(self->reader);
2231 return -1;
2232 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002233
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234 return 0;
2235}
2236
2237static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002238bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239{
2240 Py_VISIT(self->dict);
2241 return 0;
2242}
2243
2244static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002245bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246{
2247 Py_CLEAR(self->reader);
2248 Py_CLEAR(self->writer);
2249 Py_CLEAR(self->dict);
2250 return 0;
2251}
2252
2253static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002254bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255{
2256 _PyObject_GC_UNTRACK(self);
2257 Py_CLEAR(self->reader);
2258 Py_CLEAR(self->writer);
2259 Py_CLEAR(self->dict);
2260 Py_TYPE(self)->tp_free((PyObject *) self);
2261}
2262
2263static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002264_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002266 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267 PyObject *ret;
2268
2269 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002270 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271 return NULL;
2272 }
2273
2274 ret = PyObject_CallObject(func, args);
2275 Py_DECREF(func);
2276 return ret;
2277}
2278
2279static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002280bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002282 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002283}
2284
2285static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002286bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002287{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002288 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289}
2290
2291static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002292bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002294 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002295}
2296
2297static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002298bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002299{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002300 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002301}
2302
2303static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002304bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002306 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307}
2308
2309static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002310bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002311{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002312 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313}
2314
2315static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002316bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002318 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319}
2320
2321static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002322bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002324 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002325}
2326
2327static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002328bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002330 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331 if (ret == NULL)
2332 return NULL;
2333 Py_DECREF(ret);
2334
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002335 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002336}
2337
2338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002340{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002341 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002342
2343 if (ret != Py_False) {
2344 /* either True or exception */
2345 return ret;
2346 }
2347 Py_DECREF(ret);
2348
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002349 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002350}
2351
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002352static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002353bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002354{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002355 if (self->writer == NULL) {
2356 PyErr_SetString(PyExc_RuntimeError,
2357 "the BufferedRWPair object is being garbage-collected");
2358 return NULL;
2359 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002360 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2361}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002362
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002363static PyMethodDef bufferedrwpair_methods[] = {
2364 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2365 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2366 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2367 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002368
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002369 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2370 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002372 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2373 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002374
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002375 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2376 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377
Antoine Pitrou243757e2010-11-05 21:15:39 +00002378 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2379
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002380 {NULL, NULL}
2381};
2382
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002383static PyGetSetDef bufferedrwpair_getset[] = {
2384 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002385 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002386};
2387
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388PyTypeObject PyBufferedRWPair_Type = {
2389 PyVarObject_HEAD_INIT(NULL, 0)
2390 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002391 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002392 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002393 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394 0, /*tp_print*/
2395 0, /*tp_getattr*/
2396 0, /*tp_setattr*/
2397 0, /*tp_compare */
2398 0, /*tp_repr*/
2399 0, /*tp_as_number*/
2400 0, /*tp_as_sequence*/
2401 0, /*tp_as_mapping*/
2402 0, /*tp_hash */
2403 0, /*tp_call*/
2404 0, /*tp_str*/
2405 0, /*tp_getattro*/
2406 0, /*tp_setattro*/
2407 0, /*tp_as_buffer*/
2408 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2409 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002410 bufferedrwpair_doc, /* tp_doc */
2411 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2412 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002413 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002414 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002415 0, /* tp_iter */
2416 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002417 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002419 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 0, /* tp_base */
2421 0, /* tp_dict */
2422 0, /* tp_descr_get */
2423 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002424 offsetof(rwpair, dict), /* tp_dictoffset */
2425 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426 0, /* tp_alloc */
2427 PyType_GenericNew, /* tp_new */
2428};
2429
2430
2431
2432/*
2433 * BufferedRandom
2434 */
2435
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002436PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002437 "A buffered interface to random access streams.\n"
2438 "\n"
2439 "The constructor creates a reader and writer for a seekable stream,\n"
2440 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002441 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442 );
2443
2444static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002445bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002446{
Florent Xicluna109d5732012-07-07 17:03:22 +02002447 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002448 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002449 PyObject *raw;
2450
2451 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002452 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453
R David Murray9f10f562013-02-23 22:07:55 -05002454 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002455 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 return -1;
2457 }
2458
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002460 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002461 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002462 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002463 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002464 return -1;
2465
2466 Py_CLEAR(self->raw);
2467 Py_INCREF(raw);
2468 self->raw = raw;
2469 self->buffer_size = buffer_size;
2470 self->readable = 1;
2471 self->writable = 1;
2472
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002473 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002474 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002475 _bufferedreader_reset_buf(self);
2476 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002477 self->pos = 0;
2478
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002479 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2480 Py_TYPE(raw) == &PyFileIO_Type);
2481
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002482 self->ok = 1;
2483 return 0;
2484}
2485
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002486static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002487 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002488 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2489 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2490 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2491 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2492 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2493 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2494 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002495 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002496 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002497
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002498 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002499
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002500 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2501 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2502 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2503 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2504 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2505 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2506 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2507 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2508 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002509 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002510 {NULL, NULL}
2511};
2512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002513static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002514 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002515 {NULL}
2516};
2517
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002518static PyGetSetDef bufferedrandom_getset[] = {
2519 {"closed", (getter)buffered_closed_get, NULL, NULL},
2520 {"name", (getter)buffered_name_get, NULL, NULL},
2521 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002522 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002523};
2524
2525
2526PyTypeObject PyBufferedRandom_Type = {
2527 PyVarObject_HEAD_INIT(NULL, 0)
2528 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002529 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002530 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002531 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 0, /*tp_print*/
2533 0, /*tp_getattr*/
2534 0, /*tp_setattr*/
2535 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 0, /*tp_as_number*/
2538 0, /*tp_as_sequence*/
2539 0, /*tp_as_mapping*/
2540 0, /*tp_hash */
2541 0, /*tp_call*/
2542 0, /*tp_str*/
2543 0, /*tp_getattro*/
2544 0, /*tp_setattro*/
2545 0, /*tp_as_buffer*/
2546 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2547 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002548 bufferedrandom_doc, /* tp_doc */
2549 (traverseproc)buffered_traverse, /* tp_traverse */
2550 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002551 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002552 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002553 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002554 (iternextfunc)buffered_iternext, /* tp_iternext */
2555 bufferedrandom_methods, /* tp_methods */
2556 bufferedrandom_members, /* tp_members */
2557 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002558 0, /* tp_base */
2559 0, /*tp_dict*/
2560 0, /* tp_descr_get */
2561 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002562 offsetof(buffered, dict), /*tp_dictoffset*/
2563 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002564 0, /* tp_alloc */
2565 PyType_GenericNew, /* tp_new */
2566};