blob: b0bbc621734fa5daaa96cc2b0c063879db59358a [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;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001482 PyObject *res, *data = NULL, *chunk, *chunks;
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) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001495 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001496 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001497 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001498 Py_CLEAR(res);
1499 }
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)) {
1503 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1504 if (chunk == NULL)
1505 return NULL;
1506 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1507 Py_XDECREF(data);
1508 Py_DECREF(chunk);
1509 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1510 return NULL;
1511 }
1512 if (chunk == Py_None) {
1513 if (current_size == 0)
1514 return chunk;
1515 else {
1516 Py_DECREF(chunk);
1517 return data;
1518 }
1519 }
1520 else if (current_size) {
1521 PyBytes_Concat(&data, chunk);
1522 Py_DECREF(chunk);
1523 if (data == NULL)
1524 return NULL;
1525 return data;
1526 } else
1527 return chunk;
1528 }
1529
1530 chunks = PyList_New(0);
Christian Heimes8f734eb2012-09-10 17:46:09 +02001531 if (chunks == NULL) {
1532 Py_XDECREF(data);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001533 return NULL;
Christian Heimes8f734eb2012-09-10 17:46:09 +02001534 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001535
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001536 while (1) {
1537 if (data) {
1538 if (PyList_Append(chunks, data) < 0) {
1539 Py_DECREF(data);
1540 Py_DECREF(chunks);
1541 return NULL;
1542 }
1543 Py_DECREF(data);
1544 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001545
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001546 /* Read until EOF or until read() would block. */
1547 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1548 if (data == NULL) {
1549 Py_DECREF(chunks);
1550 return NULL;
1551 }
1552 if (data != Py_None && !PyBytes_Check(data)) {
1553 Py_DECREF(data);
1554 Py_DECREF(chunks);
1555 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1556 return NULL;
1557 }
1558 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1559 if (current_size == 0) {
1560 Py_DECREF(chunks);
1561 return data;
1562 }
1563 else {
1564 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1565 Py_DECREF(data);
1566 Py_DECREF(chunks);
1567 return res;
1568 }
1569 }
1570 current_size += PyBytes_GET_SIZE(data);
1571 if (self->abs_pos != -1)
1572 self->abs_pos += PyBytes_GET_SIZE(data);
1573 }
1574}
1575
1576/* Read n bytes from the buffer if it can, otherwise return None.
1577 This function is simple enough that it can run unlocked. */
1578static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001579_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001580{
1581 Py_ssize_t current_size;
1582
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001583 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1584 if (n <= current_size) {
1585 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1587 if (res != NULL)
1588 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001589 return res;
1590 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591 Py_RETURN_NONE;
1592}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001593
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594/* Generic read function: read from the stream until enough bytes are read,
1595 * or until an EOF occurs or until read() would block.
1596 */
1597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001598_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599{
1600 PyObject *res = NULL;
1601 Py_ssize_t current_size, remaining, written;
1602 char *out;
1603
1604 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1605 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001606 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001608 res = PyBytes_FromStringAndSize(NULL, n);
1609 if (res == NULL)
1610 goto error;
1611 out = PyBytes_AS_STRING(res);
1612 remaining = n;
1613 written = 0;
1614 if (current_size > 0) {
1615 memcpy(out, self->buffer + self->pos, current_size);
1616 remaining -= current_size;
1617 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001618 self->pos += current_size;
1619 }
1620 /* Flush the write buffer if necessary */
1621 if (self->writable) {
1622 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1623 if (r == NULL)
1624 goto error;
1625 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001626 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001627 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001628 while (remaining > 0) {
1629 /* We want to read a whole block at the end into buffer.
1630 If we had readv() we could do this in one pass. */
1631 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1632 if (r == 0)
1633 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001634 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001635 if (r == -1)
1636 goto error;
1637 if (r == 0 || r == -2) {
1638 /* EOF occurred or read() would block. */
1639 if (r == 0 || written > 0) {
1640 if (_PyBytes_Resize(&res, written))
1641 goto error;
1642 return res;
1643 }
1644 Py_DECREF(res);
1645 Py_INCREF(Py_None);
1646 return Py_None;
1647 }
1648 remaining -= r;
1649 written += r;
1650 }
1651 assert(remaining <= self->buffer_size);
1652 self->pos = 0;
1653 self->raw_pos = 0;
1654 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001655 /* NOTE: when the read is satisfied, we avoid issuing any additional
1656 reads, which could block indefinitely (e.g. on a socket).
1657 See issue #9550. */
1658 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001659 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001660 if (r == -1)
1661 goto error;
1662 if (r == 0 || r == -2) {
1663 /* EOF occurred or read() would block. */
1664 if (r == 0 || written > 0) {
1665 if (_PyBytes_Resize(&res, written))
1666 goto error;
1667 return res;
1668 }
1669 Py_DECREF(res);
1670 Py_INCREF(Py_None);
1671 return Py_None;
1672 }
1673 if (remaining > r) {
1674 memcpy(out + written, self->buffer + self->pos, r);
1675 written += r;
1676 self->pos += r;
1677 remaining -= r;
1678 }
1679 else if (remaining > 0) {
1680 memcpy(out + written, self->buffer + self->pos, remaining);
1681 written += remaining;
1682 self->pos += remaining;
1683 remaining = 0;
1684 }
1685 if (remaining == 0)
1686 break;
1687 }
1688
1689 return res;
1690
1691error:
1692 Py_XDECREF(res);
1693 return NULL;
1694}
1695
1696static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001697_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001698{
1699 Py_ssize_t have, r;
1700
1701 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1702 /* Constraints:
1703 1. we don't want to advance the file position.
1704 2. we don't want to lose block alignment, so we can't shift the buffer
1705 to make some place.
1706 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1707 */
1708 if (have > 0) {
1709 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1710 }
1711
1712 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001713 _bufferedreader_reset_buf(self);
1714 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001715 if (r == -1)
1716 return NULL;
1717 if (r == -2)
1718 r = 0;
1719 self->pos = 0;
1720 return PyBytes_FromStringAndSize(self->buffer, r);
1721}
1722
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001723static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001724 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001725 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1726 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1727 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1728 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1729 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1730 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1731 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1732 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001733 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001734 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001735
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001736 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1737 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1738 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001739 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001740 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1741 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1742 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1743 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001744 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745 {NULL, NULL}
1746};
1747
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001748static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001749 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750 {NULL}
1751};
1752
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001753static PyGetSetDef bufferedreader_getset[] = {
1754 {"closed", (getter)buffered_closed_get, NULL, NULL},
1755 {"name", (getter)buffered_name_get, NULL, NULL},
1756 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001757 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001758};
1759
1760
1761PyTypeObject PyBufferedReader_Type = {
1762 PyVarObject_HEAD_INIT(NULL, 0)
1763 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001764 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001765 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001766 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767 0, /*tp_print*/
1768 0, /*tp_getattr*/
1769 0, /*tp_setattr*/
1770 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001771 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001772 0, /*tp_as_number*/
1773 0, /*tp_as_sequence*/
1774 0, /*tp_as_mapping*/
1775 0, /*tp_hash */
1776 0, /*tp_call*/
1777 0, /*tp_str*/
1778 0, /*tp_getattro*/
1779 0, /*tp_setattro*/
1780 0, /*tp_as_buffer*/
1781 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1782 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001783 bufferedreader_doc, /* tp_doc */
1784 (traverseproc)buffered_traverse, /* tp_traverse */
1785 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001789 (iternextfunc)buffered_iternext, /* tp_iternext */
1790 bufferedreader_methods, /* tp_methods */
1791 bufferedreader_members, /* tp_members */
1792 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 0, /* tp_base */
1794 0, /* tp_dict */
1795 0, /* tp_descr_get */
1796 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001797 offsetof(buffered, dict), /* tp_dictoffset */
1798 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799 0, /* tp_alloc */
1800 PyType_GenericNew, /* tp_new */
1801};
1802
1803
Benjamin Peterson59406a92009-03-26 17:10:29 +00001804
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805/*
1806 * class BufferedWriter
1807 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001808PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 "A buffer for a writeable sequential RawIO object.\n"
1810 "\n"
1811 "The constructor creates a BufferedWriter for the given writeable raw\n"
1812 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001813 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814 );
1815
1816static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001817_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818{
1819 self->write_pos = 0;
1820 self->write_end = -1;
1821}
1822
1823static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825{
Florent Xicluna109d5732012-07-07 17:03:22 +02001826 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828 PyObject *raw;
1829
1830 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001831 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832
R David Murray9f10f562013-02-23 22:07:55 -05001833 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001834 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 return -1;
1836 }
1837
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001838 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001839 return -1;
1840
1841 Py_CLEAR(self->raw);
1842 Py_INCREF(raw);
1843 self->raw = raw;
1844 self->readable = 0;
1845 self->writable = 1;
1846
1847 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001848 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001850 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 self->pos = 0;
1852
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001853 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1854 Py_TYPE(raw) == &PyFileIO_Type);
1855
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856 self->ok = 1;
1857 return 0;
1858}
1859
1860static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001861_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862{
1863 Py_buffer buf;
1864 PyObject *memobj, *res;
1865 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001866 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001867 /* NOTE: the buffer needn't be released as its object is NULL. */
1868 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1869 return -1;
1870 memobj = PyMemoryView_FromBuffer(&buf);
1871 if (memobj == NULL)
1872 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001873 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1874 occurs so we needn't do it ourselves.
1875 We then retry writing, ignoring the signal if no handler has
1876 raised (see issue #10956).
1877 */
1878 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001879 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001880 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001882 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001883 Py_DECREF(memobj);
1884 if (res == NULL)
1885 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001886 if (res == Py_None) {
1887 /* Non-blocking stream would have blocked. Special return code!
1888 Being paranoid we reset errno in case it is changed by code
1889 triggered by a decref. errno is used by _set_BlockingIOError(). */
1890 Py_DECREF(res);
1891 errno = errnum;
1892 return -2;
1893 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001894 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1895 Py_DECREF(res);
1896 if (n < 0 || n > len) {
1897 PyErr_Format(PyExc_IOError,
1898 "raw write() returned invalid length %zd "
1899 "(should have been between 0 and %zd)", n, len);
1900 return -1;
1901 }
1902 if (n > 0 && self->abs_pos != -1)
1903 self->abs_pos += n;
1904 return n;
1905}
1906
1907/* `restore_pos` is 1 if we need to restore the raw stream position at
1908 the end, 0 otherwise. */
1909static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001910_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001911{
1912 Py_ssize_t written = 0;
1913 Py_off_t n, rewind;
1914
1915 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1916 goto end;
1917 /* First, rewind */
1918 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1919 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001920 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921 if (n < 0) {
1922 goto error;
1923 }
1924 self->raw_pos -= rewind;
1925 }
1926 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001927 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928 self->buffer + self->write_pos,
1929 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1930 Py_off_t, Py_ssize_t));
1931 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001932 goto error;
1933 }
1934 else if (n == -2) {
1935 _set_BlockingIOError("write could not complete without blocking",
1936 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937 goto error;
1938 }
1939 self->write_pos += n;
1940 self->raw_pos = self->write_pos;
1941 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001942 /* Partial writes can return successfully when interrupted by a
1943 signal (see write(2)). We must run signal handlers before
1944 blocking another time, possibly indefinitely. */
1945 if (PyErr_CheckSignals() < 0)
1946 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947 }
1948
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001949 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001950
1951end:
1952 Py_RETURN_NONE;
1953
1954error:
1955 return NULL;
1956}
1957
1958static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001959bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001960{
1961 PyObject *res = NULL;
1962 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001963 Py_ssize_t written, avail, remaining;
1964 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965
1966 CHECK_INITIALIZED(self)
1967 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1968 return NULL;
1969 }
1970
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001971 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972 PyErr_SetString(PyExc_ValueError, "write to closed file");
1973 PyBuffer_Release(&buf);
1974 return NULL;
1975 }
1976
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001977 if (!ENTER_BUFFERED(self)) {
1978 PyBuffer_Release(&buf);
1979 return NULL;
1980 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981
1982 /* Fast path: the data to write can be fully buffered. */
1983 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1984 self->pos = 0;
1985 self->raw_pos = 0;
1986 }
1987 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1988 if (buf.len <= avail) {
1989 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001990 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 self->write_pos = self->pos;
1992 }
1993 ADJUST_POSITION(self, self->pos + buf.len);
1994 if (self->pos > self->write_end)
1995 self->write_end = self->pos;
1996 written = buf.len;
1997 goto end;
1998 }
1999
2000 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002001 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002002 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002003 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 if (w == NULL)
2005 goto error;
2006 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002007 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 /* Make some place by shifting the buffer. */
2009 assert(VALID_WRITE_BUFFER(self));
2010 memmove(self->buffer, self->buffer + self->write_pos,
2011 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2012 Py_off_t, Py_ssize_t));
2013 self->write_end -= self->write_pos;
2014 self->raw_pos -= self->write_pos;
2015 self->pos -= self->write_pos;
2016 self->write_pos = 0;
2017 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2018 Py_off_t, Py_ssize_t);
2019 if (buf.len <= avail) {
2020 /* Everything can be buffered */
2021 PyErr_Clear();
2022 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2023 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002024 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025 written = buf.len;
2026 goto end;
2027 }
2028 /* Buffer as much as possible. */
2029 memcpy(self->buffer + self->write_end, buf.buf, avail);
2030 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002031 self->pos += avail;
2032 /* XXX Modifying the existing exception e using the pointer w
2033 will change e.characters_written but not e.args[2].
2034 Therefore we just replace with a new error. */
2035 _set_BlockingIOError("write could not complete without blocking",
2036 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 goto error;
2038 }
2039 Py_CLEAR(res);
2040
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002041 /* Adjust the raw stream position if it is away from the logical stream
2042 position. This happens if the read buffer has been filled but not
2043 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2044 the raw stream by itself).
2045 Fixes issue #6629.
2046 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002047 offset = RAW_OFFSET(self);
2048 if (offset != 0) {
2049 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002050 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002051 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002052 }
2053
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 /* Then write buf itself. At this point the buffer has been emptied. */
2055 remaining = buf.len;
2056 written = 0;
2057 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002058 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059 self, (char *) buf.buf + written, buf.len - written);
2060 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002061 goto error;
2062 } else if (n == -2) {
2063 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064 if (remaining > self->buffer_size) {
2065 /* Can't buffer everything, still buffer as much as possible */
2066 memcpy(self->buffer,
2067 (char *) buf.buf + written, self->buffer_size);
2068 self->raw_pos = 0;
2069 ADJUST_POSITION(self, self->buffer_size);
2070 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002071 written += self->buffer_size;
2072 _set_BlockingIOError("write could not complete without "
2073 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074 goto error;
2075 }
2076 PyErr_Clear();
2077 break;
2078 }
2079 written += n;
2080 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002081 /* Partial writes can return successfully when interrupted by a
2082 signal (see write(2)). We must run signal handlers before
2083 blocking another time, possibly indefinitely. */
2084 if (PyErr_CheckSignals() < 0)
2085 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086 }
2087 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002088 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002089 if (remaining > 0) {
2090 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2091 written += remaining;
2092 }
2093 self->write_pos = 0;
2094 /* TODO: sanity check (remaining >= 0) */
2095 self->write_end = remaining;
2096 ADJUST_POSITION(self, remaining);
2097 self->raw_pos = 0;
2098
2099end:
2100 res = PyLong_FromSsize_t(written);
2101
2102error:
2103 LEAVE_BUFFERED(self)
2104 PyBuffer_Release(&buf);
2105 return res;
2106}
2107
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002108static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2111 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2112 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2113 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2114 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2115 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2116 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002117 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002118 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002119
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2121 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2122 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2123 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2124 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002125 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002126 {NULL, NULL}
2127};
2128
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002130 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131 {NULL}
2132};
2133
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002134static PyGetSetDef bufferedwriter_getset[] = {
2135 {"closed", (getter)buffered_closed_get, NULL, NULL},
2136 {"name", (getter)buffered_name_get, NULL, NULL},
2137 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002138 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139};
2140
2141
2142PyTypeObject PyBufferedWriter_Type = {
2143 PyVarObject_HEAD_INIT(NULL, 0)
2144 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002145 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002146 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148 0, /*tp_print*/
2149 0, /*tp_getattr*/
2150 0, /*tp_setattr*/
2151 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002152 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 0, /*tp_as_number*/
2154 0, /*tp_as_sequence*/
2155 0, /*tp_as_mapping*/
2156 0, /*tp_hash */
2157 0, /*tp_call*/
2158 0, /*tp_str*/
2159 0, /*tp_getattro*/
2160 0, /*tp_setattro*/
2161 0, /*tp_as_buffer*/
2162 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2163 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002164 bufferedwriter_doc, /* tp_doc */
2165 (traverseproc)buffered_traverse, /* tp_traverse */
2166 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 0, /* tp_iter */
2170 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002171 bufferedwriter_methods, /* tp_methods */
2172 bufferedwriter_members, /* tp_members */
2173 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002174 0, /* tp_base */
2175 0, /* tp_dict */
2176 0, /* tp_descr_get */
2177 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002178 offsetof(buffered, dict), /* tp_dictoffset */
2179 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180 0, /* tp_alloc */
2181 PyType_GenericNew, /* tp_new */
2182};
2183
2184
2185
2186/*
2187 * BufferedRWPair
2188 */
2189
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191 "A buffered reader and writer object together.\n"
2192 "\n"
2193 "A buffered reader object and buffered writer object put together to\n"
2194 "form a sequential IO object that can read and write. This is typically\n"
2195 "used with a socket or two-way pipe.\n"
2196 "\n"
2197 "reader and writer are RawIOBase objects that are readable and\n"
2198 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002199 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002200 );
2201
2202/* XXX The usefulness of this (compared to having two separate IO objects) is
2203 * questionable.
2204 */
2205
2206typedef struct {
2207 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002208 buffered *reader;
2209 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210 PyObject *dict;
2211 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002212} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213
2214static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002215bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216{
2217 PyObject *reader, *writer;
2218 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219
Florent Xicluna109d5732012-07-07 17:03:22 +02002220 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2221 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222 return -1;
2223 }
2224
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002225 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002228 return -1;
2229
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002230 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002231 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232 if (self->reader == NULL)
2233 return -1;
2234
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002235 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002236 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237 if (self->writer == NULL) {
2238 Py_CLEAR(self->reader);
2239 return -1;
2240 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002241
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242 return 0;
2243}
2244
2245static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002246bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002247{
2248 Py_VISIT(self->dict);
2249 return 0;
2250}
2251
2252static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002253bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254{
2255 Py_CLEAR(self->reader);
2256 Py_CLEAR(self->writer);
2257 Py_CLEAR(self->dict);
2258 return 0;
2259}
2260
2261static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263{
2264 _PyObject_GC_UNTRACK(self);
2265 Py_CLEAR(self->reader);
2266 Py_CLEAR(self->writer);
2267 Py_CLEAR(self->dict);
2268 Py_TYPE(self)->tp_free((PyObject *) self);
2269}
2270
2271static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002272_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002274 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002275 PyObject *ret;
2276
2277 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002278 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002279 return NULL;
2280 }
2281
2282 ret = PyObject_CallObject(func, args);
2283 Py_DECREF(func);
2284 return ret;
2285}
2286
2287static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002288bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002290 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291}
2292
2293static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002294bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002295{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002296 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297}
2298
2299static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002300bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002301{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002302 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303}
2304
2305static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002306bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002307{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002308 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002309}
2310
2311static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002312bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002314 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002315}
2316
2317static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002318bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002320 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002321}
2322
2323static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002324bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002325{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002326 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002327}
2328
2329static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002330bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002332 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002333}
2334
2335static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002336bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002337{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002338 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339 if (ret == NULL)
2340 return NULL;
2341 Py_DECREF(ret);
2342
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002343 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002344}
2345
2346static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002347bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002348{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002349 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002350
2351 if (ret != Py_False) {
2352 /* either True or exception */
2353 return ret;
2354 }
2355 Py_DECREF(ret);
2356
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002357 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002358}
2359
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002360static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002361bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002362{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002363 if (self->writer == NULL) {
2364 PyErr_SetString(PyExc_RuntimeError,
2365 "the BufferedRWPair object is being garbage-collected");
2366 return NULL;
2367 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002368 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2369}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002370
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002371static PyMethodDef bufferedrwpair_methods[] = {
2372 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2373 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2374 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2375 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002376
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002377 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2378 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002379
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002380 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2381 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002382
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002383 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2384 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002385
Antoine Pitrou243757e2010-11-05 21:15:39 +00002386 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2387
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388 {NULL, NULL}
2389};
2390
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002391static PyGetSetDef bufferedrwpair_getset[] = {
2392 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002393 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002394};
2395
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002396PyTypeObject PyBufferedRWPair_Type = {
2397 PyVarObject_HEAD_INIT(NULL, 0)
2398 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002399 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002400 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002401 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002402 0, /*tp_print*/
2403 0, /*tp_getattr*/
2404 0, /*tp_setattr*/
2405 0, /*tp_compare */
2406 0, /*tp_repr*/
2407 0, /*tp_as_number*/
2408 0, /*tp_as_sequence*/
2409 0, /*tp_as_mapping*/
2410 0, /*tp_hash */
2411 0, /*tp_call*/
2412 0, /*tp_str*/
2413 0, /*tp_getattro*/
2414 0, /*tp_setattro*/
2415 0, /*tp_as_buffer*/
2416 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2417 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002418 bufferedrwpair_doc, /* tp_doc */
2419 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2420 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002422 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002423 0, /* tp_iter */
2424 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002425 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002427 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428 0, /* tp_base */
2429 0, /* tp_dict */
2430 0, /* tp_descr_get */
2431 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002432 offsetof(rwpair, dict), /* tp_dictoffset */
2433 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002434 0, /* tp_alloc */
2435 PyType_GenericNew, /* tp_new */
2436};
2437
2438
2439
2440/*
2441 * BufferedRandom
2442 */
2443
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002444PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002445 "A buffered interface to random access streams.\n"
2446 "\n"
2447 "The constructor creates a reader and writer for a seekable stream,\n"
2448 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002449 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002450 );
2451
2452static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002453bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002454{
Florent Xicluna109d5732012-07-07 17:03:22 +02002455 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002457 PyObject *raw;
2458
2459 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002460 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461
R David Murray9f10f562013-02-23 22:07:55 -05002462 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002463 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002464 return -1;
2465 }
2466
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002467 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002468 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002469 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002470 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002471 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002472 return -1;
2473
2474 Py_CLEAR(self->raw);
2475 Py_INCREF(raw);
2476 self->raw = raw;
2477 self->buffer_size = buffer_size;
2478 self->readable = 1;
2479 self->writable = 1;
2480
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002481 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002482 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002483 _bufferedreader_reset_buf(self);
2484 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485 self->pos = 0;
2486
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002487 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2488 Py_TYPE(raw) == &PyFileIO_Type);
2489
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002490 self->ok = 1;
2491 return 0;
2492}
2493
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002494static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002495 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002496 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2497 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2498 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2499 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2500 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2501 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2502 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002503 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002504 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002505
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002506 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002508 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2509 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2510 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2511 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2512 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2513 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2514 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2515 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2516 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002517 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002518 {NULL, NULL}
2519};
2520
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002521static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002522 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002523 {NULL}
2524};
2525
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002526static PyGetSetDef bufferedrandom_getset[] = {
2527 {"closed", (getter)buffered_closed_get, NULL, NULL},
2528 {"name", (getter)buffered_name_get, NULL, NULL},
2529 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002530 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002531};
2532
2533
2534PyTypeObject PyBufferedRandom_Type = {
2535 PyVarObject_HEAD_INIT(NULL, 0)
2536 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002537 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002538 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002539 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002540 0, /*tp_print*/
2541 0, /*tp_getattr*/
2542 0, /*tp_setattr*/
2543 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002544 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002545 0, /*tp_as_number*/
2546 0, /*tp_as_sequence*/
2547 0, /*tp_as_mapping*/
2548 0, /*tp_hash */
2549 0, /*tp_call*/
2550 0, /*tp_str*/
2551 0, /*tp_getattro*/
2552 0, /*tp_setattro*/
2553 0, /*tp_as_buffer*/
2554 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2555 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002556 bufferedrandom_doc, /* tp_doc */
2557 (traverseproc)buffered_traverse, /* tp_traverse */
2558 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002560 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002561 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002562 (iternextfunc)buffered_iternext, /* tp_iternext */
2563 bufferedrandom_methods, /* tp_methods */
2564 bufferedrandom_members, /* tp_members */
2565 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566 0, /* tp_base */
2567 0, /*tp_dict*/
2568 0, /* tp_descr_get */
2569 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570 offsetof(buffered, dict), /*tp_dictoffset*/
2571 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572 0, /* tp_alloc */
2573 PyType_GenericNew, /* tp_new */
2574};