blob: ad1aa48f213ee2c8a203739021d0c171a15f2271 [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020016_Py_IDENTIFIER(close);
17_Py_IDENTIFIER(_dealloc_warn);
18_Py_IDENTIFIER(flush);
19_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020020_Py_IDENTIFIER(mode);
21_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020022_Py_IDENTIFIER(peek);
23_Py_IDENTIFIER(read);
24_Py_IDENTIFIER(read1);
25_Py_IDENTIFIER(readable);
26_Py_IDENTIFIER(readinto);
27_Py_IDENTIFIER(writable);
28_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020029
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000030/*
31 * BufferedIOBase class, inherits from IOBase.
32 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000033PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034 "Base class for buffered IO objects.\n"
35 "\n"
36 "The main difference with RawIOBase is that the read() method\n"
37 "supports omitting the size argument, and does not have a default\n"
38 "implementation that defers to readinto().\n"
39 "\n"
40 "In addition, read(), readinto() and write() may raise\n"
41 "BlockingIOError if the underlying raw stream is in non-blocking\n"
42 "mode and not ready; unlike their raw counterparts, they will never\n"
43 "return None.\n"
44 "\n"
45 "A typical implementation should not inherit from a RawIOBase\n"
46 "implementation, but wrap one.\n"
47 );
48
49static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000050bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000051{
52 Py_buffer buf;
53 Py_ssize_t len;
54 PyObject *data;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020055 _Py_IDENTIFIER(read);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000056
57 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
58 return NULL;
59 }
60
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020061 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000062 if (data == NULL)
63 goto error;
64
65 if (!PyBytes_Check(data)) {
66 Py_DECREF(data);
67 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
68 goto error;
69 }
70
71 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030072 if (len > buf.len) {
73 PyErr_Format(PyExc_ValueError,
74 "read() returned too much data: "
75 "%zd bytes requested, %zd returned",
76 buf.len, len);
77 Py_DECREF(data);
78 goto error;
79 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
81
82 PyBuffer_Release(&buf);
83 Py_DECREF(data);
84
85 return PyLong_FromSsize_t(len);
86
87 error:
88 PyBuffer_Release(&buf);
89 return NULL;
90}
91
92static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000093bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094{
95 PyErr_SetString(IO_STATE->unsupported_operation, message);
96 return NULL;
97}
98
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000100 "Disconnect this buffer from its underlying raw stream and return it.\n"
101 "\n"
102 "After the raw stream has been detached, the buffer is in an unusable\n"
103 "state.\n");
104
105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000106bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000107{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000109}
110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000111PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000112 "Read and return up to n bytes.\n"
113 "\n"
114 "If the argument is omitted, None, or negative, reads and\n"
115 "returns all data until EOF.\n"
116 "\n"
117 "If the argument is positive, and the underlying raw stream is\n"
118 "not 'interactive', multiple raw reads may be issued to satisfy\n"
119 "the byte count (unless EOF is reached first). But for\n"
120 "interactive raw streams (as well as sockets and pipes), at most\n"
121 "one raw read will be issued, and a short result does not imply\n"
122 "that EOF is imminent.\n"
123 "\n"
124 "Returns an empty bytes object on EOF.\n"
125 "\n"
126 "Returns None if the underlying raw stream was open in non-blocking\n"
127 "mode and no data is available at the moment.\n");
128
129static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000130bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000131{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000132 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133}
134
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136 "Read and return up to n bytes, with at most one read() call\n"
137 "to the underlying raw stream. A short result does not imply\n"
138 "that EOF is imminent.\n"
139 "\n"
140 "Returns an empty bytes object on EOF.\n");
141
142static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000144{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000145 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000146}
147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149 "Write the given buffer to the IO stream.\n"
150 "\n"
151 "Returns the number of bytes written, which is never less than\n"
152 "len(b).\n"
153 "\n"
154 "Raises BlockingIOError if the buffer is full and the\n"
155 "underlying raw stream cannot accept more data at the moment.\n");
156
157static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000159{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000160 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000161}
162
163
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000164static PyMethodDef bufferediobase_methods[] = {
165 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
166 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
167 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
168 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
169 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000170 {NULL, NULL}
171};
172
173PyTypeObject PyBufferedIOBase_Type = {
174 PyVarObject_HEAD_INIT(NULL, 0)
175 "_io._BufferedIOBase", /*tp_name*/
176 0, /*tp_basicsize*/
177 0, /*tp_itemsize*/
178 0, /*tp_dealloc*/
179 0, /*tp_print*/
180 0, /*tp_getattr*/
181 0, /*tp_setattr*/
182 0, /*tp_compare */
183 0, /*tp_repr*/
184 0, /*tp_as_number*/
185 0, /*tp_as_sequence*/
186 0, /*tp_as_mapping*/
187 0, /*tp_hash */
188 0, /*tp_call*/
189 0, /*tp_str*/
190 0, /*tp_getattro*/
191 0, /*tp_setattro*/
192 0, /*tp_as_buffer*/
193 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 0, /* tp_traverse */
196 0, /* tp_clear */
197 0, /* tp_richcompare */
198 0, /* tp_weaklistoffset */
199 0, /* tp_iter */
200 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000201 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000202 0, /* tp_members */
203 0, /* tp_getset */
204 &PyIOBase_Type, /* tp_base */
205 0, /* tp_dict */
206 0, /* tp_descr_get */
207 0, /* tp_descr_set */
208 0, /* tp_dictoffset */
209 0, /* tp_init */
210 0, /* tp_alloc */
211 0, /* tp_new */
212};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000213
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000214
215typedef struct {
216 PyObject_HEAD
217
218 PyObject *raw;
219 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000220 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000221 int readable;
222 int writable;
Antoine Pitroue033e062010-10-29 10:38:18 +0000223 int deallocating;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200224
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000225 /* True if this is a vanilla Buffered object (rather than a user derived
226 class) *and* the raw stream is a vanilla FileIO object. */
227 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000228
229 /* Absolute position inside the raw stream (-1 if unknown). */
230 Py_off_t abs_pos;
231
232 /* A static buffer of size `buffer_size` */
233 char *buffer;
234 /* Current logical position in the buffer. */
235 Py_off_t pos;
236 /* Position of the raw stream in the buffer. */
237 Py_off_t raw_pos;
238
239 /* Just after the last buffered byte in the buffer, or -1 if the buffer
240 isn't ready for reading. */
241 Py_off_t read_end;
242
243 /* Just after the last byte actually written */
244 Py_off_t write_pos;
245 /* Just after the last byte waiting to be written, or -1 if the buffer
246 isn't ready for writing. */
247 Py_off_t write_end;
248
Georg Brandldfd73442009-04-05 11:47:34 +0000249#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000251 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000252#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000253
254 Py_ssize_t buffer_size;
255 Py_ssize_t buffer_mask;
256
257 PyObject *dict;
258 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000259} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260
261/*
262 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200263
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264 * BufferedReader, BufferedWriter and BufferedRandom try to share most
265 methods (this is helped by the members `readable` and `writable`, which
266 are initialized in the respective constructors)
267 * They also share a single buffer for reading and writing. This enables
268 interleaved reads and writes without flushing. It also makes the logic
269 a bit trickier to get right.
270 * The absolute position of the raw stream is cached, if possible, in the
271 `abs_pos` member. It must be updated every time an operation is done
272 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000273 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000274 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000275 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
276 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000277
278 NOTE: we should try to maintain block alignment of reads and writes to the
279 raw stream (according to the buffer size), but for now it is only done
280 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200281
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000282*/
283
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000284/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000285
Georg Brandldfd73442009-04-05 11:47:34 +0000286#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000287
288static int
289_enter_buffered_busy(buffered *self)
290{
291 if (self->owner == PyThread_get_thread_ident()) {
292 PyErr_Format(PyExc_RuntimeError,
293 "reentrant call inside %R", self);
294 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000295 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000296 Py_BEGIN_ALLOW_THREADS
297 PyThread_acquire_lock(self->lock, 1);
298 Py_END_ALLOW_THREADS
299 return 1;
300}
301
302#define ENTER_BUFFERED(self) \
303 ( (PyThread_acquire_lock(self->lock, 0) ? \
304 1 : _enter_buffered_busy(self)) \
305 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000306
307#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000308 do { \
309 self->owner = 0; \
310 PyThread_release_lock(self->lock); \
311 } while(0);
312
Georg Brandldfd73442009-04-05 11:47:34 +0000313#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000314#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000315#define LEAVE_BUFFERED(self)
316#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000317
318#define CHECK_INITIALIZED(self) \
319 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000320 if (self->detached) { \
321 PyErr_SetString(PyExc_ValueError, \
322 "raw stream has been detached"); \
323 } else { \
324 PyErr_SetString(PyExc_ValueError, \
325 "I/O operation on uninitialized object"); \
326 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000327 return NULL; \
328 }
329
330#define CHECK_INITIALIZED_INT(self) \
331 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000332 if (self->detached) { \
333 PyErr_SetString(PyExc_ValueError, \
334 "raw stream has been detached"); \
335 } else { \
336 PyErr_SetString(PyExc_ValueError, \
337 "I/O operation on uninitialized object"); \
338 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 return -1; \
340 }
341
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000342#define IS_CLOSED(self) \
343 (self->fast_closed_checks \
344 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000345 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000346
347#define CHECK_CLOSED(self, error_msg) \
348 if (IS_CLOSED(self)) { \
349 PyErr_SetString(PyExc_ValueError, error_msg); \
350 return NULL; \
351 }
352
353
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354#define VALID_READ_BUFFER(self) \
355 (self->readable && self->read_end != -1)
356
357#define VALID_WRITE_BUFFER(self) \
358 (self->writable && self->write_end != -1)
359
360#define ADJUST_POSITION(self, _new_pos) \
361 do { \
362 self->pos = _new_pos; \
363 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
364 self->read_end = self->pos; \
365 } while(0)
366
367#define READAHEAD(self) \
368 ((self->readable && VALID_READ_BUFFER(self)) \
369 ? (self->read_end - self->pos) : 0)
370
371#define RAW_OFFSET(self) \
372 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
373 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
374
375#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000376 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000377
378#define MINUS_LAST_BLOCK(self, size) \
379 (self->buffer_mask ? \
380 (size & ~self->buffer_mask) : \
381 (self->buffer_size * (size / self->buffer_size)))
382
383
384static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000385buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000386{
Antoine Pitroue033e062010-10-29 10:38:18 +0000387 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
389 return;
390 _PyObject_GC_UNTRACK(self);
391 self->ok = 0;
392 if (self->weakreflist != NULL)
393 PyObject_ClearWeakRefs((PyObject *)self);
394 Py_CLEAR(self->raw);
395 if (self->buffer) {
396 PyMem_Free(self->buffer);
397 self->buffer = NULL;
398 }
Georg Brandldfd73442009-04-05 11:47:34 +0000399#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000400 if (self->lock) {
401 PyThread_free_lock(self->lock);
402 self->lock = NULL;
403 }
Georg Brandldfd73442009-04-05 11:47:34 +0000404#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000405 Py_CLEAR(self->dict);
406 Py_TYPE(self)->tp_free((PyObject *)self);
407}
408
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200409static PyObject *
410buffered_sizeof(buffered *self, void *unused)
411{
412 Py_ssize_t res;
413
414 res = sizeof(buffered);
415 if (self->buffer)
416 res += self->buffer_size;
417 return PyLong_FromSsize_t(res);
418}
419
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000420static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000421buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422{
423 Py_VISIT(self->raw);
424 Py_VISIT(self->dict);
425 return 0;
426}
427
428static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000429buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000430{
431 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
432 return -1;
433 self->ok = 0;
434 Py_CLEAR(self->raw);
435 Py_CLEAR(self->dict);
436 return 0;
437}
438
Antoine Pitroue033e062010-10-29 10:38:18 +0000439/* Because this can call arbitrary code, it shouldn't be called when
440 the refcount is 0 (that is, not directly from tp_dealloc unless
441 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000442static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000443buffered_dealloc_warn(buffered *self, PyObject *source)
444{
445 if (self->ok && self->raw) {
446 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200447 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000448 if (r)
449 Py_DECREF(r);
450 else
451 PyErr_Clear();
452 }
453 Py_RETURN_NONE;
454}
455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456/*
457 * _BufferedIOMixin methods
458 * This is not a class, just a collection of methods that will be reused
459 * by BufferedReader and BufferedWriter
460 */
461
462/* Flush and close */
463
464static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000465buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466{
467 CHECK_INITIALIZED(self)
468 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
469}
470
471static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000472buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000473{
474 int closed;
475 PyObject *res;
476 CHECK_INITIALIZED_INT(self)
477 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
478 if (res == NULL)
479 return -1;
480 closed = PyObject_IsTrue(res);
481 Py_DECREF(res);
482 return closed;
483}
484
485static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000486buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487{
488 CHECK_INITIALIZED(self)
489 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
490}
491
492static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000493buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000494{
Benjamin Peterson68623612012-12-20 11:53:11 -0600495 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 int r;
497
498 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000499 if (!ENTER_BUFFERED(self))
500 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503 if (r < 0)
504 goto end;
505 if (r > 0) {
506 res = Py_None;
507 Py_INCREF(res);
508 goto end;
509 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000510
511 if (self->deallocating) {
512 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
513 if (r)
514 Py_DECREF(r);
515 else
516 PyErr_Clear();
517 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000518 /* flush() will most probably re-take the lock, so drop it first */
519 LEAVE_BUFFERED(self)
520 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000521 if (!ENTER_BUFFERED(self))
522 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600523 if (res == NULL)
524 PyErr_Fetch(&exc, &val, &tb);
525 else
526 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000527
528 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
529
Jesus Ceadc469452012-10-04 12:37:56 +0200530 if (self->buffer) {
531 PyMem_Free(self->buffer);
532 self->buffer = NULL;
533 }
534
Benjamin Peterson68623612012-12-20 11:53:11 -0600535 if (exc != NULL) {
536 if (res != NULL) {
537 Py_CLEAR(res);
538 PyErr_Restore(exc, val, tb);
539 }
540 else {
541 PyObject *val2;
542 Py_DECREF(exc);
543 Py_XDECREF(tb);
544 PyErr_Fetch(&exc, &val2, &tb);
545 PyErr_NormalizeException(&exc, &val2, &tb);
546 PyException_SetContext(val2, val);
547 PyErr_Restore(exc, val2, tb);
548 }
549 }
550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551end:
552 LEAVE_BUFFERED(self)
553 return res;
554}
555
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000556/* detach */
557
558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000560{
561 PyObject *raw, *res;
562 CHECK_INITIALIZED(self)
563 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
564 if (res == NULL)
565 return NULL;
566 Py_DECREF(res);
567 raw = self->raw;
568 self->raw = NULL;
569 self->detached = 1;
570 self->ok = 0;
571 return raw;
572}
573
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574/* Inquiries */
575
576static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000577buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578{
579 CHECK_INITIALIZED(self)
580 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
581}
582
583static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 CHECK_INITIALIZED(self)
587 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
588}
589
590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000591buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
594 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
595}
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200601 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200608 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609}
610
611/* Lower-level APIs */
612
613static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615{
616 CHECK_INITIALIZED(self)
617 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
618}
619
620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000621buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622{
623 CHECK_INITIALIZED(self)
624 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
625}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626
Antoine Pitrou243757e2010-11-05 21:15:39 +0000627/* Serialization */
628
629static PyObject *
630buffered_getstate(buffered *self, PyObject *args)
631{
632 PyErr_Format(PyExc_TypeError,
633 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
634 return NULL;
635}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000636
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637/* Forward decls */
638static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100639_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000645_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200647_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000650static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000652static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200654static Py_ssize_t
655_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
657/*
658 * Helpers
659 */
660
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100661/* Sets the current error to BlockingIOError */
662static void
663_set_BlockingIOError(char *msg, Py_ssize_t written)
664{
665 PyObject *err;
666 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
667 errno, msg, written);
668 if (err)
669 PyErr_SetObject(PyExc_BlockingIOError, err);
670 Py_XDECREF(err);
671}
672
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673/* Returns the address of the `written` member if a BlockingIOError was
674 raised, NULL otherwise. The error is always re-raised. */
675static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000676_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677{
678 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200679 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680
681 PyErr_Fetch(&t, &v, &tb);
682 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
683 PyErr_Restore(t, v, tb);
684 return NULL;
685 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200686 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000687 /* TODO: sanity check (err->written >= 0) */
688 PyErr_Restore(t, v, tb);
689 return &err->written;
690}
691
692static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000693_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000694{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000696 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000697 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
698 if (res == NULL)
699 return -1;
700 n = PyNumber_AsOff_t(res, PyExc_ValueError);
701 Py_DECREF(res);
702 if (n < 0) {
703 if (!PyErr_Occurred())
704 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000705 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200706 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707 return -1;
708 }
709 self->abs_pos = n;
710 return n;
711}
712
713static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000714_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715{
716 PyObject *res, *posobj, *whenceobj;
717 Py_off_t n;
718
719 posobj = PyLong_FromOff_t(target);
720 if (posobj == NULL)
721 return -1;
722 whenceobj = PyLong_FromLong(whence);
723 if (whenceobj == NULL) {
724 Py_DECREF(posobj);
725 return -1;
726 }
727 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
728 posobj, whenceobj, NULL);
729 Py_DECREF(posobj);
730 Py_DECREF(whenceobj);
731 if (res == NULL)
732 return -1;
733 n = PyNumber_AsOff_t(res, PyExc_ValueError);
734 Py_DECREF(res);
735 if (n < 0) {
736 if (!PyErr_Occurred())
737 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000738 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200739 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740 return -1;
741 }
742 self->abs_pos = n;
743 return n;
744}
745
746static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000747_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000748{
749 Py_ssize_t n;
750 if (self->buffer_size <= 0) {
751 PyErr_SetString(PyExc_ValueError,
752 "buffer size must be strictly positive");
753 return -1;
754 }
755 if (self->buffer)
756 PyMem_Free(self->buffer);
757 self->buffer = PyMem_Malloc(self->buffer_size);
758 if (self->buffer == NULL) {
759 PyErr_NoMemory();
760 return -1;
761 }
Georg Brandldfd73442009-04-05 11:47:34 +0000762#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000763 if (self->lock)
764 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000765 self->lock = PyThread_allocate_lock();
766 if (self->lock == NULL) {
767 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
768 return -1;
769 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000770 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000771#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000772 /* Find out whether buffer_size is a power of 2 */
773 /* XXX is this optimization useful? */
774 for (n = self->buffer_size - 1; n & 1; n >>= 1)
775 ;
776 if (n == 0)
777 self->buffer_mask = self->buffer_size - 1;
778 else
779 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000780 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000781 PyErr_Clear();
782 return 0;
783}
784
Antoine Pitrou707ce822011-02-25 21:24:11 +0000785/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
786 clears the error indicator), 0 otherwise.
787 Should only be called when PyErr_Occurred() is true.
788*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700789int
790_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000791{
792 static PyObject *eintr_int = NULL;
793 PyObject *typ, *val, *tb;
794 PyEnvironmentErrorObject *env_err;
795
796 if (eintr_int == NULL) {
797 eintr_int = PyLong_FromLong(EINTR);
798 assert(eintr_int != NULL);
799 }
800 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
801 return 0;
802 PyErr_Fetch(&typ, &val, &tb);
803 PyErr_NormalizeException(&typ, &val, &tb);
804 env_err = (PyEnvironmentErrorObject *) val;
805 assert(env_err != NULL);
806 if (env_err->myerrno != NULL &&
807 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
808 Py_DECREF(typ);
809 Py_DECREF(val);
810 Py_XDECREF(tb);
811 return 1;
812 }
813 /* This silences any error set by PyObject_RichCompareBool() */
814 PyErr_Restore(typ, val, tb);
815 return 0;
816}
817
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000818/*
819 * Shared methods and wrappers
820 */
821
822static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200823buffered_flush_and_rewind_unlocked(buffered *self)
824{
825 PyObject *res;
826
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100827 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200828 if (res == NULL)
829 return NULL;
830 Py_DECREF(res);
831
832 if (self->readable) {
833 /* Rewind the raw stream so that its position corresponds to
834 the current logical position. */
835 Py_off_t n;
836 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
837 _bufferedreader_reset_buf(self);
838 if (n == -1)
839 return NULL;
840 }
841 Py_RETURN_NONE;
842}
843
844static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000845buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000846{
847 PyObject *res;
848
849 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000850 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000852 if (!ENTER_BUFFERED(self))
853 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200854 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855 LEAVE_BUFFERED(self)
856
857 return res;
858}
859
860static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000861buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000862{
863 Py_ssize_t n = 0;
864 PyObject *res = NULL;
865
866 CHECK_INITIALIZED(self)
867 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
868 return NULL;
869 }
870
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000871 if (!ENTER_BUFFERED(self))
872 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000873
874 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200875 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876 if (res == NULL)
877 goto end;
878 Py_CLEAR(res);
879 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200880 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881
882end:
883 LEAVE_BUFFERED(self)
884 return res;
885}
886
887static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000888buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889{
890 Py_ssize_t n = -1;
891 PyObject *res;
892
893 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000894 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000895 return NULL;
896 }
897 if (n < -1) {
898 PyErr_SetString(PyExc_ValueError,
899 "read length must be positive or -1");
900 return NULL;
901 }
902
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000903 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000904
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000905 if (n == -1) {
906 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000907 if (!ENTER_BUFFERED(self))
908 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000909 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000910 }
911 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000912 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200913 if (res != Py_None)
914 return res;
915 Py_DECREF(res);
916 if (!ENTER_BUFFERED(self))
917 return NULL;
918 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000919 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920
Antoine Pitroue05565e2011-08-20 14:39:23 +0200921 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922 return res;
923}
924
925static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000926buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927{
928 Py_ssize_t n, have, r;
929 PyObject *res = NULL;
930
931 CHECK_INITIALIZED(self)
932 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
933 return NULL;
934 }
935
936 if (n < 0) {
937 PyErr_SetString(PyExc_ValueError,
938 "read length must be positive");
939 return NULL;
940 }
941 if (n == 0)
942 return PyBytes_FromStringAndSize(NULL, 0);
943
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000944 /* Return up to n bytes. If at least one byte is buffered, we
945 only return buffered bytes. Otherwise, we do one raw read. */
946
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
948 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100949 n = Py_MIN(have, n);
950 res = _bufferedreader_read_fast(self, n);
951 assert(res != Py_None);
952 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 res = PyBytes_FromStringAndSize(NULL, n);
955 if (res == NULL)
956 return NULL;
957 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200958 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100959 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200960 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000961 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100962 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
963 LEAVE_BUFFERED(self)
964 if (r == -1) {
965 Py_DECREF(res);
966 return NULL;
967 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 if (r == -2)
969 r = 0;
970 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100971 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 return res;
973}
974
975static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000976buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000977{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200978 Py_buffer buf;
979 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 PyObject *res = NULL;
981
982 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983
984 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
985 return NULL;
986
987 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
988 if (n > 0) {
989 if (n >= buf.len) {
990 memcpy(buf.buf, self->buffer + self->pos, buf.len);
991 self->pos += buf.len;
992 res = PyLong_FromSsize_t(buf.len);
993 goto end_unlocked;
994 }
995 memcpy(buf.buf, self->buffer + self->pos, n);
996 self->pos += n;
997 written = n;
998 }
999
1000 if (!ENTER_BUFFERED(self))
1001 goto end_unlocked;
1002
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001004 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001005 if (res == NULL)
1006 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001007 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001008 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001009
1010 _bufferedreader_reset_buf(self);
1011 self->pos = 0;
1012
1013 for (remaining = buf.len - written;
1014 remaining > 0;
1015 written += n, remaining -= n) {
1016 /* If remaining bytes is larger than internal buffer size, copy
1017 * directly into caller's buffer. */
1018 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001019 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1020 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 }
1022 else {
1023 n = _bufferedreader_fill_buffer(self);
1024 if (n > 0) {
1025 if (n > remaining)
1026 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001027 memcpy((char *) buf.buf + written,
1028 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001029 self->pos += n;
1030 continue; /* short circuit */
1031 }
1032 }
1033 if (n == 0 || (n == -2 && written > 0))
1034 break;
1035 if (n < 0) {
1036 if (n == -2) {
1037 Py_INCREF(Py_None);
1038 res = Py_None;
1039 }
1040 goto end;
1041 }
1042 }
1043 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044
1045end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001046 LEAVE_BUFFERED(self);
1047end_unlocked:
1048 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049 return res;
1050}
1051
1052static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001053_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001054{
1055 PyObject *res = NULL;
1056 PyObject *chunks = NULL;
1057 Py_ssize_t n, written = 0;
1058 const char *start, *s, *end;
1059
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001060 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001061
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001062 /* First, try to find a line in the buffer. This can run unlocked because
1063 the calls to the C API are simple enough that they can't trigger
1064 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1066 if (limit >= 0 && n > limit)
1067 n = limit;
1068 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001069 s = memchr(start, '\n', n);
1070 if (s != NULL) {
1071 res = PyBytes_FromStringAndSize(start, s - start + 1);
1072 if (res != NULL)
1073 self->pos += s - start + 1;
1074 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075 }
1076 if (n == limit) {
1077 res = PyBytes_FromStringAndSize(start, n);
1078 if (res != NULL)
1079 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001080 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081 }
1082
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001083 if (!ENTER_BUFFERED(self))
1084 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001085
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001086 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001087 chunks = PyList_New(0);
1088 if (chunks == NULL)
1089 goto end;
1090 if (n > 0) {
1091 res = PyBytes_FromStringAndSize(start, n);
1092 if (res == NULL)
1093 goto end;
1094 if (PyList_Append(chunks, res) < 0) {
1095 Py_CLEAR(res);
1096 goto end;
1097 }
1098 Py_CLEAR(res);
1099 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001100 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 if (limit >= 0)
1102 limit -= n;
1103 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001104 if (self->writable) {
1105 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1106 if (r == NULL)
1107 goto end;
1108 Py_DECREF(r);
1109 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001110
1111 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001112 _bufferedreader_reset_buf(self);
1113 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001114 if (n == -1)
1115 goto end;
1116 if (n <= 0)
1117 break;
1118 if (limit >= 0 && n > limit)
1119 n = limit;
1120 start = self->buffer;
1121 end = start + n;
1122 s = start;
1123 while (s < end) {
1124 if (*s++ == '\n') {
1125 res = PyBytes_FromStringAndSize(start, s - start);
1126 if (res == NULL)
1127 goto end;
1128 self->pos = s - start;
1129 goto found;
1130 }
1131 }
1132 res = PyBytes_FromStringAndSize(start, n);
1133 if (res == NULL)
1134 goto end;
1135 if (n == limit) {
1136 self->pos = n;
1137 break;
1138 }
1139 if (PyList_Append(chunks, res) < 0) {
1140 Py_CLEAR(res);
1141 goto end;
1142 }
1143 Py_CLEAR(res);
1144 written += n;
1145 if (limit >= 0)
1146 limit -= n;
1147 }
1148found:
1149 if (res != NULL && PyList_Append(chunks, res) < 0) {
1150 Py_CLEAR(res);
1151 goto end;
1152 }
1153 Py_CLEAR(res);
1154 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1155
1156end:
1157 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001158end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001159 Py_XDECREF(chunks);
1160 return res;
1161}
1162
1163static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001164buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001165{
1166 Py_ssize_t limit = -1;
1167
1168 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001169 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001170 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001171 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172}
1173
1174
1175static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001176buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177{
1178 Py_off_t pos;
1179
1180 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001181 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001182 if (pos == -1)
1183 return NULL;
1184 pos -= RAW_OFFSET(self);
1185 /* TODO: sanity check (pos >= 0) */
1186 return PyLong_FromOff_t(pos);
1187}
1188
1189static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001190buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001191{
1192 Py_off_t target, n;
1193 int whence = 0;
1194 PyObject *targetobj, *res = NULL;
1195
1196 CHECK_INITIALIZED(self)
1197 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1198 return NULL;
1199 }
Jesus Cea94363612012-06-22 18:32:07 +02001200
1201 /* Do some error checking instead of trusting OS 'seek()'
1202 ** error detection, just in case.
1203 */
1204 if ((whence < 0 || whence >2)
1205#ifdef SEEK_HOLE
1206 && (whence != SEEK_HOLE)
1207#endif
1208#ifdef SEEK_DATA
1209 && (whence != SEEK_DATA)
1210#endif
1211 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001212 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001213 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001214 return NULL;
1215 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001216
1217 CHECK_CLOSED(self, "seek of closed file")
1218
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001219 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1220 return NULL;
1221
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1223 if (target == -1 && PyErr_Occurred())
1224 return NULL;
1225
Jesus Cea94363612012-06-22 18:32:07 +02001226 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1227 buffer. Other whence values must be managed without this optimization.
1228 Some Operating Systems can provide additional values, like
1229 SEEK_HOLE/SEEK_DATA. */
1230 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231 Py_off_t current, avail;
1232 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001233 so as to return quickly if possible. Also, we needn't take the
1234 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001235 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001236 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1237 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238 current = RAW_TELL(self);
1239 avail = READAHEAD(self);
1240 if (avail > 0) {
1241 Py_off_t offset;
1242 if (whence == 0)
1243 offset = target - (current - RAW_OFFSET(self));
1244 else
1245 offset = target;
1246 if (offset >= -self->pos && offset <= avail) {
1247 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001248 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249 }
1250 }
1251 }
1252
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001253 if (!ENTER_BUFFERED(self))
1254 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001255
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 /* Fallback: invoke raw seek() method and clear buffer */
1257 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001258 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001259 if (res == NULL)
1260 goto end;
1261 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001262 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 }
1264
1265 /* TODO: align on block boundary and read buffer if needed? */
1266 if (whence == 1)
1267 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001268 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001269 if (n == -1)
1270 goto end;
1271 self->raw_pos = -1;
1272 res = PyLong_FromOff_t(n);
1273 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001274 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275
1276end:
1277 LEAVE_BUFFERED(self)
1278 return res;
1279}
1280
1281static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001282buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283{
1284 PyObject *pos = Py_None;
1285 PyObject *res = NULL;
1286
1287 CHECK_INITIALIZED(self)
1288 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1289 return NULL;
1290 }
1291
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001292 if (!ENTER_BUFFERED(self))
1293 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001294
1295 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001296 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001297 if (res == NULL)
1298 goto end;
1299 Py_CLEAR(res);
1300 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1302 if (res == NULL)
1303 goto end;
1304 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001305 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001306 PyErr_Clear();
1307
1308end:
1309 LEAVE_BUFFERED(self)
1310 return res;
1311}
1312
1313static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001314buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001315{
1316 PyObject *line;
1317 PyTypeObject *tp;
1318
1319 CHECK_INITIALIZED(self);
1320
1321 tp = Py_TYPE(self);
1322 if (tp == &PyBufferedReader_Type ||
1323 tp == &PyBufferedRandom_Type) {
1324 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001325 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001326 }
1327 else {
1328 line = PyObject_CallMethodObjArgs((PyObject *)self,
1329 _PyIO_str_readline, NULL);
1330 if (line && !PyBytes_Check(line)) {
1331 PyErr_Format(PyExc_IOError,
1332 "readline() should have returned a bytes object, "
1333 "not '%.200s'", Py_TYPE(line)->tp_name);
1334 Py_DECREF(line);
1335 return NULL;
1336 }
1337 }
1338
1339 if (line == NULL)
1340 return NULL;
1341
1342 if (PyBytes_GET_SIZE(line) == 0) {
1343 /* Reached EOF or would have blocked */
1344 Py_DECREF(line);
1345 return NULL;
1346 }
1347
1348 return line;
1349}
1350
Antoine Pitrou716c4442009-05-23 19:04:03 +00001351static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001352buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001353{
1354 PyObject *nameobj, *res;
1355
Martin v. Löwis767046a2011-10-14 15:35:36 +02001356 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001357 if (nameobj == NULL) {
1358 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1359 PyErr_Clear();
1360 else
1361 return NULL;
1362 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1363 }
1364 else {
1365 res = PyUnicode_FromFormat("<%s name=%R>",
1366 Py_TYPE(self)->tp_name, nameobj);
1367 Py_DECREF(nameobj);
1368 }
1369 return res;
1370}
1371
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372/*
1373 * class BufferedReader
1374 */
1375
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001376PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001377 "Create a new buffered reader using the given readable raw IO object.");
1378
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001379static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001380{
1381 self->read_end = -1;
1382}
1383
1384static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001385bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001386{
1387 char *kwlist[] = {"raw", "buffer_size", NULL};
1388 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1389 PyObject *raw;
1390
1391 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001392 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393
1394 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1395 &raw, &buffer_size)) {
1396 return -1;
1397 }
1398
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001399 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001400 return -1;
1401
1402 Py_CLEAR(self->raw);
1403 Py_INCREF(raw);
1404 self->raw = raw;
1405 self->buffer_size = buffer_size;
1406 self->readable = 1;
1407 self->writable = 0;
1408
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001409 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001410 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001411 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001412
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001413 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1414 Py_TYPE(raw) == &PyFileIO_Type);
1415
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416 self->ok = 1;
1417 return 0;
1418}
1419
1420static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001421_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001422{
1423 Py_buffer buf;
1424 PyObject *memobj, *res;
1425 Py_ssize_t n;
1426 /* NOTE: the buffer needn't be released as its object is NULL. */
1427 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1428 return -1;
1429 memobj = PyMemoryView_FromBuffer(&buf);
1430 if (memobj == NULL)
1431 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001432 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1433 occurs so we needn't do it ourselves.
1434 We then retry reading, ignoring the signal if no handler has
1435 raised (see issue #10956).
1436 */
1437 do {
1438 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001439 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440 Py_DECREF(memobj);
1441 if (res == NULL)
1442 return -1;
1443 if (res == Py_None) {
1444 /* Non-blocking stream would have blocked. Special return code! */
1445 Py_DECREF(res);
1446 return -2;
1447 }
1448 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1449 Py_DECREF(res);
1450 if (n < 0 || n > len) {
1451 PyErr_Format(PyExc_IOError,
1452 "raw readinto() returned invalid length %zd "
1453 "(should have been between 0 and %zd)", n, len);
1454 return -1;
1455 }
1456 if (n > 0 && self->abs_pos != -1)
1457 self->abs_pos += n;
1458 return n;
1459}
1460
1461static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001462_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463{
1464 Py_ssize_t start, len, n;
1465 if (VALID_READ_BUFFER(self))
1466 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1467 else
1468 start = 0;
1469 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001470 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471 if (n <= 0)
1472 return n;
1473 self->read_end = start + n;
1474 self->raw_pos = start + n;
1475 return n;
1476}
1477
1478static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001479_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001480{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001481 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001482 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001483
1484 /* First copy what we have in the current buffer. */
1485 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1486 if (current_size) {
1487 data = PyBytes_FromStringAndSize(
1488 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001489 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001490 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001491 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001492 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001493 /* We're going past the buffer's bounds, flush it */
1494 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001495 tmp = buffered_flush_and_rewind_unlocked(self);
1496 if (tmp == NULL)
1497 goto cleanup;
1498 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001499 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001500 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001501
1502 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001503 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1504 if (tmp == NULL)
1505 goto cleanup;
1506 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001507 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001508 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001509 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001510 if (tmp == Py_None) {
1511 if (current_size == 0) {
1512 res = Py_None;
1513 goto cleanup;
1514 } else {
1515 res = data;
1516 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001517 }
1518 }
1519 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001520 PyBytes_Concat(&data, tmp);
1521 res = data;
1522 goto cleanup;
1523 }
1524 else {
1525 res = tmp;
1526 goto cleanup;
1527 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001528 }
1529
1530 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001531 if (chunks == NULL)
1532 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001533
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001534 while (1) {
1535 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001536 if (PyList_Append(chunks, data) < 0)
1537 goto cleanup;
1538 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001539 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001540
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001541 /* Read until EOF or until read() would block. */
1542 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001543 if (data == NULL)
1544 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001545 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001546 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001547 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001548 }
1549 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1550 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001551 res = data;
1552 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001553 }
1554 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001555 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1556 res = tmp;
1557 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001558 }
1559 }
1560 current_size += PyBytes_GET_SIZE(data);
1561 if (self->abs_pos != -1)
1562 self->abs_pos += PyBytes_GET_SIZE(data);
1563 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001564cleanup:
1565 /* res is either NULL or a borrowed ref */
1566 Py_XINCREF(res);
1567 Py_XDECREF(data);
1568 Py_XDECREF(tmp);
1569 Py_XDECREF(chunks);
1570 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001571}
1572
1573/* Read n bytes from the buffer if it can, otherwise return None.
1574 This function is simple enough that it can run unlocked. */
1575static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001576_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001577{
1578 Py_ssize_t current_size;
1579
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001580 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1581 if (n <= current_size) {
1582 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1584 if (res != NULL)
1585 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001586 return res;
1587 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001588 Py_RETURN_NONE;
1589}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001590
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591/* Generic read function: read from the stream until enough bytes are read,
1592 * or until an EOF occurs or until read() would block.
1593 */
1594static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001595_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001596{
1597 PyObject *res = NULL;
1598 Py_ssize_t current_size, remaining, written;
1599 char *out;
1600
1601 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1602 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001603 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001604
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001605 res = PyBytes_FromStringAndSize(NULL, n);
1606 if (res == NULL)
1607 goto error;
1608 out = PyBytes_AS_STRING(res);
1609 remaining = n;
1610 written = 0;
1611 if (current_size > 0) {
1612 memcpy(out, self->buffer + self->pos, current_size);
1613 remaining -= current_size;
1614 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001615 self->pos += current_size;
1616 }
1617 /* Flush the write buffer if necessary */
1618 if (self->writable) {
1619 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1620 if (r == NULL)
1621 goto error;
1622 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001623 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001624 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001625 while (remaining > 0) {
1626 /* We want to read a whole block at the end into buffer.
1627 If we had readv() we could do this in one pass. */
1628 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1629 if (r == 0)
1630 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001631 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001632 if (r == -1)
1633 goto error;
1634 if (r == 0 || r == -2) {
1635 /* EOF occurred or read() would block. */
1636 if (r == 0 || written > 0) {
1637 if (_PyBytes_Resize(&res, written))
1638 goto error;
1639 return res;
1640 }
1641 Py_DECREF(res);
1642 Py_INCREF(Py_None);
1643 return Py_None;
1644 }
1645 remaining -= r;
1646 written += r;
1647 }
1648 assert(remaining <= self->buffer_size);
1649 self->pos = 0;
1650 self->raw_pos = 0;
1651 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001652 /* NOTE: when the read is satisfied, we avoid issuing any additional
1653 reads, which could block indefinitely (e.g. on a socket).
1654 See issue #9550. */
1655 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001656 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001657 if (r == -1)
1658 goto error;
1659 if (r == 0 || r == -2) {
1660 /* EOF occurred or read() would block. */
1661 if (r == 0 || written > 0) {
1662 if (_PyBytes_Resize(&res, written))
1663 goto error;
1664 return res;
1665 }
1666 Py_DECREF(res);
1667 Py_INCREF(Py_None);
1668 return Py_None;
1669 }
1670 if (remaining > r) {
1671 memcpy(out + written, self->buffer + self->pos, r);
1672 written += r;
1673 self->pos += r;
1674 remaining -= r;
1675 }
1676 else if (remaining > 0) {
1677 memcpy(out + written, self->buffer + self->pos, remaining);
1678 written += remaining;
1679 self->pos += remaining;
1680 remaining = 0;
1681 }
1682 if (remaining == 0)
1683 break;
1684 }
1685
1686 return res;
1687
1688error:
1689 Py_XDECREF(res);
1690 return NULL;
1691}
1692
1693static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001694_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001695{
1696 Py_ssize_t have, r;
1697
1698 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1699 /* Constraints:
1700 1. we don't want to advance the file position.
1701 2. we don't want to lose block alignment, so we can't shift the buffer
1702 to make some place.
1703 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1704 */
1705 if (have > 0) {
1706 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1707 }
1708
1709 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001710 _bufferedreader_reset_buf(self);
1711 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001712 if (r == -1)
1713 return NULL;
1714 if (r == -2)
1715 r = 0;
1716 self->pos = 0;
1717 return PyBytes_FromStringAndSize(self->buffer, r);
1718}
1719
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001720static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001721 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001722 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1723 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1724 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1725 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1726 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1727 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1728 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1729 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001730 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001731 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001732
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001733 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1734 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1735 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001736 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001737 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1738 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1739 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1740 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001741 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001742 {NULL, NULL}
1743};
1744
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001745static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001746 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001747 {NULL}
1748};
1749
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001750static PyGetSetDef bufferedreader_getset[] = {
1751 {"closed", (getter)buffered_closed_get, NULL, NULL},
1752 {"name", (getter)buffered_name_get, NULL, NULL},
1753 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001754 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001755};
1756
1757
1758PyTypeObject PyBufferedReader_Type = {
1759 PyVarObject_HEAD_INIT(NULL, 0)
1760 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001761 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001763 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 0, /*tp_print*/
1765 0, /*tp_getattr*/
1766 0, /*tp_setattr*/
1767 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001768 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769 0, /*tp_as_number*/
1770 0, /*tp_as_sequence*/
1771 0, /*tp_as_mapping*/
1772 0, /*tp_hash */
1773 0, /*tp_call*/
1774 0, /*tp_str*/
1775 0, /*tp_getattro*/
1776 0, /*tp_setattro*/
1777 0, /*tp_as_buffer*/
1778 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1779 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001780 bufferedreader_doc, /* tp_doc */
1781 (traverseproc)buffered_traverse, /* tp_traverse */
1782 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001786 (iternextfunc)buffered_iternext, /* tp_iternext */
1787 bufferedreader_methods, /* tp_methods */
1788 bufferedreader_members, /* tp_members */
1789 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 0, /* tp_base */
1791 0, /* tp_dict */
1792 0, /* tp_descr_get */
1793 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001794 offsetof(buffered, dict), /* tp_dictoffset */
1795 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001796 0, /* tp_alloc */
1797 PyType_GenericNew, /* tp_new */
1798};
1799
1800
Benjamin Peterson59406a92009-03-26 17:10:29 +00001801
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802/*
1803 * class BufferedWriter
1804 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001805PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 "A buffer for a writeable sequential RawIO object.\n"
1807 "\n"
1808 "The constructor creates a BufferedWriter for the given writeable raw\n"
1809 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001810 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 );
1812
1813static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001814_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815{
1816 self->write_pos = 0;
1817 self->write_end = -1;
1818}
1819
1820static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001821bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822{
Florent Xicluna109d5732012-07-07 17:03:22 +02001823 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001824 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 PyObject *raw;
1826
1827 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001828 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001829
R David Murray9f10f562013-02-23 22:07:55 -05001830 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001831 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832 return -1;
1833 }
1834
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001835 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 return -1;
1837
1838 Py_CLEAR(self->raw);
1839 Py_INCREF(raw);
1840 self->raw = raw;
1841 self->readable = 0;
1842 self->writable = 1;
1843
1844 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001845 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001847 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848 self->pos = 0;
1849
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001850 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1851 Py_TYPE(raw) == &PyFileIO_Type);
1852
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853 self->ok = 1;
1854 return 0;
1855}
1856
1857static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001858_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859{
1860 Py_buffer buf;
1861 PyObject *memobj, *res;
1862 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001863 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864 /* NOTE: the buffer needn't be released as its object is NULL. */
1865 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1866 return -1;
1867 memobj = PyMemoryView_FromBuffer(&buf);
1868 if (memobj == NULL)
1869 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001870 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1871 occurs so we needn't do it ourselves.
1872 We then retry writing, ignoring the signal if no handler has
1873 raised (see issue #10956).
1874 */
1875 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001876 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001877 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001878 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001879 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880 Py_DECREF(memobj);
1881 if (res == NULL)
1882 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001883 if (res == Py_None) {
1884 /* Non-blocking stream would have blocked. Special return code!
1885 Being paranoid we reset errno in case it is changed by code
1886 triggered by a decref. errno is used by _set_BlockingIOError(). */
1887 Py_DECREF(res);
1888 errno = errnum;
1889 return -2;
1890 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001891 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1892 Py_DECREF(res);
1893 if (n < 0 || n > len) {
1894 PyErr_Format(PyExc_IOError,
1895 "raw write() returned invalid length %zd "
1896 "(should have been between 0 and %zd)", n, len);
1897 return -1;
1898 }
1899 if (n > 0 && self->abs_pos != -1)
1900 self->abs_pos += n;
1901 return n;
1902}
1903
1904/* `restore_pos` is 1 if we need to restore the raw stream position at
1905 the end, 0 otherwise. */
1906static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001907_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908{
1909 Py_ssize_t written = 0;
1910 Py_off_t n, rewind;
1911
1912 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1913 goto end;
1914 /* First, rewind */
1915 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1916 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001917 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918 if (n < 0) {
1919 goto error;
1920 }
1921 self->raw_pos -= rewind;
1922 }
1923 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001924 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001925 self->buffer + self->write_pos,
1926 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1927 Py_off_t, Py_ssize_t));
1928 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001929 goto error;
1930 }
1931 else if (n == -2) {
1932 _set_BlockingIOError("write could not complete without blocking",
1933 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934 goto error;
1935 }
1936 self->write_pos += n;
1937 self->raw_pos = self->write_pos;
1938 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001939 /* Partial writes can return successfully when interrupted by a
1940 signal (see write(2)). We must run signal handlers before
1941 blocking another time, possibly indefinitely. */
1942 if (PyErr_CheckSignals() < 0)
1943 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 }
1945
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001946 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947
1948end:
1949 Py_RETURN_NONE;
1950
1951error:
1952 return NULL;
1953}
1954
1955static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001956bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957{
1958 PyObject *res = NULL;
1959 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001960 Py_ssize_t written, avail, remaining;
1961 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001962
1963 CHECK_INITIALIZED(self)
1964 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1965 return NULL;
1966 }
1967
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001968 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969 PyErr_SetString(PyExc_ValueError, "write to closed file");
1970 PyBuffer_Release(&buf);
1971 return NULL;
1972 }
1973
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001974 if (!ENTER_BUFFERED(self)) {
1975 PyBuffer_Release(&buf);
1976 return NULL;
1977 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978
1979 /* Fast path: the data to write can be fully buffered. */
1980 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1981 self->pos = 0;
1982 self->raw_pos = 0;
1983 }
1984 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1985 if (buf.len <= avail) {
1986 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001987 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988 self->write_pos = self->pos;
1989 }
1990 ADJUST_POSITION(self, self->pos + buf.len);
1991 if (self->pos > self->write_end)
1992 self->write_end = self->pos;
1993 written = buf.len;
1994 goto end;
1995 }
1996
1997 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001998 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002000 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 if (w == NULL)
2002 goto error;
2003 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002004 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002005 /* Make some place by shifting the buffer. */
2006 assert(VALID_WRITE_BUFFER(self));
2007 memmove(self->buffer, self->buffer + self->write_pos,
2008 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2009 Py_off_t, Py_ssize_t));
2010 self->write_end -= self->write_pos;
2011 self->raw_pos -= self->write_pos;
2012 self->pos -= self->write_pos;
2013 self->write_pos = 0;
2014 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2015 Py_off_t, Py_ssize_t);
2016 if (buf.len <= avail) {
2017 /* Everything can be buffered */
2018 PyErr_Clear();
2019 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2020 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002021 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022 written = buf.len;
2023 goto end;
2024 }
2025 /* Buffer as much as possible. */
2026 memcpy(self->buffer + self->write_end, buf.buf, avail);
2027 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002028 self->pos += avail;
2029 /* XXX Modifying the existing exception e using the pointer w
2030 will change e.characters_written but not e.args[2].
2031 Therefore we just replace with a new error. */
2032 _set_BlockingIOError("write could not complete without blocking",
2033 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002034 goto error;
2035 }
2036 Py_CLEAR(res);
2037
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002038 /* Adjust the raw stream position if it is away from the logical stream
2039 position. This happens if the read buffer has been filled but not
2040 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2041 the raw stream by itself).
2042 Fixes issue #6629.
2043 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002044 offset = RAW_OFFSET(self);
2045 if (offset != 0) {
2046 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002047 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002048 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002049 }
2050
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 /* Then write buf itself. At this point the buffer has been emptied. */
2052 remaining = buf.len;
2053 written = 0;
2054 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002055 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 self, (char *) buf.buf + written, buf.len - written);
2057 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002058 goto error;
2059 } else if (n == -2) {
2060 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 if (remaining > self->buffer_size) {
2062 /* Can't buffer everything, still buffer as much as possible */
2063 memcpy(self->buffer,
2064 (char *) buf.buf + written, self->buffer_size);
2065 self->raw_pos = 0;
2066 ADJUST_POSITION(self, self->buffer_size);
2067 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002068 written += self->buffer_size;
2069 _set_BlockingIOError("write could not complete without "
2070 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071 goto error;
2072 }
2073 PyErr_Clear();
2074 break;
2075 }
2076 written += n;
2077 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002078 /* Partial writes can return successfully when interrupted by a
2079 signal (see write(2)). We must run signal handlers before
2080 blocking another time, possibly indefinitely. */
2081 if (PyErr_CheckSignals() < 0)
2082 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083 }
2084 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002085 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086 if (remaining > 0) {
2087 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2088 written += remaining;
2089 }
2090 self->write_pos = 0;
2091 /* TODO: sanity check (remaining >= 0) */
2092 self->write_end = remaining;
2093 ADJUST_POSITION(self, remaining);
2094 self->raw_pos = 0;
2095
2096end:
2097 res = PyLong_FromSsize_t(written);
2098
2099error:
2100 LEAVE_BUFFERED(self)
2101 PyBuffer_Release(&buf);
2102 return res;
2103}
2104
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002107 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2108 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2109 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2110 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2111 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2112 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2113 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002114 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002115 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002116
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002117 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2118 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2119 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2120 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2121 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002122 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123 {NULL, NULL}
2124};
2125
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002127 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128 {NULL}
2129};
2130
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131static PyGetSetDef bufferedwriter_getset[] = {
2132 {"closed", (getter)buffered_closed_get, NULL, NULL},
2133 {"name", (getter)buffered_name_get, NULL, NULL},
2134 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002135 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002136};
2137
2138
2139PyTypeObject PyBufferedWriter_Type = {
2140 PyVarObject_HEAD_INIT(NULL, 0)
2141 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002142 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002144 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145 0, /*tp_print*/
2146 0, /*tp_getattr*/
2147 0, /*tp_setattr*/
2148 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002149 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150 0, /*tp_as_number*/
2151 0, /*tp_as_sequence*/
2152 0, /*tp_as_mapping*/
2153 0, /*tp_hash */
2154 0, /*tp_call*/
2155 0, /*tp_str*/
2156 0, /*tp_getattro*/
2157 0, /*tp_setattro*/
2158 0, /*tp_as_buffer*/
2159 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2160 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002161 bufferedwriter_doc, /* tp_doc */
2162 (traverseproc)buffered_traverse, /* tp_traverse */
2163 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002164 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 0, /* tp_iter */
2167 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168 bufferedwriter_methods, /* tp_methods */
2169 bufferedwriter_members, /* tp_members */
2170 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 0, /* tp_base */
2172 0, /* tp_dict */
2173 0, /* tp_descr_get */
2174 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002175 offsetof(buffered, dict), /* tp_dictoffset */
2176 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177 0, /* tp_alloc */
2178 PyType_GenericNew, /* tp_new */
2179};
2180
2181
2182
2183/*
2184 * BufferedRWPair
2185 */
2186
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188 "A buffered reader and writer object together.\n"
2189 "\n"
2190 "A buffered reader object and buffered writer object put together to\n"
2191 "form a sequential IO object that can read and write. This is typically\n"
2192 "used with a socket or two-way pipe.\n"
2193 "\n"
2194 "reader and writer are RawIOBase objects that are readable and\n"
2195 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002196 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 );
2198
2199/* XXX The usefulness of this (compared to having two separate IO objects) is
2200 * questionable.
2201 */
2202
2203typedef struct {
2204 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002205 buffered *reader;
2206 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207 PyObject *dict;
2208 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002209} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210
2211static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002212bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213{
2214 PyObject *reader, *writer;
2215 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216
Florent Xicluna109d5732012-07-07 17:03:22 +02002217 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2218 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219 return -1;
2220 }
2221
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225 return -1;
2226
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002228 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 if (self->reader == NULL)
2230 return -1;
2231
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002232 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002233 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234 if (self->writer == NULL) {
2235 Py_CLEAR(self->reader);
2236 return -1;
2237 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002238
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239 return 0;
2240}
2241
2242static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002243bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244{
2245 Py_VISIT(self->dict);
2246 return 0;
2247}
2248
2249static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251{
2252 Py_CLEAR(self->reader);
2253 Py_CLEAR(self->writer);
2254 Py_CLEAR(self->dict);
2255 return 0;
2256}
2257
2258static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260{
2261 _PyObject_GC_UNTRACK(self);
2262 Py_CLEAR(self->reader);
2263 Py_CLEAR(self->writer);
2264 Py_CLEAR(self->dict);
2265 Py_TYPE(self)->tp_free((PyObject *) self);
2266}
2267
2268static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002269_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002271 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002272 PyObject *ret;
2273
2274 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002275 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276 return NULL;
2277 }
2278
2279 ret = PyObject_CallObject(func, args);
2280 Py_DECREF(func);
2281 return ret;
2282}
2283
2284static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002285bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002287 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002288}
2289
2290static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002291bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002292{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002293 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002294}
2295
2296static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002297bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002299 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300}
2301
2302static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002303bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002304{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002305 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002306}
2307
2308static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002309bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002310{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002311 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312}
2313
2314static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002315bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002316{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002317 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002318}
2319
2320static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002321bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002322{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002323 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002324}
2325
2326static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002327bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002329 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002330}
2331
2332static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002333bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002335 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002336 if (ret == NULL)
2337 return NULL;
2338 Py_DECREF(ret);
2339
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002340 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002341}
2342
2343static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002344bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002345{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002346 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347
2348 if (ret != Py_False) {
2349 /* either True or exception */
2350 return ret;
2351 }
2352 Py_DECREF(ret);
2353
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002354 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355}
2356
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002357static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002358bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002359{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002360 if (self->writer == NULL) {
2361 PyErr_SetString(PyExc_RuntimeError,
2362 "the BufferedRWPair object is being garbage-collected");
2363 return NULL;
2364 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002365 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2366}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002367
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002368static PyMethodDef bufferedrwpair_methods[] = {
2369 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2370 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2371 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2372 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002373
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002374 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2375 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002376
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002377 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2378 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002379
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002380 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2381 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002382
Antoine Pitrou243757e2010-11-05 21:15:39 +00002383 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2384
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002385 {NULL, NULL}
2386};
2387
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002388static PyGetSetDef bufferedrwpair_getset[] = {
2389 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002390 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002391};
2392
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002393PyTypeObject PyBufferedRWPair_Type = {
2394 PyVarObject_HEAD_INIT(NULL, 0)
2395 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002396 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002397 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002398 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002399 0, /*tp_print*/
2400 0, /*tp_getattr*/
2401 0, /*tp_setattr*/
2402 0, /*tp_compare */
2403 0, /*tp_repr*/
2404 0, /*tp_as_number*/
2405 0, /*tp_as_sequence*/
2406 0, /*tp_as_mapping*/
2407 0, /*tp_hash */
2408 0, /*tp_call*/
2409 0, /*tp_str*/
2410 0, /*tp_getattro*/
2411 0, /*tp_setattro*/
2412 0, /*tp_as_buffer*/
2413 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2414 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002415 bufferedrwpair_doc, /* tp_doc */
2416 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2417 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002419 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 0, /* tp_iter */
2421 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002422 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002423 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002424 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002425 0, /* tp_base */
2426 0, /* tp_dict */
2427 0, /* tp_descr_get */
2428 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429 offsetof(rwpair, dict), /* tp_dictoffset */
2430 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002431 0, /* tp_alloc */
2432 PyType_GenericNew, /* tp_new */
2433};
2434
2435
2436
2437/*
2438 * BufferedRandom
2439 */
2440
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002441PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442 "A buffered interface to random access streams.\n"
2443 "\n"
2444 "The constructor creates a reader and writer for a seekable stream,\n"
2445 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002446 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002447 );
2448
2449static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002450bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002451{
Florent Xicluna109d5732012-07-07 17:03:22 +02002452 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002454 PyObject *raw;
2455
2456 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002457 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458
R David Murray9f10f562013-02-23 22:07:55 -05002459 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002460 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461 return -1;
2462 }
2463
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002464 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002465 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002466 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002467 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002468 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002469 return -1;
2470
2471 Py_CLEAR(self->raw);
2472 Py_INCREF(raw);
2473 self->raw = raw;
2474 self->buffer_size = buffer_size;
2475 self->readable = 1;
2476 self->writable = 1;
2477
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002478 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002479 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002480 _bufferedreader_reset_buf(self);
2481 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002482 self->pos = 0;
2483
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002484 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2485 Py_TYPE(raw) == &PyFileIO_Type);
2486
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002487 self->ok = 1;
2488 return 0;
2489}
2490
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002491static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002492 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002493 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2494 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2495 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2496 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2497 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2498 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2499 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002500 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002501 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002502
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002503 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002504
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002505 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2506 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2507 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2508 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2509 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2510 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2511 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2512 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2513 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002514 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002515 {NULL, NULL}
2516};
2517
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002518static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002519 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002520 {NULL}
2521};
2522
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002523static PyGetSetDef bufferedrandom_getset[] = {
2524 {"closed", (getter)buffered_closed_get, NULL, NULL},
2525 {"name", (getter)buffered_name_get, NULL, NULL},
2526 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002527 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002528};
2529
2530
2531PyTypeObject PyBufferedRandom_Type = {
2532 PyVarObject_HEAD_INIT(NULL, 0)
2533 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002534 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 0, /*tp_print*/
2538 0, /*tp_getattr*/
2539 0, /*tp_setattr*/
2540 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002541 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002542 0, /*tp_as_number*/
2543 0, /*tp_as_sequence*/
2544 0, /*tp_as_mapping*/
2545 0, /*tp_hash */
2546 0, /*tp_call*/
2547 0, /*tp_str*/
2548 0, /*tp_getattro*/
2549 0, /*tp_setattro*/
2550 0, /*tp_as_buffer*/
2551 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2552 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002553 bufferedrandom_doc, /* tp_doc */
2554 (traverseproc)buffered_traverse, /* tp_traverse */
2555 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002556 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002557 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002558 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002559 (iternextfunc)buffered_iternext, /* tp_iternext */
2560 bufferedrandom_methods, /* tp_methods */
2561 bufferedrandom_members, /* tp_members */
2562 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002563 0, /* tp_base */
2564 0, /*tp_dict*/
2565 0, /* tp_descr_get */
2566 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567 offsetof(buffered, dict), /*tp_dictoffset*/
2568 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569 0, /* tp_alloc */
2570 PyType_GenericNew, /* tp_new */
2571};