blob: b077f34fff8c49d63031292964880d6fede7a426 [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);
72 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
73
74 PyBuffer_Release(&buf);
75 Py_DECREF(data);
76
77 return PyLong_FromSsize_t(len);
78
79 error:
80 PyBuffer_Release(&buf);
81 return NULL;
82}
83
84static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000085bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000086{
87 PyErr_SetString(IO_STATE->unsupported_operation, message);
88 return NULL;
89}
90
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000091PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000092 "Disconnect this buffer from its underlying raw stream and return it.\n"
93 "\n"
94 "After the raw stream has been detached, the buffer is in an unusable\n"
95 "state.\n");
96
97static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000098bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +000099{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000100 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000101}
102
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000103PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000104 "Read and return up to n bytes.\n"
105 "\n"
106 "If the argument is omitted, None, or negative, reads and\n"
107 "returns all data until EOF.\n"
108 "\n"
109 "If the argument is positive, and the underlying raw stream is\n"
110 "not 'interactive', multiple raw reads may be issued to satisfy\n"
111 "the byte count (unless EOF is reached first). But for\n"
112 "interactive raw streams (as well as sockets and pipes), at most\n"
113 "one raw read will be issued, and a short result does not imply\n"
114 "that EOF is imminent.\n"
115 "\n"
116 "Returns an empty bytes object on EOF.\n"
117 "\n"
118 "Returns None if the underlying raw stream was open in non-blocking\n"
119 "mode and no data is available at the moment.\n");
120
121static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000124 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000125}
126
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000127PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000128 "Read and return up to n bytes, with at most one read() call\n"
129 "to the underlying raw stream. A short result does not imply\n"
130 "that EOF is imminent.\n"
131 "\n"
132 "Returns an empty bytes object on EOF.\n");
133
134static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000137 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000138}
139
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000140PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000141 "Write the given buffer to the IO stream.\n"
142 "\n"
143 "Returns the number of bytes written, which is never less than\n"
144 "len(b).\n"
145 "\n"
146 "Raises BlockingIOError if the buffer is full and the\n"
147 "underlying raw stream cannot accept more data at the moment.\n");
148
149static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000151{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000152 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000153}
154
155
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000156static PyMethodDef bufferediobase_methods[] = {
157 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
158 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
159 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
160 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
161 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000162 {NULL, NULL}
163};
164
165PyTypeObject PyBufferedIOBase_Type = {
166 PyVarObject_HEAD_INIT(NULL, 0)
167 "_io._BufferedIOBase", /*tp_name*/
168 0, /*tp_basicsize*/
169 0, /*tp_itemsize*/
170 0, /*tp_dealloc*/
171 0, /*tp_print*/
172 0, /*tp_getattr*/
173 0, /*tp_setattr*/
174 0, /*tp_compare */
175 0, /*tp_repr*/
176 0, /*tp_as_number*/
177 0, /*tp_as_sequence*/
178 0, /*tp_as_mapping*/
179 0, /*tp_hash */
180 0, /*tp_call*/
181 0, /*tp_str*/
182 0, /*tp_getattro*/
183 0, /*tp_setattro*/
184 0, /*tp_as_buffer*/
185 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000186 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000187 0, /* tp_traverse */
188 0, /* tp_clear */
189 0, /* tp_richcompare */
190 0, /* tp_weaklistoffset */
191 0, /* tp_iter */
192 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000193 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000194 0, /* tp_members */
195 0, /* tp_getset */
196 &PyIOBase_Type, /* tp_base */
197 0, /* tp_dict */
198 0, /* tp_descr_get */
199 0, /* tp_descr_set */
200 0, /* tp_dictoffset */
201 0, /* tp_init */
202 0, /* tp_alloc */
203 0, /* tp_new */
204};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000205
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206
207typedef struct {
208 PyObject_HEAD
209
210 PyObject *raw;
211 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000212 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213 int readable;
214 int writable;
Antoine Pitroue033e062010-10-29 10:38:18 +0000215 int deallocating;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200216
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000217 /* True if this is a vanilla Buffered object (rather than a user derived
218 class) *and* the raw stream is a vanilla FileIO object. */
219 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000220
221 /* Absolute position inside the raw stream (-1 if unknown). */
222 Py_off_t abs_pos;
223
224 /* A static buffer of size `buffer_size` */
225 char *buffer;
226 /* Current logical position in the buffer. */
227 Py_off_t pos;
228 /* Position of the raw stream in the buffer. */
229 Py_off_t raw_pos;
230
231 /* Just after the last buffered byte in the buffer, or -1 if the buffer
232 isn't ready for reading. */
233 Py_off_t read_end;
234
235 /* Just after the last byte actually written */
236 Py_off_t write_pos;
237 /* Just after the last byte waiting to be written, or -1 if the buffer
238 isn't ready for writing. */
239 Py_off_t write_end;
240
Georg Brandldfd73442009-04-05 11:47:34 +0000241#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000242 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000243 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000244#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000245
246 Py_ssize_t buffer_size;
247 Py_ssize_t buffer_mask;
248
249 PyObject *dict;
250 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000251} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000252
253/*
254 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200255
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000256 * BufferedReader, BufferedWriter and BufferedRandom try to share most
257 methods (this is helped by the members `readable` and `writable`, which
258 are initialized in the respective constructors)
259 * They also share a single buffer for reading and writing. This enables
260 interleaved reads and writes without flushing. It also makes the logic
261 a bit trickier to get right.
262 * The absolute position of the raw stream is cached, if possible, in the
263 `abs_pos` member. It must be updated every time an operation is done
264 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000265 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000266 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000267 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
268 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000269
270 NOTE: we should try to maintain block alignment of reads and writes to the
271 raw stream (according to the buffer size), but for now it is only done
272 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200273
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000274*/
275
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000276/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000277
Georg Brandldfd73442009-04-05 11:47:34 +0000278#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000279
280static int
281_enter_buffered_busy(buffered *self)
282{
283 if (self->owner == PyThread_get_thread_ident()) {
284 PyErr_Format(PyExc_RuntimeError,
285 "reentrant call inside %R", self);
286 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000287 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000288 Py_BEGIN_ALLOW_THREADS
289 PyThread_acquire_lock(self->lock, 1);
290 Py_END_ALLOW_THREADS
291 return 1;
292}
293
294#define ENTER_BUFFERED(self) \
295 ( (PyThread_acquire_lock(self->lock, 0) ? \
296 1 : _enter_buffered_busy(self)) \
297 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000298
299#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000300 do { \
301 self->owner = 0; \
302 PyThread_release_lock(self->lock); \
303 } while(0);
304
Georg Brandldfd73442009-04-05 11:47:34 +0000305#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000306#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000307#define LEAVE_BUFFERED(self)
308#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000309
310#define CHECK_INITIALIZED(self) \
311 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000312 if (self->detached) { \
313 PyErr_SetString(PyExc_ValueError, \
314 "raw stream has been detached"); \
315 } else { \
316 PyErr_SetString(PyExc_ValueError, \
317 "I/O operation on uninitialized object"); \
318 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000319 return NULL; \
320 }
321
322#define CHECK_INITIALIZED_INT(self) \
323 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000324 if (self->detached) { \
325 PyErr_SetString(PyExc_ValueError, \
326 "raw stream has been detached"); \
327 } else { \
328 PyErr_SetString(PyExc_ValueError, \
329 "I/O operation on uninitialized object"); \
330 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000331 return -1; \
332 }
333
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000334#define IS_CLOSED(self) \
335 (self->fast_closed_checks \
336 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000337 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000338
339#define CHECK_CLOSED(self, error_msg) \
340 if (IS_CLOSED(self)) { \
341 PyErr_SetString(PyExc_ValueError, error_msg); \
342 return NULL; \
343 }
344
345
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000346#define VALID_READ_BUFFER(self) \
347 (self->readable && self->read_end != -1)
348
349#define VALID_WRITE_BUFFER(self) \
350 (self->writable && self->write_end != -1)
351
352#define ADJUST_POSITION(self, _new_pos) \
353 do { \
354 self->pos = _new_pos; \
355 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
356 self->read_end = self->pos; \
357 } while(0)
358
359#define READAHEAD(self) \
360 ((self->readable && VALID_READ_BUFFER(self)) \
361 ? (self->read_end - self->pos) : 0)
362
363#define RAW_OFFSET(self) \
364 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
365 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
366
367#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000368 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000369
370#define MINUS_LAST_BLOCK(self, size) \
371 (self->buffer_mask ? \
372 (size & ~self->buffer_mask) : \
373 (self->buffer_size * (size / self->buffer_size)))
374
375
376static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000377buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000378{
Antoine Pitroue033e062010-10-29 10:38:18 +0000379 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000380 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
381 return;
382 _PyObject_GC_UNTRACK(self);
383 self->ok = 0;
384 if (self->weakreflist != NULL)
385 PyObject_ClearWeakRefs((PyObject *)self);
386 Py_CLEAR(self->raw);
387 if (self->buffer) {
388 PyMem_Free(self->buffer);
389 self->buffer = NULL;
390 }
Georg Brandldfd73442009-04-05 11:47:34 +0000391#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000392 if (self->lock) {
393 PyThread_free_lock(self->lock);
394 self->lock = NULL;
395 }
Georg Brandldfd73442009-04-05 11:47:34 +0000396#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000397 Py_CLEAR(self->dict);
398 Py_TYPE(self)->tp_free((PyObject *)self);
399}
400
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200401static PyObject *
402buffered_sizeof(buffered *self, void *unused)
403{
404 Py_ssize_t res;
405
406 res = sizeof(buffered);
407 if (self->buffer)
408 res += self->buffer_size;
409 return PyLong_FromSsize_t(res);
410}
411
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000412static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000413buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000414{
415 Py_VISIT(self->raw);
416 Py_VISIT(self->dict);
417 return 0;
418}
419
420static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000421buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422{
423 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
424 return -1;
425 self->ok = 0;
426 Py_CLEAR(self->raw);
427 Py_CLEAR(self->dict);
428 return 0;
429}
430
Antoine Pitroue033e062010-10-29 10:38:18 +0000431/* Because this can call arbitrary code, it shouldn't be called when
432 the refcount is 0 (that is, not directly from tp_dealloc unless
433 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000434static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000435buffered_dealloc_warn(buffered *self, PyObject *source)
436{
437 if (self->ok && self->raw) {
438 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200439 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000440 if (r)
441 Py_DECREF(r);
442 else
443 PyErr_Clear();
444 }
445 Py_RETURN_NONE;
446}
447
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000448/*
449 * _BufferedIOMixin methods
450 * This is not a class, just a collection of methods that will be reused
451 * by BufferedReader and BufferedWriter
452 */
453
454/* Flush and close */
455
456static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000457buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000458{
459 CHECK_INITIALIZED(self)
460 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
461}
462
463static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000464buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000465{
466 int closed;
467 PyObject *res;
468 CHECK_INITIALIZED_INT(self)
469 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
470 if (res == NULL)
471 return -1;
472 closed = PyObject_IsTrue(res);
473 Py_DECREF(res);
474 return closed;
475}
476
477static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000478buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000479{
480 CHECK_INITIALIZED(self)
481 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
482}
483
484static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000485buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000486{
Benjamin Peterson68623612012-12-20 11:53:11 -0600487 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000488 int r;
489
490 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000491 if (!ENTER_BUFFERED(self))
492 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000493
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000494 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000495 if (r < 0)
496 goto end;
497 if (r > 0) {
498 res = Py_None;
499 Py_INCREF(res);
500 goto end;
501 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000502
503 if (self->deallocating) {
504 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
505 if (r)
506 Py_DECREF(r);
507 else
508 PyErr_Clear();
509 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510 /* flush() will most probably re-take the lock, so drop it first */
511 LEAVE_BUFFERED(self)
512 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000513 if (!ENTER_BUFFERED(self))
514 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600515 if (res == NULL)
516 PyErr_Fetch(&exc, &val, &tb);
517 else
518 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519
520 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
521
Benjamin Peterson68623612012-12-20 11:53:11 -0600522 if (exc != NULL) {
523 if (res != NULL) {
524 Py_CLEAR(res);
525 PyErr_Restore(exc, val, tb);
526 }
527 else {
528 PyObject *val2;
529 Py_DECREF(exc);
530 Py_XDECREF(tb);
531 PyErr_Fetch(&exc, &val2, &tb);
532 PyErr_NormalizeException(&exc, &val2, &tb);
533 PyException_SetContext(val2, val);
534 PyErr_Restore(exc, val2, tb);
535 }
536 }
537
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000538end:
539 LEAVE_BUFFERED(self)
540 return res;
541}
542
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000543/* detach */
544
545static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000546buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000547{
548 PyObject *raw, *res;
549 CHECK_INITIALIZED(self)
550 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
551 if (res == NULL)
552 return NULL;
553 Py_DECREF(res);
554 raw = self->raw;
555 self->raw = NULL;
556 self->detached = 1;
557 self->ok = 0;
558 return raw;
559}
560
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000561/* Inquiries */
562
563static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000564buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565{
566 CHECK_INITIALIZED(self)
567 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
568}
569
570static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000571buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572{
573 CHECK_INITIALIZED(self)
574 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
575}
576
577static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000578buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579{
580 CHECK_INITIALIZED(self)
581 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
582}
583
584static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000585buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586{
587 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200588 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589}
590
591static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000592buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593{
594 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200595 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000596}
597
598/* Lower-level APIs */
599
600static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000601buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602{
603 CHECK_INITIALIZED(self)
604 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
605}
606
607static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000608buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609{
610 CHECK_INITIALIZED(self)
611 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
612}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000613
Antoine Pitrou243757e2010-11-05 21:15:39 +0000614/* Serialization */
615
616static PyObject *
617buffered_getstate(buffered *self, PyObject *args)
618{
619 PyErr_Format(PyExc_TypeError,
620 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
621 return NULL;
622}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000623
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000624/* Forward decls */
625static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100626_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000628_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000630_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000631static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000632_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200634_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000637static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000638_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000639static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200641static Py_ssize_t
642_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643
644/*
645 * Helpers
646 */
647
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100648/* Sets the current error to BlockingIOError */
649static void
650_set_BlockingIOError(char *msg, Py_ssize_t written)
651{
652 PyObject *err;
653 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
654 errno, msg, written);
655 if (err)
656 PyErr_SetObject(PyExc_BlockingIOError, err);
657 Py_XDECREF(err);
658}
659
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660/* Returns the address of the `written` member if a BlockingIOError was
661 raised, NULL otherwise. The error is always re-raised. */
662static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000663_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664{
665 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200666 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000667
668 PyErr_Fetch(&t, &v, &tb);
669 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
670 PyErr_Restore(t, v, tb);
671 return NULL;
672 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200673 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674 /* TODO: sanity check (err->written >= 0) */
675 PyErr_Restore(t, v, tb);
676 return &err->written;
677}
678
679static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000680_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000683 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
685 if (res == NULL)
686 return -1;
687 n = PyNumber_AsOff_t(res, PyExc_ValueError);
688 Py_DECREF(res);
689 if (n < 0) {
690 if (!PyErr_Occurred())
691 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000692 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200693 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000694 return -1;
695 }
696 self->abs_pos = n;
697 return n;
698}
699
700static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000701_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702{
703 PyObject *res, *posobj, *whenceobj;
704 Py_off_t n;
705
706 posobj = PyLong_FromOff_t(target);
707 if (posobj == NULL)
708 return -1;
709 whenceobj = PyLong_FromLong(whence);
710 if (whenceobj == NULL) {
711 Py_DECREF(posobj);
712 return -1;
713 }
714 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
715 posobj, whenceobj, NULL);
716 Py_DECREF(posobj);
717 Py_DECREF(whenceobj);
718 if (res == NULL)
719 return -1;
720 n = PyNumber_AsOff_t(res, PyExc_ValueError);
721 Py_DECREF(res);
722 if (n < 0) {
723 if (!PyErr_Occurred())
724 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000725 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200726 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000727 return -1;
728 }
729 self->abs_pos = n;
730 return n;
731}
732
733static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000734_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000735{
736 Py_ssize_t n;
737 if (self->buffer_size <= 0) {
738 PyErr_SetString(PyExc_ValueError,
739 "buffer size must be strictly positive");
740 return -1;
741 }
742 if (self->buffer)
743 PyMem_Free(self->buffer);
744 self->buffer = PyMem_Malloc(self->buffer_size);
745 if (self->buffer == NULL) {
746 PyErr_NoMemory();
747 return -1;
748 }
Georg Brandldfd73442009-04-05 11:47:34 +0000749#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000750 if (self->lock)
751 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000752 self->lock = PyThread_allocate_lock();
753 if (self->lock == NULL) {
754 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
755 return -1;
756 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000757 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000758#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000759 /* Find out whether buffer_size is a power of 2 */
760 /* XXX is this optimization useful? */
761 for (n = self->buffer_size - 1; n & 1; n >>= 1)
762 ;
763 if (n == 0)
764 self->buffer_mask = self->buffer_size - 1;
765 else
766 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000767 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000768 PyErr_Clear();
769 return 0;
770}
771
Antoine Pitrou707ce822011-02-25 21:24:11 +0000772/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
773 clears the error indicator), 0 otherwise.
774 Should only be called when PyErr_Occurred() is true.
775*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700776int
777_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000778{
779 static PyObject *eintr_int = NULL;
780 PyObject *typ, *val, *tb;
781 PyEnvironmentErrorObject *env_err;
782
783 if (eintr_int == NULL) {
784 eintr_int = PyLong_FromLong(EINTR);
785 assert(eintr_int != NULL);
786 }
787 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
788 return 0;
789 PyErr_Fetch(&typ, &val, &tb);
790 PyErr_NormalizeException(&typ, &val, &tb);
791 env_err = (PyEnvironmentErrorObject *) val;
792 assert(env_err != NULL);
793 if (env_err->myerrno != NULL &&
794 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
795 Py_DECREF(typ);
796 Py_DECREF(val);
797 Py_XDECREF(tb);
798 return 1;
799 }
800 /* This silences any error set by PyObject_RichCompareBool() */
801 PyErr_Restore(typ, val, tb);
802 return 0;
803}
804
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000805/*
806 * Shared methods and wrappers
807 */
808
809static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200810buffered_flush_and_rewind_unlocked(buffered *self)
811{
812 PyObject *res;
813
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100814 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200815 if (res == NULL)
816 return NULL;
817 Py_DECREF(res);
818
819 if (self->readable) {
820 /* Rewind the raw stream so that its position corresponds to
821 the current logical position. */
822 Py_off_t n;
823 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
824 _bufferedreader_reset_buf(self);
825 if (n == -1)
826 return NULL;
827 }
828 Py_RETURN_NONE;
829}
830
831static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000832buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833{
834 PyObject *res;
835
836 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000837 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000838
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000839 if (!ENTER_BUFFERED(self))
840 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200841 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000842 LEAVE_BUFFERED(self)
843
844 return res;
845}
846
847static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000848buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849{
850 Py_ssize_t n = 0;
851 PyObject *res = NULL;
852
853 CHECK_INITIALIZED(self)
854 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
855 return NULL;
856 }
857
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000858 if (!ENTER_BUFFERED(self))
859 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860
861 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200862 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000863 if (res == NULL)
864 goto end;
865 Py_CLEAR(res);
866 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200867 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868
869end:
870 LEAVE_BUFFERED(self)
871 return res;
872}
873
874static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000875buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876{
877 Py_ssize_t n = -1;
878 PyObject *res;
879
880 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000881 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882 return NULL;
883 }
884 if (n < -1) {
885 PyErr_SetString(PyExc_ValueError,
886 "read length must be positive or -1");
887 return NULL;
888 }
889
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000890 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000891
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000892 if (n == -1) {
893 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000894 if (!ENTER_BUFFERED(self))
895 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000896 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000897 }
898 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000899 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200900 if (res != Py_None)
901 return res;
902 Py_DECREF(res);
903 if (!ENTER_BUFFERED(self))
904 return NULL;
905 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000906 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000907
Antoine Pitroue05565e2011-08-20 14:39:23 +0200908 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909 return res;
910}
911
912static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000913buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000914{
915 Py_ssize_t n, have, r;
916 PyObject *res = NULL;
917
918 CHECK_INITIALIZED(self)
919 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
920 return NULL;
921 }
922
923 if (n < 0) {
924 PyErr_SetString(PyExc_ValueError,
925 "read length must be positive");
926 return NULL;
927 }
928 if (n == 0)
929 return PyBytes_FromStringAndSize(NULL, 0);
930
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931 /* Return up to n bytes. If at least one byte is buffered, we
932 only return buffered bytes. Otherwise, we do one raw read. */
933
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000934 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
935 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100936 n = Py_MIN(have, n);
937 res = _bufferedreader_read_fast(self, n);
938 assert(res != Py_None);
939 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100941 res = PyBytes_FromStringAndSize(NULL, n);
942 if (res == NULL)
943 return NULL;
944 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200945 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100946 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200947 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000948 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100949 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
950 LEAVE_BUFFERED(self)
951 if (r == -1) {
952 Py_DECREF(res);
953 return NULL;
954 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000955 if (r == -2)
956 r = 0;
957 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100958 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 return res;
960}
961
962static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000963buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200965 Py_buffer buf;
966 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 PyObject *res = NULL;
968
969 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200970
971 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
972 return NULL;
973
974 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
975 if (n > 0) {
976 if (n >= buf.len) {
977 memcpy(buf.buf, self->buffer + self->pos, buf.len);
978 self->pos += buf.len;
979 res = PyLong_FromSsize_t(buf.len);
980 goto end_unlocked;
981 }
982 memcpy(buf.buf, self->buffer + self->pos, n);
983 self->pos += n;
984 written = n;
985 }
986
987 if (!ENTER_BUFFERED(self))
988 goto end_unlocked;
989
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200991 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 if (res == NULL)
993 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200994 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996
997 _bufferedreader_reset_buf(self);
998 self->pos = 0;
999
1000 for (remaining = buf.len - written;
1001 remaining > 0;
1002 written += n, remaining -= n) {
1003 /* If remaining bytes is larger than internal buffer size, copy
1004 * directly into caller's buffer. */
1005 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001006 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1007 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001008 }
1009 else {
1010 n = _bufferedreader_fill_buffer(self);
1011 if (n > 0) {
1012 if (n > remaining)
1013 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001014 memcpy((char *) buf.buf + written,
1015 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016 self->pos += n;
1017 continue; /* short circuit */
1018 }
1019 }
1020 if (n == 0 || (n == -2 && written > 0))
1021 break;
1022 if (n < 0) {
1023 if (n == -2) {
1024 Py_INCREF(Py_None);
1025 res = Py_None;
1026 }
1027 goto end;
1028 }
1029 }
1030 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001031
1032end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001033 LEAVE_BUFFERED(self);
1034end_unlocked:
1035 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001036 return res;
1037}
1038
1039static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001040_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041{
1042 PyObject *res = NULL;
1043 PyObject *chunks = NULL;
1044 Py_ssize_t n, written = 0;
1045 const char *start, *s, *end;
1046
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001047 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001048
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001049 /* First, try to find a line in the buffer. This can run unlocked because
1050 the calls to the C API are simple enough that they can't trigger
1051 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001052 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1053 if (limit >= 0 && n > limit)
1054 n = limit;
1055 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001056 s = memchr(start, '\n', n);
1057 if (s != NULL) {
1058 res = PyBytes_FromStringAndSize(start, s - start + 1);
1059 if (res != NULL)
1060 self->pos += s - start + 1;
1061 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001062 }
1063 if (n == limit) {
1064 res = PyBytes_FromStringAndSize(start, n);
1065 if (res != NULL)
1066 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001067 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001068 }
1069
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001070 if (!ENTER_BUFFERED(self))
1071 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001072
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001073 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001074 chunks = PyList_New(0);
1075 if (chunks == NULL)
1076 goto end;
1077 if (n > 0) {
1078 res = PyBytes_FromStringAndSize(start, n);
1079 if (res == NULL)
1080 goto end;
1081 if (PyList_Append(chunks, res) < 0) {
1082 Py_CLEAR(res);
1083 goto end;
1084 }
1085 Py_CLEAR(res);
1086 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001087 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001088 if (limit >= 0)
1089 limit -= n;
1090 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001091 if (self->writable) {
1092 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1093 if (r == NULL)
1094 goto end;
1095 Py_DECREF(r);
1096 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001097
1098 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001099 _bufferedreader_reset_buf(self);
1100 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 if (n == -1)
1102 goto end;
1103 if (n <= 0)
1104 break;
1105 if (limit >= 0 && n > limit)
1106 n = limit;
1107 start = self->buffer;
1108 end = start + n;
1109 s = start;
1110 while (s < end) {
1111 if (*s++ == '\n') {
1112 res = PyBytes_FromStringAndSize(start, s - start);
1113 if (res == NULL)
1114 goto end;
1115 self->pos = s - start;
1116 goto found;
1117 }
1118 }
1119 res = PyBytes_FromStringAndSize(start, n);
1120 if (res == NULL)
1121 goto end;
1122 if (n == limit) {
1123 self->pos = n;
1124 break;
1125 }
1126 if (PyList_Append(chunks, res) < 0) {
1127 Py_CLEAR(res);
1128 goto end;
1129 }
1130 Py_CLEAR(res);
1131 written += n;
1132 if (limit >= 0)
1133 limit -= n;
1134 }
1135found:
1136 if (res != NULL && PyList_Append(chunks, res) < 0) {
1137 Py_CLEAR(res);
1138 goto end;
1139 }
1140 Py_CLEAR(res);
1141 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1142
1143end:
1144 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001145end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001146 Py_XDECREF(chunks);
1147 return res;
1148}
1149
1150static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001151buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001152{
1153 Py_ssize_t limit = -1;
1154
1155 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001156 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001157 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001158 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001159}
1160
1161
1162static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001163buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001164{
1165 Py_off_t pos;
1166
1167 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001168 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001169 if (pos == -1)
1170 return NULL;
1171 pos -= RAW_OFFSET(self);
1172 /* TODO: sanity check (pos >= 0) */
1173 return PyLong_FromOff_t(pos);
1174}
1175
1176static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001177buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001178{
1179 Py_off_t target, n;
1180 int whence = 0;
1181 PyObject *targetobj, *res = NULL;
1182
1183 CHECK_INITIALIZED(self)
1184 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1185 return NULL;
1186 }
Jesus Cea94363612012-06-22 18:32:07 +02001187
1188 /* Do some error checking instead of trusting OS 'seek()'
1189 ** error detection, just in case.
1190 */
1191 if ((whence < 0 || whence >2)
1192#ifdef SEEK_HOLE
1193 && (whence != SEEK_HOLE)
1194#endif
1195#ifdef SEEK_DATA
1196 && (whence != SEEK_DATA)
1197#endif
1198 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001200 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201 return NULL;
1202 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001203
1204 CHECK_CLOSED(self, "seek of closed file")
1205
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001206 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1207 return NULL;
1208
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1210 if (target == -1 && PyErr_Occurred())
1211 return NULL;
1212
Jesus Cea94363612012-06-22 18:32:07 +02001213 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1214 buffer. Other whence values must be managed without this optimization.
1215 Some Operating Systems can provide additional values, like
1216 SEEK_HOLE/SEEK_DATA. */
1217 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001218 Py_off_t current, avail;
1219 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001220 so as to return quickly if possible. Also, we needn't take the
1221 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001223 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1224 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225 current = RAW_TELL(self);
1226 avail = READAHEAD(self);
1227 if (avail > 0) {
1228 Py_off_t offset;
1229 if (whence == 0)
1230 offset = target - (current - RAW_OFFSET(self));
1231 else
1232 offset = target;
1233 if (offset >= -self->pos && offset <= avail) {
1234 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001235 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 }
1237 }
1238 }
1239
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001240 if (!ENTER_BUFFERED(self))
1241 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001242
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 /* Fallback: invoke raw seek() method and clear buffer */
1244 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001245 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 if (res == NULL)
1247 goto end;
1248 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001249 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250 }
1251
1252 /* TODO: align on block boundary and read buffer if needed? */
1253 if (whence == 1)
1254 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001255 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 if (n == -1)
1257 goto end;
1258 self->raw_pos = -1;
1259 res = PyLong_FromOff_t(n);
1260 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001261 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262
1263end:
1264 LEAVE_BUFFERED(self)
1265 return res;
1266}
1267
1268static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001269buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270{
1271 PyObject *pos = Py_None;
1272 PyObject *res = NULL;
1273
1274 CHECK_INITIALIZED(self)
1275 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1276 return NULL;
1277 }
1278
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001279 if (!ENTER_BUFFERED(self))
1280 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001281
1282 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001283 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001284 if (res == NULL)
1285 goto end;
1286 Py_CLEAR(res);
1287 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1289 if (res == NULL)
1290 goto end;
1291 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001292 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001293 PyErr_Clear();
1294
1295end:
1296 LEAVE_BUFFERED(self)
1297 return res;
1298}
1299
1300static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001301buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001302{
1303 PyObject *line;
1304 PyTypeObject *tp;
1305
1306 CHECK_INITIALIZED(self);
1307
1308 tp = Py_TYPE(self);
1309 if (tp == &PyBufferedReader_Type ||
1310 tp == &PyBufferedRandom_Type) {
1311 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001312 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 }
1314 else {
1315 line = PyObject_CallMethodObjArgs((PyObject *)self,
1316 _PyIO_str_readline, NULL);
1317 if (line && !PyBytes_Check(line)) {
1318 PyErr_Format(PyExc_IOError,
1319 "readline() should have returned a bytes object, "
1320 "not '%.200s'", Py_TYPE(line)->tp_name);
1321 Py_DECREF(line);
1322 return NULL;
1323 }
1324 }
1325
1326 if (line == NULL)
1327 return NULL;
1328
1329 if (PyBytes_GET_SIZE(line) == 0) {
1330 /* Reached EOF or would have blocked */
1331 Py_DECREF(line);
1332 return NULL;
1333 }
1334
1335 return line;
1336}
1337
Antoine Pitrou716c4442009-05-23 19:04:03 +00001338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001339buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001340{
1341 PyObject *nameobj, *res;
1342
Martin v. Löwis767046a2011-10-14 15:35:36 +02001343 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001344 if (nameobj == NULL) {
1345 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1346 PyErr_Clear();
1347 else
1348 return NULL;
1349 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1350 }
1351 else {
1352 res = PyUnicode_FromFormat("<%s name=%R>",
1353 Py_TYPE(self)->tp_name, nameobj);
1354 Py_DECREF(nameobj);
1355 }
1356 return res;
1357}
1358
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359/*
1360 * class BufferedReader
1361 */
1362
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001363PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001364 "Create a new buffered reader using the given readable raw IO object.");
1365
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001366static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367{
1368 self->read_end = -1;
1369}
1370
1371static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001372bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001373{
1374 char *kwlist[] = {"raw", "buffer_size", NULL};
1375 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1376 PyObject *raw;
1377
1378 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001379 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001380
1381 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1382 &raw, &buffer_size)) {
1383 return -1;
1384 }
1385
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001386 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001387 return -1;
1388
1389 Py_CLEAR(self->raw);
1390 Py_INCREF(raw);
1391 self->raw = raw;
1392 self->buffer_size = buffer_size;
1393 self->readable = 1;
1394 self->writable = 0;
1395
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001396 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001397 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001398 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001399
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001400 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1401 Py_TYPE(raw) == &PyFileIO_Type);
1402
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001403 self->ok = 1;
1404 return 0;
1405}
1406
1407static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001408_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001409{
1410 Py_buffer buf;
1411 PyObject *memobj, *res;
1412 Py_ssize_t n;
1413 /* NOTE: the buffer needn't be released as its object is NULL. */
1414 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1415 return -1;
1416 memobj = PyMemoryView_FromBuffer(&buf);
1417 if (memobj == NULL)
1418 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001419 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1420 occurs so we needn't do it ourselves.
1421 We then retry reading, ignoring the signal if no handler has
1422 raised (see issue #10956).
1423 */
1424 do {
1425 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001426 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001427 Py_DECREF(memobj);
1428 if (res == NULL)
1429 return -1;
1430 if (res == Py_None) {
1431 /* Non-blocking stream would have blocked. Special return code! */
1432 Py_DECREF(res);
1433 return -2;
1434 }
1435 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1436 Py_DECREF(res);
1437 if (n < 0 || n > len) {
1438 PyErr_Format(PyExc_IOError,
1439 "raw readinto() returned invalid length %zd "
1440 "(should have been between 0 and %zd)", n, len);
1441 return -1;
1442 }
1443 if (n > 0 && self->abs_pos != -1)
1444 self->abs_pos += n;
1445 return n;
1446}
1447
1448static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001449_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450{
1451 Py_ssize_t start, len, n;
1452 if (VALID_READ_BUFFER(self))
1453 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1454 else
1455 start = 0;
1456 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001457 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458 if (n <= 0)
1459 return n;
1460 self->read_end = start + n;
1461 self->raw_pos = start + n;
1462 return n;
1463}
1464
1465static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001466_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001467{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001468 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001469 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001470
1471 /* First copy what we have in the current buffer. */
1472 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1473 if (current_size) {
1474 data = PyBytes_FromStringAndSize(
1475 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001476 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001477 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001478 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001480 /* We're going past the buffer's bounds, flush it */
1481 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001482 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001483 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001484 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001485 Py_CLEAR(res);
1486 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001487 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001488
1489 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1490 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1491 if (chunk == NULL)
1492 return NULL;
1493 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1494 Py_XDECREF(data);
1495 Py_DECREF(chunk);
1496 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1497 return NULL;
1498 }
1499 if (chunk == Py_None) {
1500 if (current_size == 0)
1501 return chunk;
1502 else {
1503 Py_DECREF(chunk);
1504 return data;
1505 }
1506 }
1507 else if (current_size) {
1508 PyBytes_Concat(&data, chunk);
1509 Py_DECREF(chunk);
1510 if (data == NULL)
1511 return NULL;
1512 return data;
1513 } else
1514 return chunk;
1515 }
1516
1517 chunks = PyList_New(0);
Christian Heimes8f734eb2012-09-10 17:46:09 +02001518 if (chunks == NULL) {
1519 Py_XDECREF(data);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001520 return NULL;
Christian Heimes8f734eb2012-09-10 17:46:09 +02001521 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001522
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001523 while (1) {
1524 if (data) {
1525 if (PyList_Append(chunks, data) < 0) {
1526 Py_DECREF(data);
1527 Py_DECREF(chunks);
1528 return NULL;
1529 }
1530 Py_DECREF(data);
1531 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001533 /* Read until EOF or until read() would block. */
1534 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1535 if (data == NULL) {
1536 Py_DECREF(chunks);
1537 return NULL;
1538 }
1539 if (data != Py_None && !PyBytes_Check(data)) {
1540 Py_DECREF(data);
1541 Py_DECREF(chunks);
1542 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1543 return NULL;
1544 }
1545 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1546 if (current_size == 0) {
1547 Py_DECREF(chunks);
1548 return data;
1549 }
1550 else {
1551 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1552 Py_DECREF(data);
1553 Py_DECREF(chunks);
1554 return res;
1555 }
1556 }
1557 current_size += PyBytes_GET_SIZE(data);
1558 if (self->abs_pos != -1)
1559 self->abs_pos += PyBytes_GET_SIZE(data);
1560 }
1561}
1562
1563/* Read n bytes from the buffer if it can, otherwise return None.
1564 This function is simple enough that it can run unlocked. */
1565static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001566_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567{
1568 Py_ssize_t current_size;
1569
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001570 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1571 if (n <= current_size) {
1572 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001573 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1574 if (res != NULL)
1575 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001576 return res;
1577 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578 Py_RETURN_NONE;
1579}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001580
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581/* Generic read function: read from the stream until enough bytes are read,
1582 * or until an EOF occurs or until read() would block.
1583 */
1584static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001585_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586{
1587 PyObject *res = NULL;
1588 Py_ssize_t current_size, remaining, written;
1589 char *out;
1590
1591 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1592 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001593 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001595 res = PyBytes_FromStringAndSize(NULL, n);
1596 if (res == NULL)
1597 goto error;
1598 out = PyBytes_AS_STRING(res);
1599 remaining = n;
1600 written = 0;
1601 if (current_size > 0) {
1602 memcpy(out, self->buffer + self->pos, current_size);
1603 remaining -= current_size;
1604 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001605 self->pos += current_size;
1606 }
1607 /* Flush the write buffer if necessary */
1608 if (self->writable) {
1609 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1610 if (r == NULL)
1611 goto error;
1612 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001613 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001614 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001615 while (remaining > 0) {
1616 /* We want to read a whole block at the end into buffer.
1617 If we had readv() we could do this in one pass. */
1618 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1619 if (r == 0)
1620 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001621 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001622 if (r == -1)
1623 goto error;
1624 if (r == 0 || r == -2) {
1625 /* EOF occurred or read() would block. */
1626 if (r == 0 || written > 0) {
1627 if (_PyBytes_Resize(&res, written))
1628 goto error;
1629 return res;
1630 }
1631 Py_DECREF(res);
1632 Py_INCREF(Py_None);
1633 return Py_None;
1634 }
1635 remaining -= r;
1636 written += r;
1637 }
1638 assert(remaining <= self->buffer_size);
1639 self->pos = 0;
1640 self->raw_pos = 0;
1641 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001642 /* NOTE: when the read is satisfied, we avoid issuing any additional
1643 reads, which could block indefinitely (e.g. on a socket).
1644 See issue #9550. */
1645 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001646 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001647 if (r == -1)
1648 goto error;
1649 if (r == 0 || r == -2) {
1650 /* EOF occurred or read() would block. */
1651 if (r == 0 || written > 0) {
1652 if (_PyBytes_Resize(&res, written))
1653 goto error;
1654 return res;
1655 }
1656 Py_DECREF(res);
1657 Py_INCREF(Py_None);
1658 return Py_None;
1659 }
1660 if (remaining > r) {
1661 memcpy(out + written, self->buffer + self->pos, r);
1662 written += r;
1663 self->pos += r;
1664 remaining -= r;
1665 }
1666 else if (remaining > 0) {
1667 memcpy(out + written, self->buffer + self->pos, remaining);
1668 written += remaining;
1669 self->pos += remaining;
1670 remaining = 0;
1671 }
1672 if (remaining == 0)
1673 break;
1674 }
1675
1676 return res;
1677
1678error:
1679 Py_XDECREF(res);
1680 return NULL;
1681}
1682
1683static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001684_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685{
1686 Py_ssize_t have, r;
1687
1688 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1689 /* Constraints:
1690 1. we don't want to advance the file position.
1691 2. we don't want to lose block alignment, so we can't shift the buffer
1692 to make some place.
1693 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1694 */
1695 if (have > 0) {
1696 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1697 }
1698
1699 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001700 _bufferedreader_reset_buf(self);
1701 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001702 if (r == -1)
1703 return NULL;
1704 if (r == -2)
1705 r = 0;
1706 self->pos = 0;
1707 return PyBytes_FromStringAndSize(self->buffer, r);
1708}
1709
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001710static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001711 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001712 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1713 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1714 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1715 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1716 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1717 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1718 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1719 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001720 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001721 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001722
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001723 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1724 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1725 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001726 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001727 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1728 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1729 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1730 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001731 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001732 {NULL, NULL}
1733};
1734
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001736 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 {NULL}
1738};
1739
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001740static PyGetSetDef bufferedreader_getset[] = {
1741 {"closed", (getter)buffered_closed_get, NULL, NULL},
1742 {"name", (getter)buffered_name_get, NULL, NULL},
1743 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001744 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745};
1746
1747
1748PyTypeObject PyBufferedReader_Type = {
1749 PyVarObject_HEAD_INIT(NULL, 0)
1750 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001751 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001752 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001753 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001754 0, /*tp_print*/
1755 0, /*tp_getattr*/
1756 0, /*tp_setattr*/
1757 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759 0, /*tp_as_number*/
1760 0, /*tp_as_sequence*/
1761 0, /*tp_as_mapping*/
1762 0, /*tp_hash */
1763 0, /*tp_call*/
1764 0, /*tp_str*/
1765 0, /*tp_getattro*/
1766 0, /*tp_setattro*/
1767 0, /*tp_as_buffer*/
1768 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1769 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001770 bufferedreader_doc, /* tp_doc */
1771 (traverseproc)buffered_traverse, /* tp_traverse */
1772 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001774 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776 (iternextfunc)buffered_iternext, /* tp_iternext */
1777 bufferedreader_methods, /* tp_methods */
1778 bufferedreader_members, /* tp_members */
1779 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 0, /* tp_base */
1781 0, /* tp_dict */
1782 0, /* tp_descr_get */
1783 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784 offsetof(buffered, dict), /* tp_dictoffset */
1785 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 0, /* tp_alloc */
1787 PyType_GenericNew, /* tp_new */
1788};
1789
1790
Benjamin Peterson59406a92009-03-26 17:10:29 +00001791
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001792/*
1793 * class BufferedWriter
1794 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001795PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001796 "A buffer for a writeable sequential RawIO object.\n"
1797 "\n"
1798 "The constructor creates a BufferedWriter for the given writeable raw\n"
1799 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001800 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 );
1802
1803static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001804_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805{
1806 self->write_pos = 0;
1807 self->write_end = -1;
1808}
1809
1810static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001811bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812{
Florent Xicluna109d5732012-07-07 17:03:22 +02001813 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 PyObject *raw;
1816
1817 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001818 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001819
Florent Xicluna109d5732012-07-07 17:03:22 +02001820 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1821 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822 return -1;
1823 }
1824
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001825 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001826 return -1;
1827
1828 Py_CLEAR(self->raw);
1829 Py_INCREF(raw);
1830 self->raw = raw;
1831 self->readable = 0;
1832 self->writable = 1;
1833
1834 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001835 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001837 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838 self->pos = 0;
1839
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001840 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1841 Py_TYPE(raw) == &PyFileIO_Type);
1842
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001843 self->ok = 1;
1844 return 0;
1845}
1846
1847static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001848_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849{
1850 Py_buffer buf;
1851 PyObject *memobj, *res;
1852 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001853 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854 /* NOTE: the buffer needn't be released as its object is NULL. */
1855 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1856 return -1;
1857 memobj = PyMemoryView_FromBuffer(&buf);
1858 if (memobj == NULL)
1859 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001860 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1861 occurs so we needn't do it ourselves.
1862 We then retry writing, ignoring the signal if no handler has
1863 raised (see issue #10956).
1864 */
1865 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001866 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001867 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001868 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001869 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001870 Py_DECREF(memobj);
1871 if (res == NULL)
1872 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001873 if (res == Py_None) {
1874 /* Non-blocking stream would have blocked. Special return code!
1875 Being paranoid we reset errno in case it is changed by code
1876 triggered by a decref. errno is used by _set_BlockingIOError(). */
1877 Py_DECREF(res);
1878 errno = errnum;
1879 return -2;
1880 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001881 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1882 Py_DECREF(res);
1883 if (n < 0 || n > len) {
1884 PyErr_Format(PyExc_IOError,
1885 "raw write() returned invalid length %zd "
1886 "(should have been between 0 and %zd)", n, len);
1887 return -1;
1888 }
1889 if (n > 0 && self->abs_pos != -1)
1890 self->abs_pos += n;
1891 return n;
1892}
1893
1894/* `restore_pos` is 1 if we need to restore the raw stream position at
1895 the end, 0 otherwise. */
1896static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001897_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898{
1899 Py_ssize_t written = 0;
1900 Py_off_t n, rewind;
1901
1902 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1903 goto end;
1904 /* First, rewind */
1905 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1906 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001907 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908 if (n < 0) {
1909 goto error;
1910 }
1911 self->raw_pos -= rewind;
1912 }
1913 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001914 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915 self->buffer + self->write_pos,
1916 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1917 Py_off_t, Py_ssize_t));
1918 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001919 goto error;
1920 }
1921 else if (n == -2) {
1922 _set_BlockingIOError("write could not complete without blocking",
1923 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924 goto error;
1925 }
1926 self->write_pos += n;
1927 self->raw_pos = self->write_pos;
1928 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001929 /* Partial writes can return successfully when interrupted by a
1930 signal (see write(2)). We must run signal handlers before
1931 blocking another time, possibly indefinitely. */
1932 if (PyErr_CheckSignals() < 0)
1933 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934 }
1935
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001936 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937
1938end:
1939 Py_RETURN_NONE;
1940
1941error:
1942 return NULL;
1943}
1944
1945static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001946bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947{
1948 PyObject *res = NULL;
1949 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001950 Py_ssize_t written, avail, remaining;
1951 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952
1953 CHECK_INITIALIZED(self)
1954 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1955 return NULL;
1956 }
1957
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001958 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001959 PyErr_SetString(PyExc_ValueError, "write to closed file");
1960 PyBuffer_Release(&buf);
1961 return NULL;
1962 }
1963
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001964 if (!ENTER_BUFFERED(self)) {
1965 PyBuffer_Release(&buf);
1966 return NULL;
1967 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001968
1969 /* Fast path: the data to write can be fully buffered. */
1970 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1971 self->pos = 0;
1972 self->raw_pos = 0;
1973 }
1974 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1975 if (buf.len <= avail) {
1976 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001977 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978 self->write_pos = self->pos;
1979 }
1980 ADJUST_POSITION(self, self->pos + buf.len);
1981 if (self->pos > self->write_end)
1982 self->write_end = self->pos;
1983 written = buf.len;
1984 goto end;
1985 }
1986
1987 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001988 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001989 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001990 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 if (w == NULL)
1992 goto error;
1993 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001994 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001995 /* Make some place by shifting the buffer. */
1996 assert(VALID_WRITE_BUFFER(self));
1997 memmove(self->buffer, self->buffer + self->write_pos,
1998 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1999 Py_off_t, Py_ssize_t));
2000 self->write_end -= self->write_pos;
2001 self->raw_pos -= self->write_pos;
2002 self->pos -= self->write_pos;
2003 self->write_pos = 0;
2004 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2005 Py_off_t, Py_ssize_t);
2006 if (buf.len <= avail) {
2007 /* Everything can be buffered */
2008 PyErr_Clear();
2009 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2010 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002011 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 written = buf.len;
2013 goto end;
2014 }
2015 /* Buffer as much as possible. */
2016 memcpy(self->buffer + self->write_end, buf.buf, avail);
2017 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002018 self->pos += avail;
2019 /* XXX Modifying the existing exception e using the pointer w
2020 will change e.characters_written but not e.args[2].
2021 Therefore we just replace with a new error. */
2022 _set_BlockingIOError("write could not complete without blocking",
2023 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 goto error;
2025 }
2026 Py_CLEAR(res);
2027
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002028 /* Adjust the raw stream position if it is away from the logical stream
2029 position. This happens if the read buffer has been filled but not
2030 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2031 the raw stream by itself).
2032 Fixes issue #6629.
2033 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002034 offset = RAW_OFFSET(self);
2035 if (offset != 0) {
2036 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002037 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002038 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002039 }
2040
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 /* Then write buf itself. At this point the buffer has been emptied. */
2042 remaining = buf.len;
2043 written = 0;
2044 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002045 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 self, (char *) buf.buf + written, buf.len - written);
2047 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002048 goto error;
2049 } else if (n == -2) {
2050 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 if (remaining > self->buffer_size) {
2052 /* Can't buffer everything, still buffer as much as possible */
2053 memcpy(self->buffer,
2054 (char *) buf.buf + written, self->buffer_size);
2055 self->raw_pos = 0;
2056 ADJUST_POSITION(self, self->buffer_size);
2057 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002058 written += self->buffer_size;
2059 _set_BlockingIOError("write could not complete without "
2060 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 goto error;
2062 }
2063 PyErr_Clear();
2064 break;
2065 }
2066 written += n;
2067 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002068 /* Partial writes can return successfully when interrupted by a
2069 signal (see write(2)). We must run signal handlers before
2070 blocking another time, possibly indefinitely. */
2071 if (PyErr_CheckSignals() < 0)
2072 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002073 }
2074 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002075 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076 if (remaining > 0) {
2077 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2078 written += remaining;
2079 }
2080 self->write_pos = 0;
2081 /* TODO: sanity check (remaining >= 0) */
2082 self->write_end = remaining;
2083 ADJUST_POSITION(self, remaining);
2084 self->raw_pos = 0;
2085
2086end:
2087 res = PyLong_FromSsize_t(written);
2088
2089error:
2090 LEAVE_BUFFERED(self)
2091 PyBuffer_Release(&buf);
2092 return res;
2093}
2094
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002095static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002097 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2098 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2099 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2100 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2101 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2102 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2103 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002104 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002105 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002107 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2108 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2109 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2110 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2111 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002112 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113 {NULL, NULL}
2114};
2115
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002116static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002117 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118 {NULL}
2119};
2120
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121static PyGetSetDef bufferedwriter_getset[] = {
2122 {"closed", (getter)buffered_closed_get, NULL, NULL},
2123 {"name", (getter)buffered_name_get, NULL, NULL},
2124 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002125 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002126};
2127
2128
2129PyTypeObject PyBufferedWriter_Type = {
2130 PyVarObject_HEAD_INIT(NULL, 0)
2131 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002132 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002134 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002135 0, /*tp_print*/
2136 0, /*tp_getattr*/
2137 0, /*tp_setattr*/
2138 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140 0, /*tp_as_number*/
2141 0, /*tp_as_sequence*/
2142 0, /*tp_as_mapping*/
2143 0, /*tp_hash */
2144 0, /*tp_call*/
2145 0, /*tp_str*/
2146 0, /*tp_getattro*/
2147 0, /*tp_setattro*/
2148 0, /*tp_as_buffer*/
2149 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2150 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002151 bufferedwriter_doc, /* tp_doc */
2152 (traverseproc)buffered_traverse, /* tp_traverse */
2153 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002155 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 0, /* tp_iter */
2157 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002158 bufferedwriter_methods, /* tp_methods */
2159 bufferedwriter_members, /* tp_members */
2160 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161 0, /* tp_base */
2162 0, /* tp_dict */
2163 0, /* tp_descr_get */
2164 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165 offsetof(buffered, dict), /* tp_dictoffset */
2166 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167 0, /* tp_alloc */
2168 PyType_GenericNew, /* tp_new */
2169};
2170
2171
2172
2173/*
2174 * BufferedRWPair
2175 */
2176
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002177PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178 "A buffered reader and writer object together.\n"
2179 "\n"
2180 "A buffered reader object and buffered writer object put together to\n"
2181 "form a sequential IO object that can read and write. This is typically\n"
2182 "used with a socket or two-way pipe.\n"
2183 "\n"
2184 "reader and writer are RawIOBase objects that are readable and\n"
2185 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002186 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187 );
2188
2189/* XXX The usefulness of this (compared to having two separate IO objects) is
2190 * questionable.
2191 */
2192
2193typedef struct {
2194 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002195 buffered *reader;
2196 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 PyObject *dict;
2198 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002199} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002200
2201static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002202bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203{
2204 PyObject *reader, *writer;
2205 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002206
Florent Xicluna109d5732012-07-07 17:03:22 +02002207 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2208 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209 return -1;
2210 }
2211
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002212 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002214 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215 return -1;
2216
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002218 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219 if (self->reader == NULL)
2220 return -1;
2221
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002223 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 if (self->writer == NULL) {
2225 Py_CLEAR(self->reader);
2226 return -1;
2227 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002228
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 return 0;
2230}
2231
2232static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002233bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234{
2235 Py_VISIT(self->dict);
2236 return 0;
2237}
2238
2239static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002240bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002241{
2242 Py_CLEAR(self->reader);
2243 Py_CLEAR(self->writer);
2244 Py_CLEAR(self->dict);
2245 return 0;
2246}
2247
2248static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002249bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250{
2251 _PyObject_GC_UNTRACK(self);
2252 Py_CLEAR(self->reader);
2253 Py_CLEAR(self->writer);
2254 Py_CLEAR(self->dict);
2255 Py_TYPE(self)->tp_free((PyObject *) self);
2256}
2257
2258static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002259_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002261 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262 PyObject *ret;
2263
2264 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002265 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 return NULL;
2267 }
2268
2269 ret = PyObject_CallObject(func, args);
2270 Py_DECREF(func);
2271 return ret;
2272}
2273
2274static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002275bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002277 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002278}
2279
2280static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002281bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002282{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002283 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002284}
2285
2286static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002287bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002288{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002289 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290}
2291
2292static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002293bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002294{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002295 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002296}
2297
2298static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002299bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002301 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002302}
2303
2304static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002305bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002306{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002307 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308}
2309
2310static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002311bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002313 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002314}
2315
2316static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002317bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002318{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002319 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002320}
2321
2322static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002323bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002324{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002325 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002326 if (ret == NULL)
2327 return NULL;
2328 Py_DECREF(ret);
2329
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002330 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331}
2332
2333static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002334bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002335{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002336 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002337
2338 if (ret != Py_False) {
2339 /* either True or exception */
2340 return ret;
2341 }
2342 Py_DECREF(ret);
2343
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002344 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002345}
2346
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002347static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002348bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002349{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002350 if (self->writer == NULL) {
2351 PyErr_SetString(PyExc_RuntimeError,
2352 "the BufferedRWPair object is being garbage-collected");
2353 return NULL;
2354 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002355 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2356}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002357
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002358static PyMethodDef bufferedrwpair_methods[] = {
2359 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2360 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2361 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2362 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002363
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002364 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2365 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002366
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002367 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2368 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002369
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002370 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2371 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002372
Antoine Pitrou243757e2010-11-05 21:15:39 +00002373 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2374
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002375 {NULL, NULL}
2376};
2377
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002378static PyGetSetDef bufferedrwpair_getset[] = {
2379 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002380 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002381};
2382
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002383PyTypeObject PyBufferedRWPair_Type = {
2384 PyVarObject_HEAD_INIT(NULL, 0)
2385 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002386 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002387 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002388 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002389 0, /*tp_print*/
2390 0, /*tp_getattr*/
2391 0, /*tp_setattr*/
2392 0, /*tp_compare */
2393 0, /*tp_repr*/
2394 0, /*tp_as_number*/
2395 0, /*tp_as_sequence*/
2396 0, /*tp_as_mapping*/
2397 0, /*tp_hash */
2398 0, /*tp_call*/
2399 0, /*tp_str*/
2400 0, /*tp_getattro*/
2401 0, /*tp_setattro*/
2402 0, /*tp_as_buffer*/
2403 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2404 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002405 bufferedrwpair_doc, /* tp_doc */
2406 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2407 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002408 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002409 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002410 0, /* tp_iter */
2411 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002412 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002413 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002414 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002415 0, /* tp_base */
2416 0, /* tp_dict */
2417 0, /* tp_descr_get */
2418 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002419 offsetof(rwpair, dict), /* tp_dictoffset */
2420 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421 0, /* tp_alloc */
2422 PyType_GenericNew, /* tp_new */
2423};
2424
2425
2426
2427/*
2428 * BufferedRandom
2429 */
2430
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002431PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432 "A buffered interface to random access streams.\n"
2433 "\n"
2434 "The constructor creates a reader and writer for a seekable stream,\n"
2435 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002436 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002437 );
2438
2439static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002440bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002441{
Florent Xicluna109d5732012-07-07 17:03:22 +02002442 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002443 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002444 PyObject *raw;
2445
2446 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002447 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002448
Florent Xicluna109d5732012-07-07 17:03:22 +02002449 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
2450 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002451 return -1;
2452 }
2453
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002454 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002455 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002456 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002457 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002458 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459 return -1;
2460
2461 Py_CLEAR(self->raw);
2462 Py_INCREF(raw);
2463 self->raw = raw;
2464 self->buffer_size = buffer_size;
2465 self->readable = 1;
2466 self->writable = 1;
2467
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002468 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002469 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002470 _bufferedreader_reset_buf(self);
2471 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002472 self->pos = 0;
2473
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002474 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2475 Py_TYPE(raw) == &PyFileIO_Type);
2476
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002477 self->ok = 1;
2478 return 0;
2479}
2480
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002481static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002482 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002483 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2484 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2485 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2486 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2487 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2488 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2489 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002490 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002491 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002492
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002493 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002495 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2496 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2497 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2498 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2499 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2500 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2501 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2502 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2503 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002504 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002505 {NULL, NULL}
2506};
2507
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002508static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002509 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002510 {NULL}
2511};
2512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002513static PyGetSetDef bufferedrandom_getset[] = {
2514 {"closed", (getter)buffered_closed_get, NULL, NULL},
2515 {"name", (getter)buffered_name_get, NULL, NULL},
2516 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002517 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002518};
2519
2520
2521PyTypeObject PyBufferedRandom_Type = {
2522 PyVarObject_HEAD_INIT(NULL, 0)
2523 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002524 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002525 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002526 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002527 0, /*tp_print*/
2528 0, /*tp_getattr*/
2529 0, /*tp_setattr*/
2530 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002531 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 0, /*tp_as_number*/
2533 0, /*tp_as_sequence*/
2534 0, /*tp_as_mapping*/
2535 0, /*tp_hash */
2536 0, /*tp_call*/
2537 0, /*tp_str*/
2538 0, /*tp_getattro*/
2539 0, /*tp_setattro*/
2540 0, /*tp_as_buffer*/
2541 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2542 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002543 bufferedrandom_doc, /* tp_doc */
2544 (traverseproc)buffered_traverse, /* tp_traverse */
2545 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002546 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002547 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002548 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002549 (iternextfunc)buffered_iternext, /* tp_iternext */
2550 bufferedrandom_methods, /* tp_methods */
2551 bufferedrandom_members, /* tp_members */
2552 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002553 0, /* tp_base */
2554 0, /*tp_dict*/
2555 0, /* tp_descr_get */
2556 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002557 offsetof(buffered, dict), /*tp_dictoffset*/
2558 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559 0, /* tp_alloc */
2560 PyType_GenericNew, /* tp_new */
2561};