blob: 943aacb4c2bc4a82ebe3f56887f4d12dc110d70a [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
Jesus Ceadc469452012-10-04 12:37:56 +0200522 if (self->buffer) {
523 PyMem_Free(self->buffer);
524 self->buffer = NULL;
525 }
526
Benjamin Peterson68623612012-12-20 11:53:11 -0600527 if (exc != NULL) {
528 if (res != NULL) {
529 Py_CLEAR(res);
530 PyErr_Restore(exc, val, tb);
531 }
532 else {
533 PyObject *val2;
534 Py_DECREF(exc);
535 Py_XDECREF(tb);
536 PyErr_Fetch(&exc, &val2, &tb);
537 PyErr_NormalizeException(&exc, &val2, &tb);
538 PyException_SetContext(val2, val);
539 PyErr_Restore(exc, val2, tb);
540 }
541 }
542
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543end:
544 LEAVE_BUFFERED(self)
545 return res;
546}
547
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000548/* detach */
549
550static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000551buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000552{
553 PyObject *raw, *res;
554 CHECK_INITIALIZED(self)
555 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
556 if (res == NULL)
557 return NULL;
558 Py_DECREF(res);
559 raw = self->raw;
560 self->raw = NULL;
561 self->detached = 1;
562 self->ok = 0;
563 return raw;
564}
565
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000566/* Inquiries */
567
568static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000569buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570{
571 CHECK_INITIALIZED(self)
572 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
573}
574
575static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000576buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000577{
578 CHECK_INITIALIZED(self)
579 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
580}
581
582static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000583buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584{
585 CHECK_INITIALIZED(self)
586 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
587}
588
589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000590buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591{
592 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200593 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594}
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598{
599 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200600 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601}
602
603/* Lower-level APIs */
604
605static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000606buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607{
608 CHECK_INITIALIZED(self)
609 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
610}
611
612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614{
615 CHECK_INITIALIZED(self)
616 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
617}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000618
Antoine Pitrou243757e2010-11-05 21:15:39 +0000619/* Serialization */
620
621static PyObject *
622buffered_getstate(buffered *self, PyObject *args)
623{
624 PyErr_Format(PyExc_TypeError,
625 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
626 return NULL;
627}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000628
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629/* Forward decls */
630static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100631_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000632static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000633_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000634static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000635_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000636static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000637_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000638static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200639_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000642static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000644static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000645_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200646static Py_ssize_t
647_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648
649/*
650 * Helpers
651 */
652
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100653/* Sets the current error to BlockingIOError */
654static void
655_set_BlockingIOError(char *msg, Py_ssize_t written)
656{
657 PyObject *err;
658 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
659 errno, msg, written);
660 if (err)
661 PyErr_SetObject(PyExc_BlockingIOError, err);
662 Py_XDECREF(err);
663}
664
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665/* Returns the address of the `written` member if a BlockingIOError was
666 raised, NULL otherwise. The error is always re-raised. */
667static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000668_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669{
670 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200671 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672
673 PyErr_Fetch(&t, &v, &tb);
674 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
675 PyErr_Restore(t, v, tb);
676 return NULL;
677 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200678 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000679 /* TODO: sanity check (err->written >= 0) */
680 PyErr_Restore(t, v, tb);
681 return &err->written;
682}
683
684static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000685_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000686{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000687 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000688 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
690 if (res == NULL)
691 return -1;
692 n = PyNumber_AsOff_t(res, PyExc_ValueError);
693 Py_DECREF(res);
694 if (n < 0) {
695 if (!PyErr_Occurred())
696 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000697 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200698 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000699 return -1;
700 }
701 self->abs_pos = n;
702 return n;
703}
704
705static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000706_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707{
708 PyObject *res, *posobj, *whenceobj;
709 Py_off_t n;
710
711 posobj = PyLong_FromOff_t(target);
712 if (posobj == NULL)
713 return -1;
714 whenceobj = PyLong_FromLong(whence);
715 if (whenceobj == NULL) {
716 Py_DECREF(posobj);
717 return -1;
718 }
719 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
720 posobj, whenceobj, NULL);
721 Py_DECREF(posobj);
722 Py_DECREF(whenceobj);
723 if (res == NULL)
724 return -1;
725 n = PyNumber_AsOff_t(res, PyExc_ValueError);
726 Py_DECREF(res);
727 if (n < 0) {
728 if (!PyErr_Occurred())
729 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000730 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200731 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732 return -1;
733 }
734 self->abs_pos = n;
735 return n;
736}
737
738static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000739_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740{
741 Py_ssize_t n;
742 if (self->buffer_size <= 0) {
743 PyErr_SetString(PyExc_ValueError,
744 "buffer size must be strictly positive");
745 return -1;
746 }
747 if (self->buffer)
748 PyMem_Free(self->buffer);
749 self->buffer = PyMem_Malloc(self->buffer_size);
750 if (self->buffer == NULL) {
751 PyErr_NoMemory();
752 return -1;
753 }
Georg Brandldfd73442009-04-05 11:47:34 +0000754#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000755 if (self->lock)
756 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000757 self->lock = PyThread_allocate_lock();
758 if (self->lock == NULL) {
759 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
760 return -1;
761 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000762 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000763#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000764 /* Find out whether buffer_size is a power of 2 */
765 /* XXX is this optimization useful? */
766 for (n = self->buffer_size - 1; n & 1; n >>= 1)
767 ;
768 if (n == 0)
769 self->buffer_mask = self->buffer_size - 1;
770 else
771 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000772 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773 PyErr_Clear();
774 return 0;
775}
776
Antoine Pitrou707ce822011-02-25 21:24:11 +0000777/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
778 clears the error indicator), 0 otherwise.
779 Should only be called when PyErr_Occurred() is true.
780*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700781int
782_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000783{
784 static PyObject *eintr_int = NULL;
785 PyObject *typ, *val, *tb;
786 PyEnvironmentErrorObject *env_err;
787
788 if (eintr_int == NULL) {
789 eintr_int = PyLong_FromLong(EINTR);
790 assert(eintr_int != NULL);
791 }
792 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
793 return 0;
794 PyErr_Fetch(&typ, &val, &tb);
795 PyErr_NormalizeException(&typ, &val, &tb);
796 env_err = (PyEnvironmentErrorObject *) val;
797 assert(env_err != NULL);
798 if (env_err->myerrno != NULL &&
799 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
800 Py_DECREF(typ);
801 Py_DECREF(val);
802 Py_XDECREF(tb);
803 return 1;
804 }
805 /* This silences any error set by PyObject_RichCompareBool() */
806 PyErr_Restore(typ, val, tb);
807 return 0;
808}
809
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000810/*
811 * Shared methods and wrappers
812 */
813
814static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200815buffered_flush_and_rewind_unlocked(buffered *self)
816{
817 PyObject *res;
818
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100819 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200820 if (res == NULL)
821 return NULL;
822 Py_DECREF(res);
823
824 if (self->readable) {
825 /* Rewind the raw stream so that its position corresponds to
826 the current logical position. */
827 Py_off_t n;
828 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
829 _bufferedreader_reset_buf(self);
830 if (n == -1)
831 return NULL;
832 }
833 Py_RETURN_NONE;
834}
835
836static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000837buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000838{
839 PyObject *res;
840
841 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000842 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000844 if (!ENTER_BUFFERED(self))
845 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200846 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000847 LEAVE_BUFFERED(self)
848
849 return res;
850}
851
852static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000853buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000854{
855 Py_ssize_t n = 0;
856 PyObject *res = NULL;
857
858 CHECK_INITIALIZED(self)
859 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
860 return NULL;
861 }
862
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000863 if (!ENTER_BUFFERED(self))
864 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000865
866 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200867 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868 if (res == NULL)
869 goto end;
870 Py_CLEAR(res);
871 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200872 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000873
874end:
875 LEAVE_BUFFERED(self)
876 return res;
877}
878
879static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000880buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881{
882 Py_ssize_t n = -1;
883 PyObject *res;
884
885 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000886 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887 return NULL;
888 }
889 if (n < -1) {
890 PyErr_SetString(PyExc_ValueError,
891 "read length must be positive or -1");
892 return NULL;
893 }
894
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000895 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000897 if (n == -1) {
898 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000899 if (!ENTER_BUFFERED(self))
900 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000901 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000902 }
903 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000904 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200905 if (res != Py_None)
906 return res;
907 Py_DECREF(res);
908 if (!ENTER_BUFFERED(self))
909 return NULL;
910 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000911 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912
Antoine Pitroue05565e2011-08-20 14:39:23 +0200913 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000914 return res;
915}
916
917static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000918buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000919{
920 Py_ssize_t n, have, r;
921 PyObject *res = NULL;
922
923 CHECK_INITIALIZED(self)
924 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
925 return NULL;
926 }
927
928 if (n < 0) {
929 PyErr_SetString(PyExc_ValueError,
930 "read length must be positive");
931 return NULL;
932 }
933 if (n == 0)
934 return PyBytes_FromStringAndSize(NULL, 0);
935
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936 /* Return up to n bytes. If at least one byte is buffered, we
937 only return buffered bytes. Otherwise, we do one raw read. */
938
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
940 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100941 n = Py_MIN(have, n);
942 res = _bufferedreader_read_fast(self, n);
943 assert(res != Py_None);
944 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100946 res = PyBytes_FromStringAndSize(NULL, n);
947 if (res == NULL)
948 return NULL;
949 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200950 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100951 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200952 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000953 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
955 LEAVE_BUFFERED(self)
956 if (r == -1) {
957 Py_DECREF(res);
958 return NULL;
959 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960 if (r == -2)
961 r = 0;
962 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100963 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964 return res;
965}
966
967static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000968buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200970 Py_buffer buf;
971 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 PyObject *res = NULL;
973
974 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200975
976 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
977 return NULL;
978
979 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
980 if (n > 0) {
981 if (n >= buf.len) {
982 memcpy(buf.buf, self->buffer + self->pos, buf.len);
983 self->pos += buf.len;
984 res = PyLong_FromSsize_t(buf.len);
985 goto end_unlocked;
986 }
987 memcpy(buf.buf, self->buffer + self->pos, n);
988 self->pos += n;
989 written = n;
990 }
991
992 if (!ENTER_BUFFERED(self))
993 goto end_unlocked;
994
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200996 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997 if (res == NULL)
998 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200999 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001000 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001001
1002 _bufferedreader_reset_buf(self);
1003 self->pos = 0;
1004
1005 for (remaining = buf.len - written;
1006 remaining > 0;
1007 written += n, remaining -= n) {
1008 /* If remaining bytes is larger than internal buffer size, copy
1009 * directly into caller's buffer. */
1010 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001011 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1012 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001013 }
1014 else {
1015 n = _bufferedreader_fill_buffer(self);
1016 if (n > 0) {
1017 if (n > remaining)
1018 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001019 memcpy((char *) buf.buf + written,
1020 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 self->pos += n;
1022 continue; /* short circuit */
1023 }
1024 }
1025 if (n == 0 || (n == -2 && written > 0))
1026 break;
1027 if (n < 0) {
1028 if (n == -2) {
1029 Py_INCREF(Py_None);
1030 res = Py_None;
1031 }
1032 goto end;
1033 }
1034 }
1035 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001036
1037end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001038 LEAVE_BUFFERED(self);
1039end_unlocked:
1040 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 return res;
1042}
1043
1044static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001045_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046{
1047 PyObject *res = NULL;
1048 PyObject *chunks = NULL;
1049 Py_ssize_t n, written = 0;
1050 const char *start, *s, *end;
1051
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001052 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001053
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001054 /* First, try to find a line in the buffer. This can run unlocked because
1055 the calls to the C API are simple enough that they can't trigger
1056 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001057 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1058 if (limit >= 0 && n > limit)
1059 n = limit;
1060 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001061 s = memchr(start, '\n', n);
1062 if (s != NULL) {
1063 res = PyBytes_FromStringAndSize(start, s - start + 1);
1064 if (res != NULL)
1065 self->pos += s - start + 1;
1066 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067 }
1068 if (n == limit) {
1069 res = PyBytes_FromStringAndSize(start, n);
1070 if (res != NULL)
1071 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001072 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001073 }
1074
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001075 if (!ENTER_BUFFERED(self))
1076 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001077
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001078 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079 chunks = PyList_New(0);
1080 if (chunks == NULL)
1081 goto end;
1082 if (n > 0) {
1083 res = PyBytes_FromStringAndSize(start, n);
1084 if (res == NULL)
1085 goto end;
1086 if (PyList_Append(chunks, res) < 0) {
1087 Py_CLEAR(res);
1088 goto end;
1089 }
1090 Py_CLEAR(res);
1091 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001092 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001093 if (limit >= 0)
1094 limit -= n;
1095 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001096 if (self->writable) {
1097 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1098 if (r == NULL)
1099 goto end;
1100 Py_DECREF(r);
1101 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102
1103 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001104 _bufferedreader_reset_buf(self);
1105 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106 if (n == -1)
1107 goto end;
1108 if (n <= 0)
1109 break;
1110 if (limit >= 0 && n > limit)
1111 n = limit;
1112 start = self->buffer;
1113 end = start + n;
1114 s = start;
1115 while (s < end) {
1116 if (*s++ == '\n') {
1117 res = PyBytes_FromStringAndSize(start, s - start);
1118 if (res == NULL)
1119 goto end;
1120 self->pos = s - start;
1121 goto found;
1122 }
1123 }
1124 res = PyBytes_FromStringAndSize(start, n);
1125 if (res == NULL)
1126 goto end;
1127 if (n == limit) {
1128 self->pos = n;
1129 break;
1130 }
1131 if (PyList_Append(chunks, res) < 0) {
1132 Py_CLEAR(res);
1133 goto end;
1134 }
1135 Py_CLEAR(res);
1136 written += n;
1137 if (limit >= 0)
1138 limit -= n;
1139 }
1140found:
1141 if (res != NULL && PyList_Append(chunks, res) < 0) {
1142 Py_CLEAR(res);
1143 goto end;
1144 }
1145 Py_CLEAR(res);
1146 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1147
1148end:
1149 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001150end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001151 Py_XDECREF(chunks);
1152 return res;
1153}
1154
1155static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001156buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001157{
1158 Py_ssize_t limit = -1;
1159
1160 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001161 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001162 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001163 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001164}
1165
1166
1167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001168buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001169{
1170 Py_off_t pos;
1171
1172 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001173 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 if (pos == -1)
1175 return NULL;
1176 pos -= RAW_OFFSET(self);
1177 /* TODO: sanity check (pos >= 0) */
1178 return PyLong_FromOff_t(pos);
1179}
1180
1181static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001182buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183{
1184 Py_off_t target, n;
1185 int whence = 0;
1186 PyObject *targetobj, *res = NULL;
1187
1188 CHECK_INITIALIZED(self)
1189 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1190 return NULL;
1191 }
Jesus Cea94363612012-06-22 18:32:07 +02001192
1193 /* Do some error checking instead of trusting OS 'seek()'
1194 ** error detection, just in case.
1195 */
1196 if ((whence < 0 || whence >2)
1197#ifdef SEEK_HOLE
1198 && (whence != SEEK_HOLE)
1199#endif
1200#ifdef SEEK_DATA
1201 && (whence != SEEK_DATA)
1202#endif
1203 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001205 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206 return NULL;
1207 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001208
1209 CHECK_CLOSED(self, "seek of closed file")
1210
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001211 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1212 return NULL;
1213
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001214 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1215 if (target == -1 && PyErr_Occurred())
1216 return NULL;
1217
Jesus Cea94363612012-06-22 18:32:07 +02001218 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1219 buffer. Other whence values must be managed without this optimization.
1220 Some Operating Systems can provide additional values, like
1221 SEEK_HOLE/SEEK_DATA. */
1222 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001223 Py_off_t current, avail;
1224 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001225 so as to return quickly if possible. Also, we needn't take the
1226 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001228 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1229 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 current = RAW_TELL(self);
1231 avail = READAHEAD(self);
1232 if (avail > 0) {
1233 Py_off_t offset;
1234 if (whence == 0)
1235 offset = target - (current - RAW_OFFSET(self));
1236 else
1237 offset = target;
1238 if (offset >= -self->pos && offset <= avail) {
1239 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001240 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001241 }
1242 }
1243 }
1244
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001245 if (!ENTER_BUFFERED(self))
1246 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001247
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001248 /* Fallback: invoke raw seek() method and clear buffer */
1249 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001250 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 if (res == NULL)
1252 goto end;
1253 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001254 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001255 }
1256
1257 /* TODO: align on block boundary and read buffer if needed? */
1258 if (whence == 1)
1259 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001260 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001261 if (n == -1)
1262 goto end;
1263 self->raw_pos = -1;
1264 res = PyLong_FromOff_t(n);
1265 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001266 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001267
1268end:
1269 LEAVE_BUFFERED(self)
1270 return res;
1271}
1272
1273static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001274buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275{
1276 PyObject *pos = Py_None;
1277 PyObject *res = NULL;
1278
1279 CHECK_INITIALIZED(self)
1280 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1281 return NULL;
1282 }
1283
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001284 if (!ENTER_BUFFERED(self))
1285 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286
1287 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001288 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 if (res == NULL)
1290 goto end;
1291 Py_CLEAR(res);
1292 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001293 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1294 if (res == NULL)
1295 goto end;
1296 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001297 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298 PyErr_Clear();
1299
1300end:
1301 LEAVE_BUFFERED(self)
1302 return res;
1303}
1304
1305static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001306buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307{
1308 PyObject *line;
1309 PyTypeObject *tp;
1310
1311 CHECK_INITIALIZED(self);
1312
1313 tp = Py_TYPE(self);
1314 if (tp == &PyBufferedReader_Type ||
1315 tp == &PyBufferedRandom_Type) {
1316 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001317 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001318 }
1319 else {
1320 line = PyObject_CallMethodObjArgs((PyObject *)self,
1321 _PyIO_str_readline, NULL);
1322 if (line && !PyBytes_Check(line)) {
1323 PyErr_Format(PyExc_IOError,
1324 "readline() should have returned a bytes object, "
1325 "not '%.200s'", Py_TYPE(line)->tp_name);
1326 Py_DECREF(line);
1327 return NULL;
1328 }
1329 }
1330
1331 if (line == NULL)
1332 return NULL;
1333
1334 if (PyBytes_GET_SIZE(line) == 0) {
1335 /* Reached EOF or would have blocked */
1336 Py_DECREF(line);
1337 return NULL;
1338 }
1339
1340 return line;
1341}
1342
Antoine Pitrou716c4442009-05-23 19:04:03 +00001343static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001344buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001345{
1346 PyObject *nameobj, *res;
1347
Martin v. Löwis767046a2011-10-14 15:35:36 +02001348 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001349 if (nameobj == NULL) {
1350 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1351 PyErr_Clear();
1352 else
1353 return NULL;
1354 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1355 }
1356 else {
1357 res = PyUnicode_FromFormat("<%s name=%R>",
1358 Py_TYPE(self)->tp_name, nameobj);
1359 Py_DECREF(nameobj);
1360 }
1361 return res;
1362}
1363
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001364/*
1365 * class BufferedReader
1366 */
1367
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001368PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001369 "Create a new buffered reader using the given readable raw IO object.");
1370
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372{
1373 self->read_end = -1;
1374}
1375
1376static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001377bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001378{
1379 char *kwlist[] = {"raw", "buffer_size", NULL};
1380 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1381 PyObject *raw;
1382
1383 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001384 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001385
1386 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1387 &raw, &buffer_size)) {
1388 return -1;
1389 }
1390
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001391 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001392 return -1;
1393
1394 Py_CLEAR(self->raw);
1395 Py_INCREF(raw);
1396 self->raw = raw;
1397 self->buffer_size = buffer_size;
1398 self->readable = 1;
1399 self->writable = 0;
1400
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001401 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001402 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001403 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001404
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001405 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1406 Py_TYPE(raw) == &PyFileIO_Type);
1407
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001408 self->ok = 1;
1409 return 0;
1410}
1411
1412static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001413_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001414{
1415 Py_buffer buf;
1416 PyObject *memobj, *res;
1417 Py_ssize_t n;
1418 /* NOTE: the buffer needn't be released as its object is NULL. */
1419 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1420 return -1;
1421 memobj = PyMemoryView_FromBuffer(&buf);
1422 if (memobj == NULL)
1423 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001424 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1425 occurs so we needn't do it ourselves.
1426 We then retry reading, ignoring the signal if no handler has
1427 raised (see issue #10956).
1428 */
1429 do {
1430 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001431 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001432 Py_DECREF(memobj);
1433 if (res == NULL)
1434 return -1;
1435 if (res == Py_None) {
1436 /* Non-blocking stream would have blocked. Special return code! */
1437 Py_DECREF(res);
1438 return -2;
1439 }
1440 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1441 Py_DECREF(res);
1442 if (n < 0 || n > len) {
1443 PyErr_Format(PyExc_IOError,
1444 "raw readinto() returned invalid length %zd "
1445 "(should have been between 0 and %zd)", n, len);
1446 return -1;
1447 }
1448 if (n > 0 && self->abs_pos != -1)
1449 self->abs_pos += n;
1450 return n;
1451}
1452
1453static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001454_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001455{
1456 Py_ssize_t start, len, n;
1457 if (VALID_READ_BUFFER(self))
1458 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1459 else
1460 start = 0;
1461 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001462 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463 if (n <= 0)
1464 return n;
1465 self->read_end = start + n;
1466 self->raw_pos = start + n;
1467 return n;
1468}
1469
1470static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001471_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001472{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001473 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001474 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001475
1476 /* First copy what we have in the current buffer. */
1477 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1478 if (current_size) {
1479 data = PyBytes_FromStringAndSize(
1480 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001481 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001482 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001483 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001485 /* We're going past the buffer's bounds, flush it */
1486 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001487 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001488 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001489 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001490 Py_CLEAR(res);
1491 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001492 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001493
1494 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1495 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1496 if (chunk == NULL)
1497 return NULL;
1498 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1499 Py_XDECREF(data);
1500 Py_DECREF(chunk);
1501 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1502 return NULL;
1503 }
1504 if (chunk == Py_None) {
1505 if (current_size == 0)
1506 return chunk;
1507 else {
1508 Py_DECREF(chunk);
1509 return data;
1510 }
1511 }
1512 else if (current_size) {
1513 PyBytes_Concat(&data, chunk);
1514 Py_DECREF(chunk);
1515 if (data == NULL)
1516 return NULL;
1517 return data;
1518 } else
1519 return chunk;
1520 }
1521
1522 chunks = PyList_New(0);
Christian Heimes8f734eb2012-09-10 17:46:09 +02001523 if (chunks == NULL) {
1524 Py_XDECREF(data);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001525 return NULL;
Christian Heimes8f734eb2012-09-10 17:46:09 +02001526 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001527
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001528 while (1) {
1529 if (data) {
1530 if (PyList_Append(chunks, data) < 0) {
1531 Py_DECREF(data);
1532 Py_DECREF(chunks);
1533 return NULL;
1534 }
1535 Py_DECREF(data);
1536 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001538 /* Read until EOF or until read() would block. */
1539 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1540 if (data == NULL) {
1541 Py_DECREF(chunks);
1542 return NULL;
1543 }
1544 if (data != Py_None && !PyBytes_Check(data)) {
1545 Py_DECREF(data);
1546 Py_DECREF(chunks);
1547 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1548 return NULL;
1549 }
1550 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1551 if (current_size == 0) {
1552 Py_DECREF(chunks);
1553 return data;
1554 }
1555 else {
1556 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1557 Py_DECREF(data);
1558 Py_DECREF(chunks);
1559 return res;
1560 }
1561 }
1562 current_size += PyBytes_GET_SIZE(data);
1563 if (self->abs_pos != -1)
1564 self->abs_pos += PyBytes_GET_SIZE(data);
1565 }
1566}
1567
1568/* Read n bytes from the buffer if it can, otherwise return None.
1569 This function is simple enough that it can run unlocked. */
1570static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001571_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572{
1573 Py_ssize_t current_size;
1574
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001575 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1576 if (n <= current_size) {
1577 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1579 if (res != NULL)
1580 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001581 return res;
1582 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 Py_RETURN_NONE;
1584}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001585
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586/* Generic read function: read from the stream until enough bytes are read,
1587 * or until an EOF occurs or until read() would block.
1588 */
1589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001590_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591{
1592 PyObject *res = NULL;
1593 Py_ssize_t current_size, remaining, written;
1594 char *out;
1595
1596 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1597 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001598 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001600 res = PyBytes_FromStringAndSize(NULL, n);
1601 if (res == NULL)
1602 goto error;
1603 out = PyBytes_AS_STRING(res);
1604 remaining = n;
1605 written = 0;
1606 if (current_size > 0) {
1607 memcpy(out, self->buffer + self->pos, current_size);
1608 remaining -= current_size;
1609 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001610 self->pos += current_size;
1611 }
1612 /* Flush the write buffer if necessary */
1613 if (self->writable) {
1614 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1615 if (r == NULL)
1616 goto error;
1617 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001618 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001619 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620 while (remaining > 0) {
1621 /* We want to read a whole block at the end into buffer.
1622 If we had readv() we could do this in one pass. */
1623 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1624 if (r == 0)
1625 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001626 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001627 if (r == -1)
1628 goto error;
1629 if (r == 0 || r == -2) {
1630 /* EOF occurred or read() would block. */
1631 if (r == 0 || written > 0) {
1632 if (_PyBytes_Resize(&res, written))
1633 goto error;
1634 return res;
1635 }
1636 Py_DECREF(res);
1637 Py_INCREF(Py_None);
1638 return Py_None;
1639 }
1640 remaining -= r;
1641 written += r;
1642 }
1643 assert(remaining <= self->buffer_size);
1644 self->pos = 0;
1645 self->raw_pos = 0;
1646 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001647 /* NOTE: when the read is satisfied, we avoid issuing any additional
1648 reads, which could block indefinitely (e.g. on a socket).
1649 See issue #9550. */
1650 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001651 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001652 if (r == -1)
1653 goto error;
1654 if (r == 0 || r == -2) {
1655 /* EOF occurred or read() would block. */
1656 if (r == 0 || written > 0) {
1657 if (_PyBytes_Resize(&res, written))
1658 goto error;
1659 return res;
1660 }
1661 Py_DECREF(res);
1662 Py_INCREF(Py_None);
1663 return Py_None;
1664 }
1665 if (remaining > r) {
1666 memcpy(out + written, self->buffer + self->pos, r);
1667 written += r;
1668 self->pos += r;
1669 remaining -= r;
1670 }
1671 else if (remaining > 0) {
1672 memcpy(out + written, self->buffer + self->pos, remaining);
1673 written += remaining;
1674 self->pos += remaining;
1675 remaining = 0;
1676 }
1677 if (remaining == 0)
1678 break;
1679 }
1680
1681 return res;
1682
1683error:
1684 Py_XDECREF(res);
1685 return NULL;
1686}
1687
1688static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001689_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001690{
1691 Py_ssize_t have, r;
1692
1693 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1694 /* Constraints:
1695 1. we don't want to advance the file position.
1696 2. we don't want to lose block alignment, so we can't shift the buffer
1697 to make some place.
1698 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1699 */
1700 if (have > 0) {
1701 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1702 }
1703
1704 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 _bufferedreader_reset_buf(self);
1706 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001707 if (r == -1)
1708 return NULL;
1709 if (r == -2)
1710 r = 0;
1711 self->pos = 0;
1712 return PyBytes_FromStringAndSize(self->buffer, r);
1713}
1714
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001715static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001716 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001717 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1718 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1719 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1720 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1721 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1722 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1723 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1724 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001725 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001726 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001727
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001728 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1729 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1730 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001731 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001732 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1733 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1734 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1735 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001736 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 {NULL, NULL}
1738};
1739
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001740static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001741 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001742 {NULL}
1743};
1744
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001745static PyGetSetDef bufferedreader_getset[] = {
1746 {"closed", (getter)buffered_closed_get, NULL, NULL},
1747 {"name", (getter)buffered_name_get, NULL, NULL},
1748 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001749 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750};
1751
1752
1753PyTypeObject PyBufferedReader_Type = {
1754 PyVarObject_HEAD_INIT(NULL, 0)
1755 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001756 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759 0, /*tp_print*/
1760 0, /*tp_getattr*/
1761 0, /*tp_setattr*/
1762 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001763 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 0, /*tp_as_number*/
1765 0, /*tp_as_sequence*/
1766 0, /*tp_as_mapping*/
1767 0, /*tp_hash */
1768 0, /*tp_call*/
1769 0, /*tp_str*/
1770 0, /*tp_getattro*/
1771 0, /*tp_setattro*/
1772 0, /*tp_as_buffer*/
1773 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1774 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001775 bufferedreader_doc, /* tp_doc */
1776 (traverseproc)buffered_traverse, /* tp_traverse */
1777 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001779 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001781 (iternextfunc)buffered_iternext, /* tp_iternext */
1782 bufferedreader_methods, /* tp_methods */
1783 bufferedreader_members, /* tp_members */
1784 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 0, /* tp_base */
1786 0, /* tp_dict */
1787 0, /* tp_descr_get */
1788 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001789 offsetof(buffered, dict), /* tp_dictoffset */
1790 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791 0, /* tp_alloc */
1792 PyType_GenericNew, /* tp_new */
1793};
1794
1795
Benjamin Peterson59406a92009-03-26 17:10:29 +00001796
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797/*
1798 * class BufferedWriter
1799 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 "A buffer for a writeable sequential RawIO object.\n"
1802 "\n"
1803 "The constructor creates a BufferedWriter for the given writeable raw\n"
1804 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001805 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 );
1807
1808static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810{
1811 self->write_pos = 0;
1812 self->write_end = -1;
1813}
1814
1815static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001816bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001817{
Florent Xicluna109d5732012-07-07 17:03:22 +02001818 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001819 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 PyObject *raw;
1821
1822 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001823 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001824
R David Murray9f10f562013-02-23 22:07:55 -05001825 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001826 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 return -1;
1828 }
1829
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001830 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 return -1;
1832
1833 Py_CLEAR(self->raw);
1834 Py_INCREF(raw);
1835 self->raw = raw;
1836 self->readable = 0;
1837 self->writable = 1;
1838
1839 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001840 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001842 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001843 self->pos = 0;
1844
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001845 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1846 Py_TYPE(raw) == &PyFileIO_Type);
1847
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848 self->ok = 1;
1849 return 0;
1850}
1851
1852static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001853_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854{
1855 Py_buffer buf;
1856 PyObject *memobj, *res;
1857 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001858 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859 /* NOTE: the buffer needn't be released as its object is NULL. */
1860 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1861 return -1;
1862 memobj = PyMemoryView_FromBuffer(&buf);
1863 if (memobj == NULL)
1864 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001865 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1866 occurs so we needn't do it ourselves.
1867 We then retry writing, ignoring the signal if no handler has
1868 raised (see issue #10956).
1869 */
1870 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001871 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001872 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001873 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001874 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875 Py_DECREF(memobj);
1876 if (res == NULL)
1877 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001878 if (res == Py_None) {
1879 /* Non-blocking stream would have blocked. Special return code!
1880 Being paranoid we reset errno in case it is changed by code
1881 triggered by a decref. errno is used by _set_BlockingIOError(). */
1882 Py_DECREF(res);
1883 errno = errnum;
1884 return -2;
1885 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001886 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1887 Py_DECREF(res);
1888 if (n < 0 || n > len) {
1889 PyErr_Format(PyExc_IOError,
1890 "raw write() returned invalid length %zd "
1891 "(should have been between 0 and %zd)", n, len);
1892 return -1;
1893 }
1894 if (n > 0 && self->abs_pos != -1)
1895 self->abs_pos += n;
1896 return n;
1897}
1898
1899/* `restore_pos` is 1 if we need to restore the raw stream position at
1900 the end, 0 otherwise. */
1901static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001902_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001903{
1904 Py_ssize_t written = 0;
1905 Py_off_t n, rewind;
1906
1907 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1908 goto end;
1909 /* First, rewind */
1910 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1911 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001912 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913 if (n < 0) {
1914 goto error;
1915 }
1916 self->raw_pos -= rewind;
1917 }
1918 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001919 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001920 self->buffer + self->write_pos,
1921 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1922 Py_off_t, Py_ssize_t));
1923 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001924 goto error;
1925 }
1926 else if (n == -2) {
1927 _set_BlockingIOError("write could not complete without blocking",
1928 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929 goto error;
1930 }
1931 self->write_pos += n;
1932 self->raw_pos = self->write_pos;
1933 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001934 /* Partial writes can return successfully when interrupted by a
1935 signal (see write(2)). We must run signal handlers before
1936 blocking another time, possibly indefinitely. */
1937 if (PyErr_CheckSignals() < 0)
1938 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939 }
1940
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001941 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942
1943end:
1944 Py_RETURN_NONE;
1945
1946error:
1947 return NULL;
1948}
1949
1950static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952{
1953 PyObject *res = NULL;
1954 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001955 Py_ssize_t written, avail, remaining;
1956 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957
1958 CHECK_INITIALIZED(self)
1959 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1960 return NULL;
1961 }
1962
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001963 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 PyErr_SetString(PyExc_ValueError, "write to closed file");
1965 PyBuffer_Release(&buf);
1966 return NULL;
1967 }
1968
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001969 if (!ENTER_BUFFERED(self)) {
1970 PyBuffer_Release(&buf);
1971 return NULL;
1972 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973
1974 /* Fast path: the data to write can be fully buffered. */
1975 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1976 self->pos = 0;
1977 self->raw_pos = 0;
1978 }
1979 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1980 if (buf.len <= avail) {
1981 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001982 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983 self->write_pos = self->pos;
1984 }
1985 ADJUST_POSITION(self, self->pos + buf.len);
1986 if (self->pos > self->write_end)
1987 self->write_end = self->pos;
1988 written = buf.len;
1989 goto end;
1990 }
1991
1992 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001993 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001994 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001995 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 if (w == NULL)
1997 goto error;
1998 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001999 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000 /* Make some place by shifting the buffer. */
2001 assert(VALID_WRITE_BUFFER(self));
2002 memmove(self->buffer, self->buffer + self->write_pos,
2003 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2004 Py_off_t, Py_ssize_t));
2005 self->write_end -= self->write_pos;
2006 self->raw_pos -= self->write_pos;
2007 self->pos -= self->write_pos;
2008 self->write_pos = 0;
2009 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2010 Py_off_t, Py_ssize_t);
2011 if (buf.len <= avail) {
2012 /* Everything can be buffered */
2013 PyErr_Clear();
2014 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2015 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002016 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 written = buf.len;
2018 goto end;
2019 }
2020 /* Buffer as much as possible. */
2021 memcpy(self->buffer + self->write_end, buf.buf, avail);
2022 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002023 self->pos += avail;
2024 /* XXX Modifying the existing exception e using the pointer w
2025 will change e.characters_written but not e.args[2].
2026 Therefore we just replace with a new error. */
2027 _set_BlockingIOError("write could not complete without blocking",
2028 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 goto error;
2030 }
2031 Py_CLEAR(res);
2032
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002033 /* Adjust the raw stream position if it is away from the logical stream
2034 position. This happens if the read buffer has been filled but not
2035 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2036 the raw stream by itself).
2037 Fixes issue #6629.
2038 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002039 offset = RAW_OFFSET(self);
2040 if (offset != 0) {
2041 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002042 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002043 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002044 }
2045
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 /* Then write buf itself. At this point the buffer has been emptied. */
2047 remaining = buf.len;
2048 written = 0;
2049 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002050 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 self, (char *) buf.buf + written, buf.len - written);
2052 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002053 goto error;
2054 } else if (n == -2) {
2055 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 if (remaining > self->buffer_size) {
2057 /* Can't buffer everything, still buffer as much as possible */
2058 memcpy(self->buffer,
2059 (char *) buf.buf + written, self->buffer_size);
2060 self->raw_pos = 0;
2061 ADJUST_POSITION(self, self->buffer_size);
2062 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002063 written += self->buffer_size;
2064 _set_BlockingIOError("write could not complete without "
2065 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 goto error;
2067 }
2068 PyErr_Clear();
2069 break;
2070 }
2071 written += n;
2072 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002073 /* Partial writes can return successfully when interrupted by a
2074 signal (see write(2)). We must run signal handlers before
2075 blocking another time, possibly indefinitely. */
2076 if (PyErr_CheckSignals() < 0)
2077 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078 }
2079 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002080 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 if (remaining > 0) {
2082 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2083 written += remaining;
2084 }
2085 self->write_pos = 0;
2086 /* TODO: sanity check (remaining >= 0) */
2087 self->write_end = remaining;
2088 ADJUST_POSITION(self, remaining);
2089 self->raw_pos = 0;
2090
2091end:
2092 res = PyLong_FromSsize_t(written);
2093
2094error:
2095 LEAVE_BUFFERED(self)
2096 PyBuffer_Release(&buf);
2097 return res;
2098}
2099
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002102 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2103 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2104 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2105 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2106 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2107 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2108 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002109 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002110 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2113 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2114 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2115 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2116 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002117 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118 {NULL, NULL}
2119};
2120
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002122 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123 {NULL}
2124};
2125
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126static PyGetSetDef bufferedwriter_getset[] = {
2127 {"closed", (getter)buffered_closed_get, NULL, NULL},
2128 {"name", (getter)buffered_name_get, NULL, NULL},
2129 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002130 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131};
2132
2133
2134PyTypeObject PyBufferedWriter_Type = {
2135 PyVarObject_HEAD_INIT(NULL, 0)
2136 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002137 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140 0, /*tp_print*/
2141 0, /*tp_getattr*/
2142 0, /*tp_setattr*/
2143 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002144 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145 0, /*tp_as_number*/
2146 0, /*tp_as_sequence*/
2147 0, /*tp_as_mapping*/
2148 0, /*tp_hash */
2149 0, /*tp_call*/
2150 0, /*tp_str*/
2151 0, /*tp_getattro*/
2152 0, /*tp_setattro*/
2153 0, /*tp_as_buffer*/
2154 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2155 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002156 bufferedwriter_doc, /* tp_doc */
2157 (traverseproc)buffered_traverse, /* tp_traverse */
2158 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002160 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161 0, /* tp_iter */
2162 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002163 bufferedwriter_methods, /* tp_methods */
2164 bufferedwriter_members, /* tp_members */
2165 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 0, /* tp_base */
2167 0, /* tp_dict */
2168 0, /* tp_descr_get */
2169 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 offsetof(buffered, dict), /* tp_dictoffset */
2171 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172 0, /* tp_alloc */
2173 PyType_GenericNew, /* tp_new */
2174};
2175
2176
2177
2178/*
2179 * BufferedRWPair
2180 */
2181
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002182PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183 "A buffered reader and writer object together.\n"
2184 "\n"
2185 "A buffered reader object and buffered writer object put together to\n"
2186 "form a sequential IO object that can read and write. This is typically\n"
2187 "used with a socket or two-way pipe.\n"
2188 "\n"
2189 "reader and writer are RawIOBase objects that are readable and\n"
2190 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002191 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 );
2193
2194/* XXX The usefulness of this (compared to having two separate IO objects) is
2195 * questionable.
2196 */
2197
2198typedef struct {
2199 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002200 buffered *reader;
2201 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 PyObject *dict;
2203 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002204} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205
2206static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002207bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208{
2209 PyObject *reader, *writer;
2210 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211
Florent Xicluna109d5732012-07-07 17:03:22 +02002212 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2213 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214 return -1;
2215 }
2216
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002219 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220 return -1;
2221
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002223 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 if (self->reader == NULL)
2225 return -1;
2226
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002228 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 if (self->writer == NULL) {
2230 Py_CLEAR(self->reader);
2231 return -1;
2232 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002233
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234 return 0;
2235}
2236
2237static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002238bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239{
2240 Py_VISIT(self->dict);
2241 return 0;
2242}
2243
2244static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002245bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246{
2247 Py_CLEAR(self->reader);
2248 Py_CLEAR(self->writer);
2249 Py_CLEAR(self->dict);
2250 return 0;
2251}
2252
2253static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002254bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255{
2256 _PyObject_GC_UNTRACK(self);
2257 Py_CLEAR(self->reader);
2258 Py_CLEAR(self->writer);
2259 Py_CLEAR(self->dict);
2260 Py_TYPE(self)->tp_free((PyObject *) self);
2261}
2262
2263static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002264_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002266 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267 PyObject *ret;
2268
2269 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002270 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271 return NULL;
2272 }
2273
2274 ret = PyObject_CallObject(func, args);
2275 Py_DECREF(func);
2276 return ret;
2277}
2278
2279static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002280bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002282 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002283}
2284
2285static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002286bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002287{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002288 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289}
2290
2291static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002292bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002294 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002295}
2296
2297static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002298bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002299{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002300 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002301}
2302
2303static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002304bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002306 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307}
2308
2309static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002310bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002311{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002312 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313}
2314
2315static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002316bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002318 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319}
2320
2321static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002322bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002324 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002325}
2326
2327static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002328bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002330 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331 if (ret == NULL)
2332 return NULL;
2333 Py_DECREF(ret);
2334
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002335 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002336}
2337
2338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002340{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002341 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002342
2343 if (ret != Py_False) {
2344 /* either True or exception */
2345 return ret;
2346 }
2347 Py_DECREF(ret);
2348
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002349 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002350}
2351
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002352static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002353bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002354{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002355 if (self->writer == NULL) {
2356 PyErr_SetString(PyExc_RuntimeError,
2357 "the BufferedRWPair object is being garbage-collected");
2358 return NULL;
2359 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002360 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2361}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002362
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002363static PyMethodDef bufferedrwpair_methods[] = {
2364 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2365 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2366 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2367 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002368
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002369 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2370 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002372 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2373 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002374
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002375 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2376 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377
Antoine Pitrou243757e2010-11-05 21:15:39 +00002378 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2379
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002380 {NULL, NULL}
2381};
2382
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002383static PyGetSetDef bufferedrwpair_getset[] = {
2384 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002385 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002386};
2387
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388PyTypeObject PyBufferedRWPair_Type = {
2389 PyVarObject_HEAD_INIT(NULL, 0)
2390 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002391 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002392 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002393 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394 0, /*tp_print*/
2395 0, /*tp_getattr*/
2396 0, /*tp_setattr*/
2397 0, /*tp_compare */
2398 0, /*tp_repr*/
2399 0, /*tp_as_number*/
2400 0, /*tp_as_sequence*/
2401 0, /*tp_as_mapping*/
2402 0, /*tp_hash */
2403 0, /*tp_call*/
2404 0, /*tp_str*/
2405 0, /*tp_getattro*/
2406 0, /*tp_setattro*/
2407 0, /*tp_as_buffer*/
2408 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2409 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002410 bufferedrwpair_doc, /* tp_doc */
2411 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2412 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002413 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002414 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002415 0, /* tp_iter */
2416 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002417 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002419 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 0, /* tp_base */
2421 0, /* tp_dict */
2422 0, /* tp_descr_get */
2423 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002424 offsetof(rwpair, dict), /* tp_dictoffset */
2425 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426 0, /* tp_alloc */
2427 PyType_GenericNew, /* tp_new */
2428};
2429
2430
2431
2432/*
2433 * BufferedRandom
2434 */
2435
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002436PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002437 "A buffered interface to random access streams.\n"
2438 "\n"
2439 "The constructor creates a reader and writer for a seekable stream,\n"
2440 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002441 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442 );
2443
2444static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002445bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002446{
Florent Xicluna109d5732012-07-07 17:03:22 +02002447 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002448 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002449 PyObject *raw;
2450
2451 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002452 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453
R David Murray9f10f562013-02-23 22:07:55 -05002454 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002455 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 return -1;
2457 }
2458
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002460 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002461 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002462 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002463 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002464 return -1;
2465
2466 Py_CLEAR(self->raw);
2467 Py_INCREF(raw);
2468 self->raw = raw;
2469 self->buffer_size = buffer_size;
2470 self->readable = 1;
2471 self->writable = 1;
2472
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002473 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002474 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002475 _bufferedreader_reset_buf(self);
2476 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002477 self->pos = 0;
2478
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002479 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2480 Py_TYPE(raw) == &PyFileIO_Type);
2481
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002482 self->ok = 1;
2483 return 0;
2484}
2485
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002486static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002487 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002488 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2489 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2490 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2491 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2492 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2493 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2494 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002495 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002496 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002497
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002498 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002499
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002500 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2501 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2502 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2503 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2504 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2505 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2506 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2507 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2508 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002509 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002510 {NULL, NULL}
2511};
2512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002513static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002514 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002515 {NULL}
2516};
2517
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002518static PyGetSetDef bufferedrandom_getset[] = {
2519 {"closed", (getter)buffered_closed_get, NULL, NULL},
2520 {"name", (getter)buffered_name_get, NULL, NULL},
2521 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002522 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002523};
2524
2525
2526PyTypeObject PyBufferedRandom_Type = {
2527 PyVarObject_HEAD_INIT(NULL, 0)
2528 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002529 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002530 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002531 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 0, /*tp_print*/
2533 0, /*tp_getattr*/
2534 0, /*tp_setattr*/
2535 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 0, /*tp_as_number*/
2538 0, /*tp_as_sequence*/
2539 0, /*tp_as_mapping*/
2540 0, /*tp_hash */
2541 0, /*tp_call*/
2542 0, /*tp_str*/
2543 0, /*tp_getattro*/
2544 0, /*tp_setattro*/
2545 0, /*tp_as_buffer*/
2546 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2547 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002548 bufferedrandom_doc, /* tp_doc */
2549 (traverseproc)buffered_traverse, /* tp_traverse */
2550 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002551 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002552 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002553 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002554 (iternextfunc)buffered_iternext, /* tp_iternext */
2555 bufferedrandom_methods, /* tp_methods */
2556 bufferedrandom_members, /* tp_members */
2557 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002558 0, /* tp_base */
2559 0, /*tp_dict*/
2560 0, /* tp_descr_get */
2561 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002562 offsetof(buffered, dict), /*tp_dictoffset*/
2563 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002564 0, /* tp_alloc */
2565 PyType_GenericNew, /* tp_new */
2566};