blob: 7f180a459288a7c6b254f2d8e26eb6faa797319a [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020016_Py_IDENTIFIER(close);
17_Py_IDENTIFIER(_dealloc_warn);
18_Py_IDENTIFIER(flush);
19_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020020_Py_IDENTIFIER(mode);
21_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020022_Py_IDENTIFIER(peek);
23_Py_IDENTIFIER(read);
24_Py_IDENTIFIER(read1);
25_Py_IDENTIFIER(readable);
26_Py_IDENTIFIER(readinto);
27_Py_IDENTIFIER(writable);
28_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020029
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000030/*
31 * BufferedIOBase class, inherits from IOBase.
32 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000033PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034 "Base class for buffered IO objects.\n"
35 "\n"
36 "The main difference with RawIOBase is that the read() method\n"
37 "supports omitting the size argument, and does not have a default\n"
38 "implementation that defers to readinto().\n"
39 "\n"
40 "In addition, read(), readinto() and write() may raise\n"
41 "BlockingIOError if the underlying raw stream is in non-blocking\n"
42 "mode and not ready; unlike their raw counterparts, they will never\n"
43 "return None.\n"
44 "\n"
45 "A typical implementation should not inherit from a RawIOBase\n"
46 "implementation, but wrap one.\n"
47 );
48
49static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000050bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000051{
52 Py_buffer buf;
53 Py_ssize_t len;
54 PyObject *data;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020055 _Py_IDENTIFIER(read);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000056
57 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
58 return NULL;
59 }
60
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020061 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000062 if (data == NULL)
63 goto error;
64
65 if (!PyBytes_Check(data)) {
66 Py_DECREF(data);
67 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
68 goto error;
69 }
70
71 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030072 if (len > buf.len) {
73 PyErr_Format(PyExc_ValueError,
74 "read() returned too much data: "
75 "%zd bytes requested, %zd returned",
76 buf.len, len);
77 Py_DECREF(data);
78 goto error;
79 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
81
82 PyBuffer_Release(&buf);
83 Py_DECREF(data);
84
85 return PyLong_FromSsize_t(len);
86
87 error:
88 PyBuffer_Release(&buf);
89 return NULL;
90}
91
92static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000093bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094{
95 PyErr_SetString(IO_STATE->unsupported_operation, message);
96 return NULL;
97}
98
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000100 "Disconnect this buffer from its underlying raw stream and return it.\n"
101 "\n"
102 "After the raw stream has been detached, the buffer is in an unusable\n"
103 "state.\n");
104
105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000106bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000107{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000109}
110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000111PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000112 "Read and return up to n bytes.\n"
113 "\n"
114 "If the argument is omitted, None, or negative, reads and\n"
115 "returns all data until EOF.\n"
116 "\n"
117 "If the argument is positive, and the underlying raw stream is\n"
118 "not 'interactive', multiple raw reads may be issued to satisfy\n"
119 "the byte count (unless EOF is reached first). But for\n"
120 "interactive raw streams (as well as sockets and pipes), at most\n"
121 "one raw read will be issued, and a short result does not imply\n"
122 "that EOF is imminent.\n"
123 "\n"
124 "Returns an empty bytes object on EOF.\n"
125 "\n"
126 "Returns None if the underlying raw stream was open in non-blocking\n"
127 "mode and no data is available at the moment.\n");
128
129static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000130bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000131{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000132 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133}
134
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136 "Read and return up to n bytes, with at most one read() call\n"
137 "to the underlying raw stream. A short result does not imply\n"
138 "that EOF is imminent.\n"
139 "\n"
140 "Returns an empty bytes object on EOF.\n");
141
142static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000144{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000145 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000146}
147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149 "Write the given buffer to the IO stream.\n"
150 "\n"
151 "Returns the number of bytes written, which is never less than\n"
152 "len(b).\n"
153 "\n"
154 "Raises BlockingIOError if the buffer is full and the\n"
155 "underlying raw stream cannot accept more data at the moment.\n");
156
157static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000159{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000160 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000161}
162
163
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000164static PyMethodDef bufferediobase_methods[] = {
165 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
166 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
167 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
168 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
169 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000170 {NULL, NULL}
171};
172
173PyTypeObject PyBufferedIOBase_Type = {
174 PyVarObject_HEAD_INIT(NULL, 0)
175 "_io._BufferedIOBase", /*tp_name*/
176 0, /*tp_basicsize*/
177 0, /*tp_itemsize*/
178 0, /*tp_dealloc*/
179 0, /*tp_print*/
180 0, /*tp_getattr*/
181 0, /*tp_setattr*/
182 0, /*tp_compare */
183 0, /*tp_repr*/
184 0, /*tp_as_number*/
185 0, /*tp_as_sequence*/
186 0, /*tp_as_mapping*/
187 0, /*tp_hash */
188 0, /*tp_call*/
189 0, /*tp_str*/
190 0, /*tp_getattro*/
191 0, /*tp_setattro*/
192 0, /*tp_as_buffer*/
193 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 0, /* tp_traverse */
196 0, /* tp_clear */
197 0, /* tp_richcompare */
198 0, /* tp_weaklistoffset */
199 0, /* tp_iter */
200 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000201 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000202 0, /* tp_members */
203 0, /* tp_getset */
204 &PyIOBase_Type, /* tp_base */
205 0, /* tp_dict */
206 0, /* tp_descr_get */
207 0, /* tp_descr_set */
208 0, /* tp_dictoffset */
209 0, /* tp_init */
210 0, /* tp_alloc */
211 0, /* tp_new */
212};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000213
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000214
215typedef struct {
216 PyObject_HEAD
217
218 PyObject *raw;
219 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000220 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000221 int readable;
222 int writable;
Antoine Pitroue033e062010-10-29 10:38:18 +0000223 int deallocating;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200224
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000225 /* True if this is a vanilla Buffered object (rather than a user derived
226 class) *and* the raw stream is a vanilla FileIO object. */
227 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000228
229 /* Absolute position inside the raw stream (-1 if unknown). */
230 Py_off_t abs_pos;
231
232 /* A static buffer of size `buffer_size` */
233 char *buffer;
234 /* Current logical position in the buffer. */
235 Py_off_t pos;
236 /* Position of the raw stream in the buffer. */
237 Py_off_t raw_pos;
238
239 /* Just after the last buffered byte in the buffer, or -1 if the buffer
240 isn't ready for reading. */
241 Py_off_t read_end;
242
243 /* Just after the last byte actually written */
244 Py_off_t write_pos;
245 /* Just after the last byte waiting to be written, or -1 if the buffer
246 isn't ready for writing. */
247 Py_off_t write_end;
248
Georg Brandldfd73442009-04-05 11:47:34 +0000249#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000251 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000252#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000253
254 Py_ssize_t buffer_size;
255 Py_ssize_t buffer_mask;
256
257 PyObject *dict;
258 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000259} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260
261/*
262 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200263
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264 * BufferedReader, BufferedWriter and BufferedRandom try to share most
265 methods (this is helped by the members `readable` and `writable`, which
266 are initialized in the respective constructors)
267 * They also share a single buffer for reading and writing. This enables
268 interleaved reads and writes without flushing. It also makes the logic
269 a bit trickier to get right.
270 * The absolute position of the raw stream is cached, if possible, in the
271 `abs_pos` member. It must be updated every time an operation is done
272 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000273 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000274 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000275 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
276 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000277
278 NOTE: we should try to maintain block alignment of reads and writes to the
279 raw stream (according to the buffer size), but for now it is only done
280 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200281
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000282*/
283
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000284/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000285
Georg Brandldfd73442009-04-05 11:47:34 +0000286#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000287
288static int
289_enter_buffered_busy(buffered *self)
290{
291 if (self->owner == PyThread_get_thread_ident()) {
292 PyErr_Format(PyExc_RuntimeError,
293 "reentrant call inside %R", self);
294 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000295 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000296 Py_BEGIN_ALLOW_THREADS
297 PyThread_acquire_lock(self->lock, 1);
298 Py_END_ALLOW_THREADS
299 return 1;
300}
301
302#define ENTER_BUFFERED(self) \
303 ( (PyThread_acquire_lock(self->lock, 0) ? \
304 1 : _enter_buffered_busy(self)) \
305 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000306
307#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000308 do { \
309 self->owner = 0; \
310 PyThread_release_lock(self->lock); \
311 } while(0);
312
Georg Brandldfd73442009-04-05 11:47:34 +0000313#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000314#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000315#define LEAVE_BUFFERED(self)
316#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000317
318#define CHECK_INITIALIZED(self) \
319 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000320 if (self->detached) { \
321 PyErr_SetString(PyExc_ValueError, \
322 "raw stream has been detached"); \
323 } else { \
324 PyErr_SetString(PyExc_ValueError, \
325 "I/O operation on uninitialized object"); \
326 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000327 return NULL; \
328 }
329
330#define CHECK_INITIALIZED_INT(self) \
331 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000332 if (self->detached) { \
333 PyErr_SetString(PyExc_ValueError, \
334 "raw stream has been detached"); \
335 } else { \
336 PyErr_SetString(PyExc_ValueError, \
337 "I/O operation on uninitialized object"); \
338 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 return -1; \
340 }
341
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000342#define IS_CLOSED(self) \
343 (self->fast_closed_checks \
344 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000345 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000346
347#define CHECK_CLOSED(self, error_msg) \
348 if (IS_CLOSED(self)) { \
349 PyErr_SetString(PyExc_ValueError, error_msg); \
350 return NULL; \
351 }
352
353
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354#define VALID_READ_BUFFER(self) \
355 (self->readable && self->read_end != -1)
356
357#define VALID_WRITE_BUFFER(self) \
358 (self->writable && self->write_end != -1)
359
360#define ADJUST_POSITION(self, _new_pos) \
361 do { \
362 self->pos = _new_pos; \
363 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
364 self->read_end = self->pos; \
365 } while(0)
366
367#define READAHEAD(self) \
368 ((self->readable && VALID_READ_BUFFER(self)) \
369 ? (self->read_end - self->pos) : 0)
370
371#define RAW_OFFSET(self) \
372 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
373 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
374
375#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000376 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000377
378#define MINUS_LAST_BLOCK(self, size) \
379 (self->buffer_mask ? \
380 (size & ~self->buffer_mask) : \
381 (self->buffer_size * (size / self->buffer_size)))
382
383
384static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000385buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000386{
Antoine Pitroue033e062010-10-29 10:38:18 +0000387 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
389 return;
390 _PyObject_GC_UNTRACK(self);
391 self->ok = 0;
392 if (self->weakreflist != NULL)
393 PyObject_ClearWeakRefs((PyObject *)self);
394 Py_CLEAR(self->raw);
395 if (self->buffer) {
396 PyMem_Free(self->buffer);
397 self->buffer = NULL;
398 }
Georg Brandldfd73442009-04-05 11:47:34 +0000399#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000400 if (self->lock) {
401 PyThread_free_lock(self->lock);
402 self->lock = NULL;
403 }
Georg Brandldfd73442009-04-05 11:47:34 +0000404#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000405 Py_CLEAR(self->dict);
406 Py_TYPE(self)->tp_free((PyObject *)self);
407}
408
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200409static PyObject *
410buffered_sizeof(buffered *self, void *unused)
411{
412 Py_ssize_t res;
413
414 res = sizeof(buffered);
415 if (self->buffer)
416 res += self->buffer_size;
417 return PyLong_FromSsize_t(res);
418}
419
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000420static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000421buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422{
423 Py_VISIT(self->raw);
424 Py_VISIT(self->dict);
425 return 0;
426}
427
428static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000429buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000430{
431 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
432 return -1;
433 self->ok = 0;
434 Py_CLEAR(self->raw);
435 Py_CLEAR(self->dict);
436 return 0;
437}
438
Antoine Pitroue033e062010-10-29 10:38:18 +0000439/* Because this can call arbitrary code, it shouldn't be called when
440 the refcount is 0 (that is, not directly from tp_dealloc unless
441 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000442static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000443buffered_dealloc_warn(buffered *self, PyObject *source)
444{
445 if (self->ok && self->raw) {
446 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200447 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000448 if (r)
449 Py_DECREF(r);
450 else
451 PyErr_Clear();
452 }
453 Py_RETURN_NONE;
454}
455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456/*
457 * _BufferedIOMixin methods
458 * This is not a class, just a collection of methods that will be reused
459 * by BufferedReader and BufferedWriter
460 */
461
462/* Flush and close */
463
464static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000465buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466{
467 CHECK_INITIALIZED(self)
468 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
469}
470
471static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000472buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000473{
474 int closed;
475 PyObject *res;
476 CHECK_INITIALIZED_INT(self)
477 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
478 if (res == NULL)
479 return -1;
480 closed = PyObject_IsTrue(res);
481 Py_DECREF(res);
482 return closed;
483}
484
485static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000486buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487{
488 CHECK_INITIALIZED(self)
489 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
490}
491
492static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000493buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000494{
Benjamin Peterson68623612012-12-20 11:53:11 -0600495 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 int r;
497
498 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000499 if (!ENTER_BUFFERED(self))
500 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503 if (r < 0)
504 goto end;
505 if (r > 0) {
506 res = Py_None;
507 Py_INCREF(res);
508 goto end;
509 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000510
511 if (self->deallocating) {
512 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
513 if (r)
514 Py_DECREF(r);
515 else
516 PyErr_Clear();
517 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000518 /* flush() will most probably re-take the lock, so drop it first */
519 LEAVE_BUFFERED(self)
520 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000521 if (!ENTER_BUFFERED(self))
522 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600523 if (res == NULL)
524 PyErr_Fetch(&exc, &val, &tb);
525 else
526 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000527
528 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
529
Benjamin Peterson68623612012-12-20 11:53:11 -0600530 if (exc != NULL) {
531 if (res != NULL) {
532 Py_CLEAR(res);
533 PyErr_Restore(exc, val, tb);
534 }
535 else {
536 PyObject *val2;
537 Py_DECREF(exc);
538 Py_XDECREF(tb);
539 PyErr_Fetch(&exc, &val2, &tb);
540 PyErr_NormalizeException(&exc, &val2, &tb);
541 PyException_SetContext(val2, val);
542 PyErr_Restore(exc, val2, tb);
543 }
544 }
545
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000546end:
547 LEAVE_BUFFERED(self)
548 return res;
549}
550
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000551/* detach */
552
553static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000554buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000555{
556 PyObject *raw, *res;
557 CHECK_INITIALIZED(self)
558 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
559 if (res == NULL)
560 return NULL;
561 Py_DECREF(res);
562 raw = self->raw;
563 self->raw = NULL;
564 self->detached = 1;
565 self->ok = 0;
566 return raw;
567}
568
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569/* Inquiries */
570
571static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000572buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573{
574 CHECK_INITIALIZED(self)
575 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
576}
577
578static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000579buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580{
581 CHECK_INITIALIZED(self)
582 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
583}
584
585static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000586buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000587{
588 CHECK_INITIALIZED(self)
589 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
590}
591
592static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000593buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594{
595 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200596 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597}
598
599static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000600buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601{
602 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200603 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604}
605
606/* Lower-level APIs */
607
608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000610{
611 CHECK_INITIALIZED(self)
612 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
613}
614
615static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000616buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617{
618 CHECK_INITIALIZED(self)
619 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
620}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000621
Antoine Pitrou243757e2010-11-05 21:15:39 +0000622/* Serialization */
623
624static PyObject *
625buffered_getstate(buffered *self, PyObject *args)
626{
627 PyErr_Format(PyExc_TypeError,
628 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
629 return NULL;
630}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000631
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000632/* Forward decls */
633static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100634_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000638_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200642_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000644_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000645static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000646_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000647static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000648_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200649static Py_ssize_t
650_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651
652/*
653 * Helpers
654 */
655
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100656/* Sets the current error to BlockingIOError */
657static void
658_set_BlockingIOError(char *msg, Py_ssize_t written)
659{
660 PyObject *err;
661 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
662 errno, msg, written);
663 if (err)
664 PyErr_SetObject(PyExc_BlockingIOError, err);
665 Py_XDECREF(err);
666}
667
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668/* Returns the address of the `written` member if a BlockingIOError was
669 raised, NULL otherwise. The error is always re-raised. */
670static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000671_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672{
673 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200674 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675
676 PyErr_Fetch(&t, &v, &tb);
677 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
678 PyErr_Restore(t, v, tb);
679 return NULL;
680 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200681 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 /* TODO: sanity check (err->written >= 0) */
683 PyErr_Restore(t, v, tb);
684 return &err->written;
685}
686
687static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000688_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000691 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
693 if (res == NULL)
694 return -1;
695 n = PyNumber_AsOff_t(res, PyExc_ValueError);
696 Py_DECREF(res);
697 if (n < 0) {
698 if (!PyErr_Occurred())
699 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000700 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200701 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 return -1;
703 }
704 self->abs_pos = n;
705 return n;
706}
707
708static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000709_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710{
711 PyObject *res, *posobj, *whenceobj;
712 Py_off_t n;
713
714 posobj = PyLong_FromOff_t(target);
715 if (posobj == NULL)
716 return -1;
717 whenceobj = PyLong_FromLong(whence);
718 if (whenceobj == NULL) {
719 Py_DECREF(posobj);
720 return -1;
721 }
722 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
723 posobj, whenceobj, NULL);
724 Py_DECREF(posobj);
725 Py_DECREF(whenceobj);
726 if (res == NULL)
727 return -1;
728 n = PyNumber_AsOff_t(res, PyExc_ValueError);
729 Py_DECREF(res);
730 if (n < 0) {
731 if (!PyErr_Occurred())
732 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000733 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200734 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000735 return -1;
736 }
737 self->abs_pos = n;
738 return n;
739}
740
741static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000742_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000743{
744 Py_ssize_t n;
745 if (self->buffer_size <= 0) {
746 PyErr_SetString(PyExc_ValueError,
747 "buffer size must be strictly positive");
748 return -1;
749 }
750 if (self->buffer)
751 PyMem_Free(self->buffer);
752 self->buffer = PyMem_Malloc(self->buffer_size);
753 if (self->buffer == NULL) {
754 PyErr_NoMemory();
755 return -1;
756 }
Georg Brandldfd73442009-04-05 11:47:34 +0000757#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000758 if (self->lock)
759 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000760 self->lock = PyThread_allocate_lock();
761 if (self->lock == NULL) {
762 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
763 return -1;
764 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000765 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000766#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000767 /* Find out whether buffer_size is a power of 2 */
768 /* XXX is this optimization useful? */
769 for (n = self->buffer_size - 1; n & 1; n >>= 1)
770 ;
771 if (n == 0)
772 self->buffer_mask = self->buffer_size - 1;
773 else
774 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000775 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000776 PyErr_Clear();
777 return 0;
778}
779
Antoine Pitrou707ce822011-02-25 21:24:11 +0000780/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
781 clears the error indicator), 0 otherwise.
782 Should only be called when PyErr_Occurred() is true.
783*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700784int
785_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000786{
787 static PyObject *eintr_int = NULL;
788 PyObject *typ, *val, *tb;
789 PyEnvironmentErrorObject *env_err;
790
791 if (eintr_int == NULL) {
792 eintr_int = PyLong_FromLong(EINTR);
793 assert(eintr_int != NULL);
794 }
795 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
796 return 0;
797 PyErr_Fetch(&typ, &val, &tb);
798 PyErr_NormalizeException(&typ, &val, &tb);
799 env_err = (PyEnvironmentErrorObject *) val;
800 assert(env_err != NULL);
801 if (env_err->myerrno != NULL &&
802 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
803 Py_DECREF(typ);
804 Py_DECREF(val);
805 Py_XDECREF(tb);
806 return 1;
807 }
808 /* This silences any error set by PyObject_RichCompareBool() */
809 PyErr_Restore(typ, val, tb);
810 return 0;
811}
812
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000813/*
814 * Shared methods and wrappers
815 */
816
817static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200818buffered_flush_and_rewind_unlocked(buffered *self)
819{
820 PyObject *res;
821
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100822 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200823 if (res == NULL)
824 return NULL;
825 Py_DECREF(res);
826
827 if (self->readable) {
828 /* Rewind the raw stream so that its position corresponds to
829 the current logical position. */
830 Py_off_t n;
831 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
832 _bufferedreader_reset_buf(self);
833 if (n == -1)
834 return NULL;
835 }
836 Py_RETURN_NONE;
837}
838
839static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000840buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841{
842 PyObject *res;
843
844 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000845 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000846
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000847 if (!ENTER_BUFFERED(self))
848 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200849 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850 LEAVE_BUFFERED(self)
851
852 return res;
853}
854
855static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000856buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000857{
858 Py_ssize_t n = 0;
859 PyObject *res = NULL;
860
861 CHECK_INITIALIZED(self)
862 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
863 return NULL;
864 }
865
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000866 if (!ENTER_BUFFERED(self))
867 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868
869 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200870 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871 if (res == NULL)
872 goto end;
873 Py_CLEAR(res);
874 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200875 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876
877end:
878 LEAVE_BUFFERED(self)
879 return res;
880}
881
882static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000883buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000884{
885 Py_ssize_t n = -1;
886 PyObject *res;
887
888 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000889 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890 return NULL;
891 }
892 if (n < -1) {
893 PyErr_SetString(PyExc_ValueError,
894 "read length must be positive or -1");
895 return NULL;
896 }
897
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000898 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000900 if (n == -1) {
901 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000902 if (!ENTER_BUFFERED(self))
903 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000904 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000905 }
906 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000907 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200908 if (res != Py_None)
909 return res;
910 Py_DECREF(res);
911 if (!ENTER_BUFFERED(self))
912 return NULL;
913 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000914 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915
Antoine Pitroue05565e2011-08-20 14:39:23 +0200916 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 return res;
918}
919
920static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000921buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922{
923 Py_ssize_t n, have, r;
924 PyObject *res = NULL;
925
926 CHECK_INITIALIZED(self)
927 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
928 return NULL;
929 }
930
931 if (n < 0) {
932 PyErr_SetString(PyExc_ValueError,
933 "read length must be positive");
934 return NULL;
935 }
936 if (n == 0)
937 return PyBytes_FromStringAndSize(NULL, 0);
938
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 /* Return up to n bytes. If at least one byte is buffered, we
940 only return buffered bytes. Otherwise, we do one raw read. */
941
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
943 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100944 n = Py_MIN(have, n);
945 res = _bufferedreader_read_fast(self, n);
946 assert(res != Py_None);
947 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100949 res = PyBytes_FromStringAndSize(NULL, n);
950 if (res == NULL)
951 return NULL;
952 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200953 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200955 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000956 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100957 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
958 LEAVE_BUFFERED(self)
959 if (r == -1) {
960 Py_DECREF(res);
961 return NULL;
962 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 if (r == -2)
964 r = 0;
965 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100966 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 return res;
968}
969
970static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000971buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200973 Py_buffer buf;
974 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000975 PyObject *res = NULL;
976
977 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200978
979 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
980 return NULL;
981
982 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
983 if (n > 0) {
984 if (n >= buf.len) {
985 memcpy(buf.buf, self->buffer + self->pos, buf.len);
986 self->pos += buf.len;
987 res = PyLong_FromSsize_t(buf.len);
988 goto end_unlocked;
989 }
990 memcpy(buf.buf, self->buffer + self->pos, n);
991 self->pos += n;
992 written = n;
993 }
994
995 if (!ENTER_BUFFERED(self))
996 goto end_unlocked;
997
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000998 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200999 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001000 if (res == NULL)
1001 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001004
1005 _bufferedreader_reset_buf(self);
1006 self->pos = 0;
1007
1008 for (remaining = buf.len - written;
1009 remaining > 0;
1010 written += n, remaining -= n) {
1011 /* If remaining bytes is larger than internal buffer size, copy
1012 * directly into caller's buffer. */
1013 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001014 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1015 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016 }
1017 else {
1018 n = _bufferedreader_fill_buffer(self);
1019 if (n > 0) {
1020 if (n > remaining)
1021 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001022 memcpy((char *) buf.buf + written,
1023 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001024 self->pos += n;
1025 continue; /* short circuit */
1026 }
1027 }
1028 if (n == 0 || (n == -2 && written > 0))
1029 break;
1030 if (n < 0) {
1031 if (n == -2) {
1032 Py_INCREF(Py_None);
1033 res = Py_None;
1034 }
1035 goto end;
1036 }
1037 }
1038 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001039
1040end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001041 LEAVE_BUFFERED(self);
1042end_unlocked:
1043 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044 return res;
1045}
1046
1047static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001048_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049{
1050 PyObject *res = NULL;
1051 PyObject *chunks = NULL;
1052 Py_ssize_t n, written = 0;
1053 const char *start, *s, *end;
1054
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001055 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001056
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001057 /* First, try to find a line in the buffer. This can run unlocked because
1058 the calls to the C API are simple enough that they can't trigger
1059 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001060 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1061 if (limit >= 0 && n > limit)
1062 n = limit;
1063 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001064 s = memchr(start, '\n', n);
1065 if (s != NULL) {
1066 res = PyBytes_FromStringAndSize(start, s - start + 1);
1067 if (res != NULL)
1068 self->pos += s - start + 1;
1069 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070 }
1071 if (n == limit) {
1072 res = PyBytes_FromStringAndSize(start, n);
1073 if (res != NULL)
1074 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001075 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001076 }
1077
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001078 if (!ENTER_BUFFERED(self))
1079 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001080
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001082 chunks = PyList_New(0);
1083 if (chunks == NULL)
1084 goto end;
1085 if (n > 0) {
1086 res = PyBytes_FromStringAndSize(start, n);
1087 if (res == NULL)
1088 goto end;
1089 if (PyList_Append(chunks, res) < 0) {
1090 Py_CLEAR(res);
1091 goto end;
1092 }
1093 Py_CLEAR(res);
1094 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001095 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001096 if (limit >= 0)
1097 limit -= n;
1098 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001099 if (self->writable) {
1100 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1101 if (r == NULL)
1102 goto end;
1103 Py_DECREF(r);
1104 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105
1106 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001107 _bufferedreader_reset_buf(self);
1108 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001109 if (n == -1)
1110 goto end;
1111 if (n <= 0)
1112 break;
1113 if (limit >= 0 && n > limit)
1114 n = limit;
1115 start = self->buffer;
1116 end = start + n;
1117 s = start;
1118 while (s < end) {
1119 if (*s++ == '\n') {
1120 res = PyBytes_FromStringAndSize(start, s - start);
1121 if (res == NULL)
1122 goto end;
1123 self->pos = s - start;
1124 goto found;
1125 }
1126 }
1127 res = PyBytes_FromStringAndSize(start, n);
1128 if (res == NULL)
1129 goto end;
1130 if (n == limit) {
1131 self->pos = n;
1132 break;
1133 }
1134 if (PyList_Append(chunks, res) < 0) {
1135 Py_CLEAR(res);
1136 goto end;
1137 }
1138 Py_CLEAR(res);
1139 written += n;
1140 if (limit >= 0)
1141 limit -= n;
1142 }
1143found:
1144 if (res != NULL && PyList_Append(chunks, res) < 0) {
1145 Py_CLEAR(res);
1146 goto end;
1147 }
1148 Py_CLEAR(res);
1149 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1150
1151end:
1152 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001153end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001154 Py_XDECREF(chunks);
1155 return res;
1156}
1157
1158static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001159buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001160{
1161 Py_ssize_t limit = -1;
1162
1163 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001164 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001165 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001166 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001167}
1168
1169
1170static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001171buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172{
1173 Py_off_t pos;
1174
1175 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001176 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177 if (pos == -1)
1178 return NULL;
1179 pos -= RAW_OFFSET(self);
1180 /* TODO: sanity check (pos >= 0) */
1181 return PyLong_FromOff_t(pos);
1182}
1183
1184static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001185buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186{
1187 Py_off_t target, n;
1188 int whence = 0;
1189 PyObject *targetobj, *res = NULL;
1190
1191 CHECK_INITIALIZED(self)
1192 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1193 return NULL;
1194 }
Jesus Cea94363612012-06-22 18:32:07 +02001195
1196 /* Do some error checking instead of trusting OS 'seek()'
1197 ** error detection, just in case.
1198 */
1199 if ((whence < 0 || whence >2)
1200#ifdef SEEK_HOLE
1201 && (whence != SEEK_HOLE)
1202#endif
1203#ifdef SEEK_DATA
1204 && (whence != SEEK_DATA)
1205#endif
1206 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001208 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209 return NULL;
1210 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001211
1212 CHECK_CLOSED(self, "seek of closed file")
1213
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001214 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1215 return NULL;
1216
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1218 if (target == -1 && PyErr_Occurred())
1219 return NULL;
1220
Jesus Cea94363612012-06-22 18:32:07 +02001221 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1222 buffer. Other whence values must be managed without this optimization.
1223 Some Operating Systems can provide additional values, like
1224 SEEK_HOLE/SEEK_DATA. */
1225 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226 Py_off_t current, avail;
1227 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001228 so as to return quickly if possible. Also, we needn't take the
1229 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001231 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1232 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001233 current = RAW_TELL(self);
1234 avail = READAHEAD(self);
1235 if (avail > 0) {
1236 Py_off_t offset;
1237 if (whence == 0)
1238 offset = target - (current - RAW_OFFSET(self));
1239 else
1240 offset = target;
1241 if (offset >= -self->pos && offset <= avail) {
1242 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001243 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244 }
1245 }
1246 }
1247
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001248 if (!ENTER_BUFFERED(self))
1249 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001250
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 /* Fallback: invoke raw seek() method and clear buffer */
1252 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001253 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 if (res == NULL)
1255 goto end;
1256 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001257 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001258 }
1259
1260 /* TODO: align on block boundary and read buffer if needed? */
1261 if (whence == 1)
1262 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001263 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 if (n == -1)
1265 goto end;
1266 self->raw_pos = -1;
1267 res = PyLong_FromOff_t(n);
1268 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001269 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270
1271end:
1272 LEAVE_BUFFERED(self)
1273 return res;
1274}
1275
1276static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001277buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278{
1279 PyObject *pos = Py_None;
1280 PyObject *res = NULL;
1281
1282 CHECK_INITIALIZED(self)
1283 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1284 return NULL;
1285 }
1286
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001287 if (!ENTER_BUFFERED(self))
1288 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289
1290 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001291 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 if (res == NULL)
1293 goto end;
1294 Py_CLEAR(res);
1295 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1297 if (res == NULL)
1298 goto end;
1299 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001300 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 PyErr_Clear();
1302
1303end:
1304 LEAVE_BUFFERED(self)
1305 return res;
1306}
1307
1308static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001309buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310{
1311 PyObject *line;
1312 PyTypeObject *tp;
1313
1314 CHECK_INITIALIZED(self);
1315
1316 tp = Py_TYPE(self);
1317 if (tp == &PyBufferedReader_Type ||
1318 tp == &PyBufferedRandom_Type) {
1319 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001320 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321 }
1322 else {
1323 line = PyObject_CallMethodObjArgs((PyObject *)self,
1324 _PyIO_str_readline, NULL);
1325 if (line && !PyBytes_Check(line)) {
1326 PyErr_Format(PyExc_IOError,
1327 "readline() should have returned a bytes object, "
1328 "not '%.200s'", Py_TYPE(line)->tp_name);
1329 Py_DECREF(line);
1330 return NULL;
1331 }
1332 }
1333
1334 if (line == NULL)
1335 return NULL;
1336
1337 if (PyBytes_GET_SIZE(line) == 0) {
1338 /* Reached EOF or would have blocked */
1339 Py_DECREF(line);
1340 return NULL;
1341 }
1342
1343 return line;
1344}
1345
Antoine Pitrou716c4442009-05-23 19:04:03 +00001346static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001347buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001348{
1349 PyObject *nameobj, *res;
1350
Martin v. Löwis767046a2011-10-14 15:35:36 +02001351 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001352 if (nameobj == NULL) {
1353 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1354 PyErr_Clear();
1355 else
1356 return NULL;
1357 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1358 }
1359 else {
1360 res = PyUnicode_FromFormat("<%s name=%R>",
1361 Py_TYPE(self)->tp_name, nameobj);
1362 Py_DECREF(nameobj);
1363 }
1364 return res;
1365}
1366
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367/*
1368 * class BufferedReader
1369 */
1370
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372 "Create a new buffered reader using the given readable raw IO object.");
1373
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001374static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001375{
1376 self->read_end = -1;
1377}
1378
1379static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001380bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381{
1382 char *kwlist[] = {"raw", "buffer_size", NULL};
1383 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1384 PyObject *raw;
1385
1386 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001387 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388
1389 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1390 &raw, &buffer_size)) {
1391 return -1;
1392 }
1393
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001394 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001395 return -1;
1396
1397 Py_CLEAR(self->raw);
1398 Py_INCREF(raw);
1399 self->raw = raw;
1400 self->buffer_size = buffer_size;
1401 self->readable = 1;
1402 self->writable = 0;
1403
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001404 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001405 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001406 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001407
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001408 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1409 Py_TYPE(raw) == &PyFileIO_Type);
1410
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411 self->ok = 1;
1412 return 0;
1413}
1414
1415static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001416_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001417{
1418 Py_buffer buf;
1419 PyObject *memobj, *res;
1420 Py_ssize_t n;
1421 /* NOTE: the buffer needn't be released as its object is NULL. */
1422 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1423 return -1;
1424 memobj = PyMemoryView_FromBuffer(&buf);
1425 if (memobj == NULL)
1426 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001427 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1428 occurs so we needn't do it ourselves.
1429 We then retry reading, ignoring the signal if no handler has
1430 raised (see issue #10956).
1431 */
1432 do {
1433 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001434 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 Py_DECREF(memobj);
1436 if (res == NULL)
1437 return -1;
1438 if (res == Py_None) {
1439 /* Non-blocking stream would have blocked. Special return code! */
1440 Py_DECREF(res);
1441 return -2;
1442 }
1443 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1444 Py_DECREF(res);
1445 if (n < 0 || n > len) {
1446 PyErr_Format(PyExc_IOError,
1447 "raw readinto() returned invalid length %zd "
1448 "(should have been between 0 and %zd)", n, len);
1449 return -1;
1450 }
1451 if (n > 0 && self->abs_pos != -1)
1452 self->abs_pos += n;
1453 return n;
1454}
1455
1456static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001457_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458{
1459 Py_ssize_t start, len, n;
1460 if (VALID_READ_BUFFER(self))
1461 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1462 else
1463 start = 0;
1464 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001465 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 if (n <= 0)
1467 return n;
1468 self->read_end = start + n;
1469 self->raw_pos = start + n;
1470 return n;
1471}
1472
1473static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001474_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001475{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001476 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001477 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001478
1479 /* First copy what we have in the current buffer. */
1480 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1481 if (current_size) {
1482 data = PyBytes_FromStringAndSize(
1483 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001484 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001485 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001486 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001487 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001488 /* We're going past the buffer's bounds, flush it */
1489 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001490 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001491 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001492 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001493 Py_CLEAR(res);
1494 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001495 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001496
1497 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1498 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1499 if (chunk == NULL)
1500 return NULL;
1501 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1502 Py_XDECREF(data);
1503 Py_DECREF(chunk);
1504 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1505 return NULL;
1506 }
1507 if (chunk == Py_None) {
1508 if (current_size == 0)
1509 return chunk;
1510 else {
1511 Py_DECREF(chunk);
1512 return data;
1513 }
1514 }
1515 else if (current_size) {
1516 PyBytes_Concat(&data, chunk);
1517 Py_DECREF(chunk);
1518 if (data == NULL)
1519 return NULL;
1520 return data;
1521 } else
1522 return chunk;
1523 }
1524
1525 chunks = PyList_New(0);
Christian Heimes8f734eb2012-09-10 17:46:09 +02001526 if (chunks == NULL) {
1527 Py_XDECREF(data);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001528 return NULL;
Christian Heimes8f734eb2012-09-10 17:46:09 +02001529 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001530
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001531 while (1) {
1532 if (data) {
1533 if (PyList_Append(chunks, data) < 0) {
1534 Py_DECREF(data);
1535 Py_DECREF(chunks);
1536 return NULL;
1537 }
1538 Py_DECREF(data);
1539 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001540
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001541 /* Read until EOF or until read() would block. */
1542 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1543 if (data == NULL) {
1544 Py_DECREF(chunks);
1545 return NULL;
1546 }
1547 if (data != Py_None && !PyBytes_Check(data)) {
1548 Py_DECREF(data);
1549 Py_DECREF(chunks);
1550 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1551 return NULL;
1552 }
1553 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1554 if (current_size == 0) {
1555 Py_DECREF(chunks);
1556 return data;
1557 }
1558 else {
1559 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1560 Py_DECREF(data);
1561 Py_DECREF(chunks);
1562 return res;
1563 }
1564 }
1565 current_size += PyBytes_GET_SIZE(data);
1566 if (self->abs_pos != -1)
1567 self->abs_pos += PyBytes_GET_SIZE(data);
1568 }
1569}
1570
1571/* Read n bytes from the buffer if it can, otherwise return None.
1572 This function is simple enough that it can run unlocked. */
1573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001574_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001575{
1576 Py_ssize_t current_size;
1577
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001578 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1579 if (n <= current_size) {
1580 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1582 if (res != NULL)
1583 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001584 return res;
1585 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586 Py_RETURN_NONE;
1587}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001588
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001589/* Generic read function: read from the stream until enough bytes are read,
1590 * or until an EOF occurs or until read() would block.
1591 */
1592static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001593_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594{
1595 PyObject *res = NULL;
1596 Py_ssize_t current_size, remaining, written;
1597 char *out;
1598
1599 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1600 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001601 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001603 res = PyBytes_FromStringAndSize(NULL, n);
1604 if (res == NULL)
1605 goto error;
1606 out = PyBytes_AS_STRING(res);
1607 remaining = n;
1608 written = 0;
1609 if (current_size > 0) {
1610 memcpy(out, self->buffer + self->pos, current_size);
1611 remaining -= current_size;
1612 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001613 self->pos += current_size;
1614 }
1615 /* Flush the write buffer if necessary */
1616 if (self->writable) {
1617 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1618 if (r == NULL)
1619 goto error;
1620 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001621 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001622 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001623 while (remaining > 0) {
1624 /* We want to read a whole block at the end into buffer.
1625 If we had readv() we could do this in one pass. */
1626 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1627 if (r == 0)
1628 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630 if (r == -1)
1631 goto error;
1632 if (r == 0 || r == -2) {
1633 /* EOF occurred or read() would block. */
1634 if (r == 0 || written > 0) {
1635 if (_PyBytes_Resize(&res, written))
1636 goto error;
1637 return res;
1638 }
1639 Py_DECREF(res);
1640 Py_INCREF(Py_None);
1641 return Py_None;
1642 }
1643 remaining -= r;
1644 written += r;
1645 }
1646 assert(remaining <= self->buffer_size);
1647 self->pos = 0;
1648 self->raw_pos = 0;
1649 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001650 /* NOTE: when the read is satisfied, we avoid issuing any additional
1651 reads, which could block indefinitely (e.g. on a socket).
1652 See issue #9550. */
1653 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001654 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001655 if (r == -1)
1656 goto error;
1657 if (r == 0 || r == -2) {
1658 /* EOF occurred or read() would block. */
1659 if (r == 0 || written > 0) {
1660 if (_PyBytes_Resize(&res, written))
1661 goto error;
1662 return res;
1663 }
1664 Py_DECREF(res);
1665 Py_INCREF(Py_None);
1666 return Py_None;
1667 }
1668 if (remaining > r) {
1669 memcpy(out + written, self->buffer + self->pos, r);
1670 written += r;
1671 self->pos += r;
1672 remaining -= r;
1673 }
1674 else if (remaining > 0) {
1675 memcpy(out + written, self->buffer + self->pos, remaining);
1676 written += remaining;
1677 self->pos += remaining;
1678 remaining = 0;
1679 }
1680 if (remaining == 0)
1681 break;
1682 }
1683
1684 return res;
1685
1686error:
1687 Py_XDECREF(res);
1688 return NULL;
1689}
1690
1691static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001692_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693{
1694 Py_ssize_t have, r;
1695
1696 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1697 /* Constraints:
1698 1. we don't want to advance the file position.
1699 2. we don't want to lose block alignment, so we can't shift the buffer
1700 to make some place.
1701 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1702 */
1703 if (have > 0) {
1704 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1705 }
1706
1707 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001708 _bufferedreader_reset_buf(self);
1709 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001710 if (r == -1)
1711 return NULL;
1712 if (r == -2)
1713 r = 0;
1714 self->pos = 0;
1715 return PyBytes_FromStringAndSize(self->buffer, r);
1716}
1717
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001718static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001720 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1721 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1722 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1723 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1724 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1725 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1726 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1727 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001728 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001729 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001730
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001731 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1732 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1733 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001734 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1736 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1737 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1738 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001739 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001740 {NULL, NULL}
1741};
1742
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001743static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001744 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745 {NULL}
1746};
1747
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001748static PyGetSetDef bufferedreader_getset[] = {
1749 {"closed", (getter)buffered_closed_get, NULL, NULL},
1750 {"name", (getter)buffered_name_get, NULL, NULL},
1751 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001752 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001753};
1754
1755
1756PyTypeObject PyBufferedReader_Type = {
1757 PyVarObject_HEAD_INIT(NULL, 0)
1758 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001759 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001761 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762 0, /*tp_print*/
1763 0, /*tp_getattr*/
1764 0, /*tp_setattr*/
1765 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001766 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767 0, /*tp_as_number*/
1768 0, /*tp_as_sequence*/
1769 0, /*tp_as_mapping*/
1770 0, /*tp_hash */
1771 0, /*tp_call*/
1772 0, /*tp_str*/
1773 0, /*tp_getattro*/
1774 0, /*tp_setattro*/
1775 0, /*tp_as_buffer*/
1776 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1777 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001778 bufferedreader_doc, /* tp_doc */
1779 (traverseproc)buffered_traverse, /* tp_traverse */
1780 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001782 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784 (iternextfunc)buffered_iternext, /* tp_iternext */
1785 bufferedreader_methods, /* tp_methods */
1786 bufferedreader_members, /* tp_members */
1787 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 0, /* tp_base */
1789 0, /* tp_dict */
1790 0, /* tp_descr_get */
1791 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001792 offsetof(buffered, dict), /* tp_dictoffset */
1793 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794 0, /* tp_alloc */
1795 PyType_GenericNew, /* tp_new */
1796};
1797
1798
Benjamin Peterson59406a92009-03-26 17:10:29 +00001799
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800/*
1801 * class BufferedWriter
1802 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001803PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 "A buffer for a writeable sequential RawIO object.\n"
1805 "\n"
1806 "The constructor creates a BufferedWriter for the given writeable raw\n"
1807 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001808 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 );
1810
1811static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813{
1814 self->write_pos = 0;
1815 self->write_end = -1;
1816}
1817
1818static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001819bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820{
Florent Xicluna109d5732012-07-07 17:03:22 +02001821 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823 PyObject *raw;
1824
1825 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001826 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827
R David Murray9f10f562013-02-23 22:07:55 -05001828 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001829 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830 return -1;
1831 }
1832
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001833 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834 return -1;
1835
1836 Py_CLEAR(self->raw);
1837 Py_INCREF(raw);
1838 self->raw = raw;
1839 self->readable = 0;
1840 self->writable = 1;
1841
1842 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001843 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001845 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 self->pos = 0;
1847
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001848 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1849 Py_TYPE(raw) == &PyFileIO_Type);
1850
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 self->ok = 1;
1852 return 0;
1853}
1854
1855static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001856_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001857{
1858 Py_buffer buf;
1859 PyObject *memobj, *res;
1860 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001861 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862 /* NOTE: the buffer needn't be released as its object is NULL. */
1863 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1864 return -1;
1865 memobj = PyMemoryView_FromBuffer(&buf);
1866 if (memobj == NULL)
1867 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001868 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1869 occurs so we needn't do it ourselves.
1870 We then retry writing, ignoring the signal if no handler has
1871 raised (see issue #10956).
1872 */
1873 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001874 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001875 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001876 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001877 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001878 Py_DECREF(memobj);
1879 if (res == NULL)
1880 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881 if (res == Py_None) {
1882 /* Non-blocking stream would have blocked. Special return code!
1883 Being paranoid we reset errno in case it is changed by code
1884 triggered by a decref. errno is used by _set_BlockingIOError(). */
1885 Py_DECREF(res);
1886 errno = errnum;
1887 return -2;
1888 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1890 Py_DECREF(res);
1891 if (n < 0 || n > len) {
1892 PyErr_Format(PyExc_IOError,
1893 "raw write() returned invalid length %zd "
1894 "(should have been between 0 and %zd)", n, len);
1895 return -1;
1896 }
1897 if (n > 0 && self->abs_pos != -1)
1898 self->abs_pos += n;
1899 return n;
1900}
1901
1902/* `restore_pos` is 1 if we need to restore the raw stream position at
1903 the end, 0 otherwise. */
1904static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001905_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906{
1907 Py_ssize_t written = 0;
1908 Py_off_t n, rewind;
1909
1910 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1911 goto end;
1912 /* First, rewind */
1913 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1914 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001915 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916 if (n < 0) {
1917 goto error;
1918 }
1919 self->raw_pos -= rewind;
1920 }
1921 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001922 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923 self->buffer + self->write_pos,
1924 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1925 Py_off_t, Py_ssize_t));
1926 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001927 goto error;
1928 }
1929 else if (n == -2) {
1930 _set_BlockingIOError("write could not complete without blocking",
1931 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001932 goto error;
1933 }
1934 self->write_pos += n;
1935 self->raw_pos = self->write_pos;
1936 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001937 /* Partial writes can return successfully when interrupted by a
1938 signal (see write(2)). We must run signal handlers before
1939 blocking another time, possibly indefinitely. */
1940 if (PyErr_CheckSignals() < 0)
1941 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942 }
1943
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001944 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945
1946end:
1947 Py_RETURN_NONE;
1948
1949error:
1950 return NULL;
1951}
1952
1953static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001954bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955{
1956 PyObject *res = NULL;
1957 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001958 Py_ssize_t written, avail, remaining;
1959 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001960
1961 CHECK_INITIALIZED(self)
1962 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1963 return NULL;
1964 }
1965
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001966 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 PyErr_SetString(PyExc_ValueError, "write to closed file");
1968 PyBuffer_Release(&buf);
1969 return NULL;
1970 }
1971
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001972 if (!ENTER_BUFFERED(self)) {
1973 PyBuffer_Release(&buf);
1974 return NULL;
1975 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976
1977 /* Fast path: the data to write can be fully buffered. */
1978 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1979 self->pos = 0;
1980 self->raw_pos = 0;
1981 }
1982 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1983 if (buf.len <= avail) {
1984 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001985 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001986 self->write_pos = self->pos;
1987 }
1988 ADJUST_POSITION(self, self->pos + buf.len);
1989 if (self->pos > self->write_end)
1990 self->write_end = self->pos;
1991 written = buf.len;
1992 goto end;
1993 }
1994
1995 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001996 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001997 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001998 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 if (w == NULL)
2000 goto error;
2001 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002002 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003 /* Make some place by shifting the buffer. */
2004 assert(VALID_WRITE_BUFFER(self));
2005 memmove(self->buffer, self->buffer + self->write_pos,
2006 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2007 Py_off_t, Py_ssize_t));
2008 self->write_end -= self->write_pos;
2009 self->raw_pos -= self->write_pos;
2010 self->pos -= self->write_pos;
2011 self->write_pos = 0;
2012 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2013 Py_off_t, Py_ssize_t);
2014 if (buf.len <= avail) {
2015 /* Everything can be buffered */
2016 PyErr_Clear();
2017 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2018 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002019 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 written = buf.len;
2021 goto end;
2022 }
2023 /* Buffer as much as possible. */
2024 memcpy(self->buffer + self->write_end, buf.buf, avail);
2025 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002026 self->pos += avail;
2027 /* XXX Modifying the existing exception e using the pointer w
2028 will change e.characters_written but not e.args[2].
2029 Therefore we just replace with a new error. */
2030 _set_BlockingIOError("write could not complete without blocking",
2031 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002032 goto error;
2033 }
2034 Py_CLEAR(res);
2035
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002036 /* Adjust the raw stream position if it is away from the logical stream
2037 position. This happens if the read buffer has been filled but not
2038 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2039 the raw stream by itself).
2040 Fixes issue #6629.
2041 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002042 offset = RAW_OFFSET(self);
2043 if (offset != 0) {
2044 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002045 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002046 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002047 }
2048
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002049 /* Then write buf itself. At this point the buffer has been emptied. */
2050 remaining = buf.len;
2051 written = 0;
2052 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002053 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 self, (char *) buf.buf + written, buf.len - written);
2055 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002056 goto error;
2057 } else if (n == -2) {
2058 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059 if (remaining > self->buffer_size) {
2060 /* Can't buffer everything, still buffer as much as possible */
2061 memcpy(self->buffer,
2062 (char *) buf.buf + written, self->buffer_size);
2063 self->raw_pos = 0;
2064 ADJUST_POSITION(self, self->buffer_size);
2065 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002066 written += self->buffer_size;
2067 _set_BlockingIOError("write could not complete without "
2068 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002069 goto error;
2070 }
2071 PyErr_Clear();
2072 break;
2073 }
2074 written += n;
2075 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002076 /* Partial writes can return successfully when interrupted by a
2077 signal (see write(2)). We must run signal handlers before
2078 blocking another time, possibly indefinitely. */
2079 if (PyErr_CheckSignals() < 0)
2080 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 }
2082 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002083 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002084 if (remaining > 0) {
2085 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2086 written += remaining;
2087 }
2088 self->write_pos = 0;
2089 /* TODO: sanity check (remaining >= 0) */
2090 self->write_end = remaining;
2091 ADJUST_POSITION(self, remaining);
2092 self->raw_pos = 0;
2093
2094end:
2095 res = PyLong_FromSsize_t(written);
2096
2097error:
2098 LEAVE_BUFFERED(self)
2099 PyBuffer_Release(&buf);
2100 return res;
2101}
2102
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2106 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2107 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2108 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2109 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2110 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2111 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002112 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002113 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002114
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002115 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2116 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2117 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2118 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2119 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002120 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121 {NULL, NULL}
2122};
2123
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002124static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002125 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002126 {NULL}
2127};
2128
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129static PyGetSetDef bufferedwriter_getset[] = {
2130 {"closed", (getter)buffered_closed_get, NULL, NULL},
2131 {"name", (getter)buffered_name_get, NULL, NULL},
2132 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002133 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002134};
2135
2136
2137PyTypeObject PyBufferedWriter_Type = {
2138 PyVarObject_HEAD_INIT(NULL, 0)
2139 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002140 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002142 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143 0, /*tp_print*/
2144 0, /*tp_getattr*/
2145 0, /*tp_setattr*/
2146 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148 0, /*tp_as_number*/
2149 0, /*tp_as_sequence*/
2150 0, /*tp_as_mapping*/
2151 0, /*tp_hash */
2152 0, /*tp_call*/
2153 0, /*tp_str*/
2154 0, /*tp_getattro*/
2155 0, /*tp_setattro*/
2156 0, /*tp_as_buffer*/
2157 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2158 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002159 bufferedwriter_doc, /* tp_doc */
2160 (traverseproc)buffered_traverse, /* tp_traverse */
2161 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002162 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002163 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002164 0, /* tp_iter */
2165 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002166 bufferedwriter_methods, /* tp_methods */
2167 bufferedwriter_members, /* tp_members */
2168 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 0, /* tp_base */
2170 0, /* tp_dict */
2171 0, /* tp_descr_get */
2172 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002173 offsetof(buffered, dict), /* tp_dictoffset */
2174 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175 0, /* tp_alloc */
2176 PyType_GenericNew, /* tp_new */
2177};
2178
2179
2180
2181/*
2182 * BufferedRWPair
2183 */
2184
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002185PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186 "A buffered reader and writer object together.\n"
2187 "\n"
2188 "A buffered reader object and buffered writer object put together to\n"
2189 "form a sequential IO object that can read and write. This is typically\n"
2190 "used with a socket or two-way pipe.\n"
2191 "\n"
2192 "reader and writer are RawIOBase objects that are readable and\n"
2193 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002194 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195 );
2196
2197/* XXX The usefulness of this (compared to having two separate IO objects) is
2198 * questionable.
2199 */
2200
2201typedef struct {
2202 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002203 buffered *reader;
2204 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205 PyObject *dict;
2206 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002207} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208
2209static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211{
2212 PyObject *reader, *writer;
2213 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214
Florent Xicluna109d5732012-07-07 17:03:22 +02002215 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2216 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217 return -1;
2218 }
2219
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002220 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223 return -1;
2224
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002225 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002226 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227 if (self->reader == NULL)
2228 return -1;
2229
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002230 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002231 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232 if (self->writer == NULL) {
2233 Py_CLEAR(self->reader);
2234 return -1;
2235 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002236
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237 return 0;
2238}
2239
2240static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002241bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242{
2243 Py_VISIT(self->dict);
2244 return 0;
2245}
2246
2247static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002248bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249{
2250 Py_CLEAR(self->reader);
2251 Py_CLEAR(self->writer);
2252 Py_CLEAR(self->dict);
2253 return 0;
2254}
2255
2256static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002257bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002258{
2259 _PyObject_GC_UNTRACK(self);
2260 Py_CLEAR(self->reader);
2261 Py_CLEAR(self->writer);
2262 Py_CLEAR(self->dict);
2263 Py_TYPE(self)->tp_free((PyObject *) self);
2264}
2265
2266static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002267_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002268{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002269 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270 PyObject *ret;
2271
2272 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002273 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002274 return NULL;
2275 }
2276
2277 ret = PyObject_CallObject(func, args);
2278 Py_DECREF(func);
2279 return ret;
2280}
2281
2282static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002283bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002284{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002285 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286}
2287
2288static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002291 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002292}
2293
2294static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002295bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002297 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298}
2299
2300static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002301bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002302{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002303 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002304}
2305
2306static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002307bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002309 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002310}
2311
2312static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002313bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002314{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002315 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002316}
2317
2318static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002319bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002320{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002321 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002322}
2323
2324static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002325bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002326{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002327 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328}
2329
2330static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002331bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002332{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002333 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334 if (ret == NULL)
2335 return NULL;
2336 Py_DECREF(ret);
2337
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002338 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339}
2340
2341static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002342bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002343{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002344 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002345
2346 if (ret != Py_False) {
2347 /* either True or exception */
2348 return ret;
2349 }
2350 Py_DECREF(ret);
2351
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002352 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002353}
2354
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002355static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002356bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002357{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002358 if (self->writer == NULL) {
2359 PyErr_SetString(PyExc_RuntimeError,
2360 "the BufferedRWPair object is being garbage-collected");
2361 return NULL;
2362 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002363 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2364}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002365
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002366static PyMethodDef bufferedrwpair_methods[] = {
2367 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2368 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2369 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2370 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002372 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2373 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002374
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002375 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2376 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002378 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2379 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002380
Antoine Pitrou243757e2010-11-05 21:15:39 +00002381 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2382
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002383 {NULL, NULL}
2384};
2385
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002386static PyGetSetDef bufferedrwpair_getset[] = {
2387 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002388 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002389};
2390
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002391PyTypeObject PyBufferedRWPair_Type = {
2392 PyVarObject_HEAD_INIT(NULL, 0)
2393 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002394 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002395 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002396 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002397 0, /*tp_print*/
2398 0, /*tp_getattr*/
2399 0, /*tp_setattr*/
2400 0, /*tp_compare */
2401 0, /*tp_repr*/
2402 0, /*tp_as_number*/
2403 0, /*tp_as_sequence*/
2404 0, /*tp_as_mapping*/
2405 0, /*tp_hash */
2406 0, /*tp_call*/
2407 0, /*tp_str*/
2408 0, /*tp_getattro*/
2409 0, /*tp_setattro*/
2410 0, /*tp_as_buffer*/
2411 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2412 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002413 bufferedrwpair_doc, /* tp_doc */
2414 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2415 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002416 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002417 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 0, /* tp_iter */
2419 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002420 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002422 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002423 0, /* tp_base */
2424 0, /* tp_dict */
2425 0, /* tp_descr_get */
2426 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002427 offsetof(rwpair, dict), /* tp_dictoffset */
2428 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002429 0, /* tp_alloc */
2430 PyType_GenericNew, /* tp_new */
2431};
2432
2433
2434
2435/*
2436 * BufferedRandom
2437 */
2438
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002439PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002440 "A buffered interface to random access streams.\n"
2441 "\n"
2442 "The constructor creates a reader and writer for a seekable stream,\n"
2443 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002444 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002445 );
2446
2447static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002448bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002449{
Florent Xicluna109d5732012-07-07 17:03:22 +02002450 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002451 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002452 PyObject *raw;
2453
2454 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002455 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456
R David Murray9f10f562013-02-23 22:07:55 -05002457 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002458 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459 return -1;
2460 }
2461
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002462 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002463 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002464 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002465 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002466 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002467 return -1;
2468
2469 Py_CLEAR(self->raw);
2470 Py_INCREF(raw);
2471 self->raw = raw;
2472 self->buffer_size = buffer_size;
2473 self->readable = 1;
2474 self->writable = 1;
2475
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002476 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002477 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002478 _bufferedreader_reset_buf(self);
2479 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002480 self->pos = 0;
2481
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002482 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2483 Py_TYPE(raw) == &PyFileIO_Type);
2484
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485 self->ok = 1;
2486 return 0;
2487}
2488
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002489static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002490 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002491 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2492 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2493 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2494 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2495 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2496 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2497 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002498 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002499 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002501 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002502
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002503 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2504 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2505 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2506 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2507 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2508 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2509 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2510 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2511 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002512 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002513 {NULL, NULL}
2514};
2515
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002516static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002517 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002518 {NULL}
2519};
2520
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002521static PyGetSetDef bufferedrandom_getset[] = {
2522 {"closed", (getter)buffered_closed_get, NULL, NULL},
2523 {"name", (getter)buffered_name_get, NULL, NULL},
2524 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002525 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002526};
2527
2528
2529PyTypeObject PyBufferedRandom_Type = {
2530 PyVarObject_HEAD_INIT(NULL, 0)
2531 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002532 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002533 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002534 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 0, /*tp_print*/
2536 0, /*tp_getattr*/
2537 0, /*tp_setattr*/
2538 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002539 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002540 0, /*tp_as_number*/
2541 0, /*tp_as_sequence*/
2542 0, /*tp_as_mapping*/
2543 0, /*tp_hash */
2544 0, /*tp_call*/
2545 0, /*tp_str*/
2546 0, /*tp_getattro*/
2547 0, /*tp_setattro*/
2548 0, /*tp_as_buffer*/
2549 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2550 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002551 bufferedrandom_doc, /* tp_doc */
2552 (traverseproc)buffered_traverse, /* tp_traverse */
2553 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002554 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002555 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002556 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002557 (iternextfunc)buffered_iternext, /* tp_iternext */
2558 bufferedrandom_methods, /* tp_methods */
2559 bufferedrandom_members, /* tp_members */
2560 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002561 0, /* tp_base */
2562 0, /*tp_dict*/
2563 0, /* tp_descr_get */
2564 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002565 offsetof(buffered, dict), /*tp_dictoffset*/
2566 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002567 0, /* tp_alloc */
2568 PyType_GenericNew, /* tp_new */
2569};