blob: 432349a7f6370c55f897576d90610932f4a47f59 [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{
487 PyObject *res = NULL;
488 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 Peterson4fa88fa2009-03-04 00:14:51 +0000515 if (res == NULL) {
Antoine Pitrou6be88762010-05-03 16:48:20 +0000516 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000517 }
518 Py_XDECREF(res);
519
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 Peterson4fa88fa2009-03-04 00:14:51 +0000527end:
528 LEAVE_BUFFERED(self)
529 return res;
530}
531
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000532/* detach */
533
534static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000535buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000536{
537 PyObject *raw, *res;
538 CHECK_INITIALIZED(self)
539 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
540 if (res == NULL)
541 return NULL;
542 Py_DECREF(res);
543 raw = self->raw;
544 self->raw = NULL;
545 self->detached = 1;
546 self->ok = 0;
547 return raw;
548}
549
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000550/* Inquiries */
551
552static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000553buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000554{
555 CHECK_INITIALIZED(self)
556 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
557}
558
559static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000560buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000561{
562 CHECK_INITIALIZED(self)
563 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
564}
565
566static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000567buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000568{
569 CHECK_INITIALIZED(self)
570 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
571}
572
573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000574buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575{
576 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200577 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578}
579
580static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000581buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582{
583 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200584 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585}
586
587/* Lower-level APIs */
588
589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000590buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591{
592 CHECK_INITIALIZED(self)
593 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
594}
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598{
599 CHECK_INITIALIZED(self)
600 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
601}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000602
Antoine Pitrou243757e2010-11-05 21:15:39 +0000603/* Serialization */
604
605static PyObject *
606buffered_getstate(buffered *self, PyObject *args)
607{
608 PyErr_Format(PyExc_TypeError,
609 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
610 return NULL;
611}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000612
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000613/* Forward decls */
614static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100615_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000617_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000619_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000621_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200623_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000628static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000629_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200630static Py_ssize_t
631_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000632
633/*
634 * Helpers
635 */
636
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100637/* Sets the current error to BlockingIOError */
638static void
639_set_BlockingIOError(char *msg, Py_ssize_t written)
640{
641 PyObject *err;
642 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
643 errno, msg, written);
644 if (err)
645 PyErr_SetObject(PyExc_BlockingIOError, err);
646 Py_XDECREF(err);
647}
648
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649/* Returns the address of the `written` member if a BlockingIOError was
650 raised, NULL otherwise. The error is always re-raised. */
651static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653{
654 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200655 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
657 PyErr_Fetch(&t, &v, &tb);
658 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
659 PyErr_Restore(t, v, tb);
660 return NULL;
661 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200662 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000663 /* TODO: sanity check (err->written >= 0) */
664 PyErr_Restore(t, v, tb);
665 return &err->written;
666}
667
668static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000669_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000672 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
674 if (res == NULL)
675 return -1;
676 n = PyNumber_AsOff_t(res, PyExc_ValueError);
677 Py_DECREF(res);
678 if (n < 0) {
679 if (!PyErr_Occurred())
680 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000681 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200682 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000683 return -1;
684 }
685 self->abs_pos = n;
686 return n;
687}
688
689static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000690_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691{
692 PyObject *res, *posobj, *whenceobj;
693 Py_off_t n;
694
695 posobj = PyLong_FromOff_t(target);
696 if (posobj == NULL)
697 return -1;
698 whenceobj = PyLong_FromLong(whence);
699 if (whenceobj == NULL) {
700 Py_DECREF(posobj);
701 return -1;
702 }
703 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
704 posobj, whenceobj, NULL);
705 Py_DECREF(posobj);
706 Py_DECREF(whenceobj);
707 if (res == NULL)
708 return -1;
709 n = PyNumber_AsOff_t(res, PyExc_ValueError);
710 Py_DECREF(res);
711 if (n < 0) {
712 if (!PyErr_Occurred())
713 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000714 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200715 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716 return -1;
717 }
718 self->abs_pos = n;
719 return n;
720}
721
722static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000723_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000724{
725 Py_ssize_t n;
726 if (self->buffer_size <= 0) {
727 PyErr_SetString(PyExc_ValueError,
728 "buffer size must be strictly positive");
729 return -1;
730 }
731 if (self->buffer)
732 PyMem_Free(self->buffer);
733 self->buffer = PyMem_Malloc(self->buffer_size);
734 if (self->buffer == NULL) {
735 PyErr_NoMemory();
736 return -1;
737 }
Georg Brandldfd73442009-04-05 11:47:34 +0000738#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000739 if (self->lock)
740 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 self->lock = PyThread_allocate_lock();
742 if (self->lock == NULL) {
743 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
744 return -1;
745 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000746 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000747#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000748 /* Find out whether buffer_size is a power of 2 */
749 /* XXX is this optimization useful? */
750 for (n = self->buffer_size - 1; n & 1; n >>= 1)
751 ;
752 if (n == 0)
753 self->buffer_mask = self->buffer_size - 1;
754 else
755 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000756 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000757 PyErr_Clear();
758 return 0;
759}
760
Antoine Pitrou707ce822011-02-25 21:24:11 +0000761/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
762 clears the error indicator), 0 otherwise.
763 Should only be called when PyErr_Occurred() is true.
764*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700765int
766_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000767{
768 static PyObject *eintr_int = NULL;
769 PyObject *typ, *val, *tb;
770 PyEnvironmentErrorObject *env_err;
771
772 if (eintr_int == NULL) {
773 eintr_int = PyLong_FromLong(EINTR);
774 assert(eintr_int != NULL);
775 }
776 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
777 return 0;
778 PyErr_Fetch(&typ, &val, &tb);
779 PyErr_NormalizeException(&typ, &val, &tb);
780 env_err = (PyEnvironmentErrorObject *) val;
781 assert(env_err != NULL);
782 if (env_err->myerrno != NULL &&
783 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
784 Py_DECREF(typ);
785 Py_DECREF(val);
786 Py_XDECREF(tb);
787 return 1;
788 }
789 /* This silences any error set by PyObject_RichCompareBool() */
790 PyErr_Restore(typ, val, tb);
791 return 0;
792}
793
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000794/*
795 * Shared methods and wrappers
796 */
797
798static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200799buffered_flush_and_rewind_unlocked(buffered *self)
800{
801 PyObject *res;
802
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100803 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200804 if (res == NULL)
805 return NULL;
806 Py_DECREF(res);
807
808 if (self->readable) {
809 /* Rewind the raw stream so that its position corresponds to
810 the current logical position. */
811 Py_off_t n;
812 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
813 _bufferedreader_reset_buf(self);
814 if (n == -1)
815 return NULL;
816 }
817 Py_RETURN_NONE;
818}
819
820static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000821buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822{
823 PyObject *res;
824
825 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000826 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000827
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000828 if (!ENTER_BUFFERED(self))
829 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200830 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000831 LEAVE_BUFFERED(self)
832
833 return res;
834}
835
836static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000837buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000838{
839 Py_ssize_t n = 0;
840 PyObject *res = NULL;
841
842 CHECK_INITIALIZED(self)
843 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
844 return NULL;
845 }
846
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000847 if (!ENTER_BUFFERED(self))
848 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849
850 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200851 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852 if (res == NULL)
853 goto end;
854 Py_CLEAR(res);
855 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200856 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000857
858end:
859 LEAVE_BUFFERED(self)
860 return res;
861}
862
863static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000864buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000865{
866 Py_ssize_t n = -1;
867 PyObject *res;
868
869 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000870 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871 return NULL;
872 }
873 if (n < -1) {
874 PyErr_SetString(PyExc_ValueError,
875 "read length must be positive or -1");
876 return NULL;
877 }
878
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000879 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000881 if (n == -1) {
882 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000883 if (!ENTER_BUFFERED(self))
884 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000885 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000886 }
887 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000888 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200889 if (res != Py_None)
890 return res;
891 Py_DECREF(res);
892 if (!ENTER_BUFFERED(self))
893 return NULL;
894 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000895 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896
Antoine Pitroue05565e2011-08-20 14:39:23 +0200897 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000898 return res;
899}
900
901static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000902buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903{
904 Py_ssize_t n, have, r;
905 PyObject *res = NULL;
906
907 CHECK_INITIALIZED(self)
908 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
909 return NULL;
910 }
911
912 if (n < 0) {
913 PyErr_SetString(PyExc_ValueError,
914 "read length must be positive");
915 return NULL;
916 }
917 if (n == 0)
918 return PyBytes_FromStringAndSize(NULL, 0);
919
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 /* Return up to n bytes. If at least one byte is buffered, we
921 only return buffered bytes. Otherwise, we do one raw read. */
922
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
924 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100925 n = Py_MIN(have, n);
926 res = _bufferedreader_read_fast(self, n);
927 assert(res != Py_None);
928 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100930 res = PyBytes_FromStringAndSize(NULL, n);
931 if (res == NULL)
932 return NULL;
933 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200934 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100935 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200936 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000937 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100938 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
939 LEAVE_BUFFERED(self)
940 if (r == -1) {
941 Py_DECREF(res);
942 return NULL;
943 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000944 if (r == -2)
945 r = 0;
946 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100947 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 return res;
949}
950
951static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000952buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200954 Py_buffer buf;
955 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000956 PyObject *res = NULL;
957
958 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200959
960 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
961 return NULL;
962
963 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
964 if (n > 0) {
965 if (n >= buf.len) {
966 memcpy(buf.buf, self->buffer + self->pos, buf.len);
967 self->pos += buf.len;
968 res = PyLong_FromSsize_t(buf.len);
969 goto end_unlocked;
970 }
971 memcpy(buf.buf, self->buffer + self->pos, n);
972 self->pos += n;
973 written = n;
974 }
975
976 if (!ENTER_BUFFERED(self))
977 goto end_unlocked;
978
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000979 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200980 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981 if (res == NULL)
982 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200985
986 _bufferedreader_reset_buf(self);
987 self->pos = 0;
988
989 for (remaining = buf.len - written;
990 remaining > 0;
991 written += n, remaining -= n) {
992 /* If remaining bytes is larger than internal buffer size, copy
993 * directly into caller's buffer. */
994 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200995 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
996 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997 }
998 else {
999 n = _bufferedreader_fill_buffer(self);
1000 if (n > 0) {
1001 if (n > remaining)
1002 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001003 memcpy((char *) buf.buf + written,
1004 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001005 self->pos += n;
1006 continue; /* short circuit */
1007 }
1008 }
1009 if (n == 0 || (n == -2 && written > 0))
1010 break;
1011 if (n < 0) {
1012 if (n == -2) {
1013 Py_INCREF(Py_None);
1014 res = Py_None;
1015 }
1016 goto end;
1017 }
1018 }
1019 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001020
1021end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022 LEAVE_BUFFERED(self);
1023end_unlocked:
1024 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001025 return res;
1026}
1027
1028static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001029_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001030{
1031 PyObject *res = NULL;
1032 PyObject *chunks = NULL;
1033 Py_ssize_t n, written = 0;
1034 const char *start, *s, *end;
1035
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001036 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001037
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001038 /* First, try to find a line in the buffer. This can run unlocked because
1039 the calls to the C API are simple enough that they can't trigger
1040 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1042 if (limit >= 0 && n > limit)
1043 n = limit;
1044 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001045 s = memchr(start, '\n', n);
1046 if (s != NULL) {
1047 res = PyBytes_FromStringAndSize(start, s - start + 1);
1048 if (res != NULL)
1049 self->pos += s - start + 1;
1050 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001051 }
1052 if (n == limit) {
1053 res = PyBytes_FromStringAndSize(start, n);
1054 if (res != NULL)
1055 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001056 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001057 }
1058
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001059 if (!ENTER_BUFFERED(self))
1060 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001061
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001062 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001063 chunks = PyList_New(0);
1064 if (chunks == NULL)
1065 goto end;
1066 if (n > 0) {
1067 res = PyBytes_FromStringAndSize(start, n);
1068 if (res == NULL)
1069 goto end;
1070 if (PyList_Append(chunks, res) < 0) {
1071 Py_CLEAR(res);
1072 goto end;
1073 }
1074 Py_CLEAR(res);
1075 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001076 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001077 if (limit >= 0)
1078 limit -= n;
1079 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001080 if (self->writable) {
1081 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1082 if (r == NULL)
1083 goto end;
1084 Py_DECREF(r);
1085 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001086
1087 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001088 _bufferedreader_reset_buf(self);
1089 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 if (n == -1)
1091 goto end;
1092 if (n <= 0)
1093 break;
1094 if (limit >= 0 && n > limit)
1095 n = limit;
1096 start = self->buffer;
1097 end = start + n;
1098 s = start;
1099 while (s < end) {
1100 if (*s++ == '\n') {
1101 res = PyBytes_FromStringAndSize(start, s - start);
1102 if (res == NULL)
1103 goto end;
1104 self->pos = s - start;
1105 goto found;
1106 }
1107 }
1108 res = PyBytes_FromStringAndSize(start, n);
1109 if (res == NULL)
1110 goto end;
1111 if (n == limit) {
1112 self->pos = n;
1113 break;
1114 }
1115 if (PyList_Append(chunks, res) < 0) {
1116 Py_CLEAR(res);
1117 goto end;
1118 }
1119 Py_CLEAR(res);
1120 written += n;
1121 if (limit >= 0)
1122 limit -= n;
1123 }
1124found:
1125 if (res != NULL && PyList_Append(chunks, res) < 0) {
1126 Py_CLEAR(res);
1127 goto end;
1128 }
1129 Py_CLEAR(res);
1130 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1131
1132end:
1133 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001134end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001135 Py_XDECREF(chunks);
1136 return res;
1137}
1138
1139static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001140buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001141{
1142 Py_ssize_t limit = -1;
1143
1144 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001145 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001146 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001147 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001148}
1149
1150
1151static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001152buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001153{
1154 Py_off_t pos;
1155
1156 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001157 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001158 if (pos == -1)
1159 return NULL;
1160 pos -= RAW_OFFSET(self);
1161 /* TODO: sanity check (pos >= 0) */
1162 return PyLong_FromOff_t(pos);
1163}
1164
1165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001166buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001167{
1168 Py_off_t target, n;
1169 int whence = 0;
1170 PyObject *targetobj, *res = NULL;
1171
1172 CHECK_INITIALIZED(self)
1173 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1174 return NULL;
1175 }
Jesus Cea94363612012-06-22 18:32:07 +02001176
1177 /* Do some error checking instead of trusting OS 'seek()'
1178 ** error detection, just in case.
1179 */
1180 if ((whence < 0 || whence >2)
1181#ifdef SEEK_HOLE
1182 && (whence != SEEK_HOLE)
1183#endif
1184#ifdef SEEK_DATA
1185 && (whence != SEEK_DATA)
1186#endif
1187 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001188 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001189 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190 return NULL;
1191 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001192
1193 CHECK_CLOSED(self, "seek of closed file")
1194
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001195 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1196 return NULL;
1197
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001198 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1199 if (target == -1 && PyErr_Occurred())
1200 return NULL;
1201
Jesus Cea94363612012-06-22 18:32:07 +02001202 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1203 buffer. Other whence values must be managed without this optimization.
1204 Some Operating Systems can provide additional values, like
1205 SEEK_HOLE/SEEK_DATA. */
1206 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207 Py_off_t current, avail;
1208 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001209 so as to return quickly if possible. Also, we needn't take the
1210 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001211 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001212 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1213 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001214 current = RAW_TELL(self);
1215 avail = READAHEAD(self);
1216 if (avail > 0) {
1217 Py_off_t offset;
1218 if (whence == 0)
1219 offset = target - (current - RAW_OFFSET(self));
1220 else
1221 offset = target;
1222 if (offset >= -self->pos && offset <= avail) {
1223 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001224 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225 }
1226 }
1227 }
1228
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001229 if (!ENTER_BUFFERED(self))
1230 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001231
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001232 /* Fallback: invoke raw seek() method and clear buffer */
1233 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001234 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001235 if (res == NULL)
1236 goto end;
1237 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001238 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239 }
1240
1241 /* TODO: align on block boundary and read buffer if needed? */
1242 if (whence == 1)
1243 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001244 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245 if (n == -1)
1246 goto end;
1247 self->raw_pos = -1;
1248 res = PyLong_FromOff_t(n);
1249 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001250 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251
1252end:
1253 LEAVE_BUFFERED(self)
1254 return res;
1255}
1256
1257static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001258buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001259{
1260 PyObject *pos = Py_None;
1261 PyObject *res = NULL;
1262
1263 CHECK_INITIALIZED(self)
1264 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1265 return NULL;
1266 }
1267
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001268 if (!ENTER_BUFFERED(self))
1269 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270
1271 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001272 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 if (res == NULL)
1274 goto end;
1275 Py_CLEAR(res);
1276 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001277 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1278 if (res == NULL)
1279 goto end;
1280 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001281 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 PyErr_Clear();
1283
1284end:
1285 LEAVE_BUFFERED(self)
1286 return res;
1287}
1288
1289static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001290buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001291{
1292 PyObject *line;
1293 PyTypeObject *tp;
1294
1295 CHECK_INITIALIZED(self);
1296
1297 tp = Py_TYPE(self);
1298 if (tp == &PyBufferedReader_Type ||
1299 tp == &PyBufferedRandom_Type) {
1300 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001301 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001302 }
1303 else {
1304 line = PyObject_CallMethodObjArgs((PyObject *)self,
1305 _PyIO_str_readline, NULL);
1306 if (line && !PyBytes_Check(line)) {
1307 PyErr_Format(PyExc_IOError,
1308 "readline() should have returned a bytes object, "
1309 "not '%.200s'", Py_TYPE(line)->tp_name);
1310 Py_DECREF(line);
1311 return NULL;
1312 }
1313 }
1314
1315 if (line == NULL)
1316 return NULL;
1317
1318 if (PyBytes_GET_SIZE(line) == 0) {
1319 /* Reached EOF or would have blocked */
1320 Py_DECREF(line);
1321 return NULL;
1322 }
1323
1324 return line;
1325}
1326
Antoine Pitrou716c4442009-05-23 19:04:03 +00001327static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001328buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001329{
1330 PyObject *nameobj, *res;
1331
Martin v. Löwis767046a2011-10-14 15:35:36 +02001332 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001333 if (nameobj == NULL) {
1334 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1335 PyErr_Clear();
1336 else
1337 return NULL;
1338 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1339 }
1340 else {
1341 res = PyUnicode_FromFormat("<%s name=%R>",
1342 Py_TYPE(self)->tp_name, nameobj);
1343 Py_DECREF(nameobj);
1344 }
1345 return res;
1346}
1347
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001348/*
1349 * class BufferedReader
1350 */
1351
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001352PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001353 "Create a new buffered reader using the given readable raw IO object.");
1354
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001355static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001356{
1357 self->read_end = -1;
1358}
1359
1360static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001361bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362{
1363 char *kwlist[] = {"raw", "buffer_size", NULL};
1364 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1365 PyObject *raw;
1366
1367 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001368 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001369
1370 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1371 &raw, &buffer_size)) {
1372 return -1;
1373 }
1374
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001375 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001376 return -1;
1377
1378 Py_CLEAR(self->raw);
1379 Py_INCREF(raw);
1380 self->raw = raw;
1381 self->buffer_size = buffer_size;
1382 self->readable = 1;
1383 self->writable = 0;
1384
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001385 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001386 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001387 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001389 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1390 Py_TYPE(raw) == &PyFileIO_Type);
1391
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001392 self->ok = 1;
1393 return 0;
1394}
1395
1396static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001397_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001398{
1399 Py_buffer buf;
1400 PyObject *memobj, *res;
1401 Py_ssize_t n;
1402 /* NOTE: the buffer needn't be released as its object is NULL. */
1403 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1404 return -1;
1405 memobj = PyMemoryView_FromBuffer(&buf);
1406 if (memobj == NULL)
1407 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001408 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1409 occurs so we needn't do it ourselves.
1410 We then retry reading, ignoring the signal if no handler has
1411 raised (see issue #10956).
1412 */
1413 do {
1414 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001415 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416 Py_DECREF(memobj);
1417 if (res == NULL)
1418 return -1;
1419 if (res == Py_None) {
1420 /* Non-blocking stream would have blocked. Special return code! */
1421 Py_DECREF(res);
1422 return -2;
1423 }
1424 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1425 Py_DECREF(res);
1426 if (n < 0 || n > len) {
1427 PyErr_Format(PyExc_IOError,
1428 "raw readinto() returned invalid length %zd "
1429 "(should have been between 0 and %zd)", n, len);
1430 return -1;
1431 }
1432 if (n > 0 && self->abs_pos != -1)
1433 self->abs_pos += n;
1434 return n;
1435}
1436
1437static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001438_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001439{
1440 Py_ssize_t start, len, n;
1441 if (VALID_READ_BUFFER(self))
1442 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1443 else
1444 start = 0;
1445 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001446 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001447 if (n <= 0)
1448 return n;
1449 self->read_end = start + n;
1450 self->raw_pos = start + n;
1451 return n;
1452}
1453
1454static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001455_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001456{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001457 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001458 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001459
1460 /* First copy what we have in the current buffer. */
1461 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1462 if (current_size) {
1463 data = PyBytes_FromStringAndSize(
1464 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001465 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001467 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001468 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001469 /* We're going past the buffer's bounds, flush it */
1470 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001471 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001472 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001473 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001474 Py_CLEAR(res);
1475 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001476 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001477
1478 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1479 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1480 if (chunk == NULL)
1481 return NULL;
1482 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1483 Py_XDECREF(data);
1484 Py_DECREF(chunk);
1485 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1486 return NULL;
1487 }
1488 if (chunk == Py_None) {
1489 if (current_size == 0)
1490 return chunk;
1491 else {
1492 Py_DECREF(chunk);
1493 return data;
1494 }
1495 }
1496 else if (current_size) {
1497 PyBytes_Concat(&data, chunk);
1498 Py_DECREF(chunk);
1499 if (data == NULL)
1500 return NULL;
1501 return data;
1502 } else
1503 return chunk;
1504 }
1505
1506 chunks = PyList_New(0);
Christian Heimes8f734eb2012-09-10 17:46:09 +02001507 if (chunks == NULL) {
1508 Py_XDECREF(data);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001509 return NULL;
Christian Heimes8f734eb2012-09-10 17:46:09 +02001510 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001511
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001512 while (1) {
1513 if (data) {
1514 if (PyList_Append(chunks, data) < 0) {
1515 Py_DECREF(data);
1516 Py_DECREF(chunks);
1517 return NULL;
1518 }
1519 Py_DECREF(data);
1520 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001521
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001522 /* Read until EOF or until read() would block. */
1523 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1524 if (data == NULL) {
1525 Py_DECREF(chunks);
1526 return NULL;
1527 }
1528 if (data != Py_None && !PyBytes_Check(data)) {
1529 Py_DECREF(data);
1530 Py_DECREF(chunks);
1531 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1532 return NULL;
1533 }
1534 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1535 if (current_size == 0) {
1536 Py_DECREF(chunks);
1537 return data;
1538 }
1539 else {
1540 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1541 Py_DECREF(data);
1542 Py_DECREF(chunks);
1543 return res;
1544 }
1545 }
1546 current_size += PyBytes_GET_SIZE(data);
1547 if (self->abs_pos != -1)
1548 self->abs_pos += PyBytes_GET_SIZE(data);
1549 }
1550}
1551
1552/* Read n bytes from the buffer if it can, otherwise return None.
1553 This function is simple enough that it can run unlocked. */
1554static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001555_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001556{
1557 Py_ssize_t current_size;
1558
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001559 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1560 if (n <= current_size) {
1561 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001562 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1563 if (res != NULL)
1564 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001565 return res;
1566 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567 Py_RETURN_NONE;
1568}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001569
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001570/* Generic read function: read from the stream until enough bytes are read,
1571 * or until an EOF occurs or until read() would block.
1572 */
1573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001574_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001575{
1576 PyObject *res = NULL;
1577 Py_ssize_t current_size, remaining, written;
1578 char *out;
1579
1580 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1581 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001582 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001584 res = PyBytes_FromStringAndSize(NULL, n);
1585 if (res == NULL)
1586 goto error;
1587 out = PyBytes_AS_STRING(res);
1588 remaining = n;
1589 written = 0;
1590 if (current_size > 0) {
1591 memcpy(out, self->buffer + self->pos, current_size);
1592 remaining -= current_size;
1593 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001594 self->pos += current_size;
1595 }
1596 /* Flush the write buffer if necessary */
1597 if (self->writable) {
1598 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1599 if (r == NULL)
1600 goto error;
1601 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001602 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001603 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001604 while (remaining > 0) {
1605 /* We want to read a whole block at the end into buffer.
1606 If we had readv() we could do this in one pass. */
1607 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1608 if (r == 0)
1609 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001610 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001611 if (r == -1)
1612 goto error;
1613 if (r == 0 || r == -2) {
1614 /* EOF occurred or read() would block. */
1615 if (r == 0 || written > 0) {
1616 if (_PyBytes_Resize(&res, written))
1617 goto error;
1618 return res;
1619 }
1620 Py_DECREF(res);
1621 Py_INCREF(Py_None);
1622 return Py_None;
1623 }
1624 remaining -= r;
1625 written += r;
1626 }
1627 assert(remaining <= self->buffer_size);
1628 self->pos = 0;
1629 self->raw_pos = 0;
1630 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001631 /* NOTE: when the read is satisfied, we avoid issuing any additional
1632 reads, which could block indefinitely (e.g. on a socket).
1633 See issue #9550. */
1634 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001635 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001636 if (r == -1)
1637 goto error;
1638 if (r == 0 || r == -2) {
1639 /* EOF occurred or read() would block. */
1640 if (r == 0 || written > 0) {
1641 if (_PyBytes_Resize(&res, written))
1642 goto error;
1643 return res;
1644 }
1645 Py_DECREF(res);
1646 Py_INCREF(Py_None);
1647 return Py_None;
1648 }
1649 if (remaining > r) {
1650 memcpy(out + written, self->buffer + self->pos, r);
1651 written += r;
1652 self->pos += r;
1653 remaining -= r;
1654 }
1655 else if (remaining > 0) {
1656 memcpy(out + written, self->buffer + self->pos, remaining);
1657 written += remaining;
1658 self->pos += remaining;
1659 remaining = 0;
1660 }
1661 if (remaining == 0)
1662 break;
1663 }
1664
1665 return res;
1666
1667error:
1668 Py_XDECREF(res);
1669 return NULL;
1670}
1671
1672static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001673_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001674{
1675 Py_ssize_t have, r;
1676
1677 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1678 /* Constraints:
1679 1. we don't want to advance the file position.
1680 2. we don't want to lose block alignment, so we can't shift the buffer
1681 to make some place.
1682 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1683 */
1684 if (have > 0) {
1685 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1686 }
1687
1688 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001689 _bufferedreader_reset_buf(self);
1690 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001691 if (r == -1)
1692 return NULL;
1693 if (r == -2)
1694 r = 0;
1695 self->pos = 0;
1696 return PyBytes_FromStringAndSize(self->buffer, r);
1697}
1698
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001699static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001701 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1702 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1703 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1704 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1705 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1706 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1707 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1708 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001709 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001710 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001711
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001712 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1713 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1714 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001715 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001716 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1717 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1718 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1719 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001720 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001721 {NULL, NULL}
1722};
1723
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001724static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001725 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001726 {NULL}
1727};
1728
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001729static PyGetSetDef bufferedreader_getset[] = {
1730 {"closed", (getter)buffered_closed_get, NULL, NULL},
1731 {"name", (getter)buffered_name_get, NULL, NULL},
1732 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001733 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001734};
1735
1736
1737PyTypeObject PyBufferedReader_Type = {
1738 PyVarObject_HEAD_INIT(NULL, 0)
1739 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001740 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001741 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001742 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743 0, /*tp_print*/
1744 0, /*tp_getattr*/
1745 0, /*tp_setattr*/
1746 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001747 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001748 0, /*tp_as_number*/
1749 0, /*tp_as_sequence*/
1750 0, /*tp_as_mapping*/
1751 0, /*tp_hash */
1752 0, /*tp_call*/
1753 0, /*tp_str*/
1754 0, /*tp_getattro*/
1755 0, /*tp_setattro*/
1756 0, /*tp_as_buffer*/
1757 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1758 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001759 bufferedreader_doc, /* tp_doc */
1760 (traverseproc)buffered_traverse, /* tp_traverse */
1761 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001763 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001765 (iternextfunc)buffered_iternext, /* tp_iternext */
1766 bufferedreader_methods, /* tp_methods */
1767 bufferedreader_members, /* tp_members */
1768 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769 0, /* tp_base */
1770 0, /* tp_dict */
1771 0, /* tp_descr_get */
1772 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001773 offsetof(buffered, dict), /* tp_dictoffset */
1774 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775 0, /* tp_alloc */
1776 PyType_GenericNew, /* tp_new */
1777};
1778
1779
Benjamin Peterson59406a92009-03-26 17:10:29 +00001780
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781/*
1782 * class BufferedWriter
1783 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 "A buffer for a writeable sequential RawIO object.\n"
1786 "\n"
1787 "The constructor creates a BufferedWriter for the given writeable raw\n"
1788 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001789 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 );
1791
1792static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001793_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794{
1795 self->write_pos = 0;
1796 self->write_end = -1;
1797}
1798
1799static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801{
Florent Xicluna109d5732012-07-07 17:03:22 +02001802 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001803 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 PyObject *raw;
1805
1806 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001807 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001808
Florent Xicluna109d5732012-07-07 17:03:22 +02001809 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1810 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 return -1;
1812 }
1813
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001814 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 return -1;
1816
1817 Py_CLEAR(self->raw);
1818 Py_INCREF(raw);
1819 self->raw = raw;
1820 self->readable = 0;
1821 self->writable = 1;
1822
1823 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001826 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 self->pos = 0;
1828
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001829 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1830 Py_TYPE(raw) == &PyFileIO_Type);
1831
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832 self->ok = 1;
1833 return 0;
1834}
1835
1836static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001837_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838{
1839 Py_buffer buf;
1840 PyObject *memobj, *res;
1841 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001842 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001843 /* NOTE: the buffer needn't be released as its object is NULL. */
1844 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1845 return -1;
1846 memobj = PyMemoryView_FromBuffer(&buf);
1847 if (memobj == NULL)
1848 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001849 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1850 occurs so we needn't do it ourselves.
1851 We then retry writing, ignoring the signal if no handler has
1852 raised (see issue #10956).
1853 */
1854 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001855 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001856 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001857 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001858 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859 Py_DECREF(memobj);
1860 if (res == NULL)
1861 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001862 if (res == Py_None) {
1863 /* Non-blocking stream would have blocked. Special return code!
1864 Being paranoid we reset errno in case it is changed by code
1865 triggered by a decref. errno is used by _set_BlockingIOError(). */
1866 Py_DECREF(res);
1867 errno = errnum;
1868 return -2;
1869 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001870 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1871 Py_DECREF(res);
1872 if (n < 0 || n > len) {
1873 PyErr_Format(PyExc_IOError,
1874 "raw write() returned invalid length %zd "
1875 "(should have been between 0 and %zd)", n, len);
1876 return -1;
1877 }
1878 if (n > 0 && self->abs_pos != -1)
1879 self->abs_pos += n;
1880 return n;
1881}
1882
1883/* `restore_pos` is 1 if we need to restore the raw stream position at
1884 the end, 0 otherwise. */
1885static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001886_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001887{
1888 Py_ssize_t written = 0;
1889 Py_off_t n, rewind;
1890
1891 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1892 goto end;
1893 /* First, rewind */
1894 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1895 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001896 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001897 if (n < 0) {
1898 goto error;
1899 }
1900 self->raw_pos -= rewind;
1901 }
1902 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001903 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001904 self->buffer + self->write_pos,
1905 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1906 Py_off_t, Py_ssize_t));
1907 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001908 goto error;
1909 }
1910 else if (n == -2) {
1911 _set_BlockingIOError("write could not complete without blocking",
1912 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913 goto error;
1914 }
1915 self->write_pos += n;
1916 self->raw_pos = self->write_pos;
1917 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001918 /* Partial writes can return successfully when interrupted by a
1919 signal (see write(2)). We must run signal handlers before
1920 blocking another time, possibly indefinitely. */
1921 if (PyErr_CheckSignals() < 0)
1922 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923 }
1924
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001925 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926
1927end:
1928 Py_RETURN_NONE;
1929
1930error:
1931 return NULL;
1932}
1933
1934static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001935bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936{
1937 PyObject *res = NULL;
1938 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001939 Py_ssize_t written, avail, remaining;
1940 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941
1942 CHECK_INITIALIZED(self)
1943 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1944 return NULL;
1945 }
1946
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001947 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 PyErr_SetString(PyExc_ValueError, "write to closed file");
1949 PyBuffer_Release(&buf);
1950 return NULL;
1951 }
1952
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001953 if (!ENTER_BUFFERED(self)) {
1954 PyBuffer_Release(&buf);
1955 return NULL;
1956 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957
1958 /* Fast path: the data to write can be fully buffered. */
1959 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1960 self->pos = 0;
1961 self->raw_pos = 0;
1962 }
1963 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1964 if (buf.len <= avail) {
1965 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001966 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 self->write_pos = self->pos;
1968 }
1969 ADJUST_POSITION(self, self->pos + buf.len);
1970 if (self->pos > self->write_end)
1971 self->write_end = self->pos;
1972 written = buf.len;
1973 goto end;
1974 }
1975
1976 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001977 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001979 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001980 if (w == NULL)
1981 goto error;
1982 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001983 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001984 /* Make some place by shifting the buffer. */
1985 assert(VALID_WRITE_BUFFER(self));
1986 memmove(self->buffer, self->buffer + self->write_pos,
1987 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1988 Py_off_t, Py_ssize_t));
1989 self->write_end -= self->write_pos;
1990 self->raw_pos -= self->write_pos;
1991 self->pos -= self->write_pos;
1992 self->write_pos = 0;
1993 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1994 Py_off_t, Py_ssize_t);
1995 if (buf.len <= avail) {
1996 /* Everything can be buffered */
1997 PyErr_Clear();
1998 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1999 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002000 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 written = buf.len;
2002 goto end;
2003 }
2004 /* Buffer as much as possible. */
2005 memcpy(self->buffer + self->write_end, buf.buf, avail);
2006 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002007 self->pos += avail;
2008 /* XXX Modifying the existing exception e using the pointer w
2009 will change e.characters_written but not e.args[2].
2010 Therefore we just replace with a new error. */
2011 _set_BlockingIOError("write could not complete without blocking",
2012 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002013 goto error;
2014 }
2015 Py_CLEAR(res);
2016
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002017 /* Adjust the raw stream position if it is away from the logical stream
2018 position. This happens if the read buffer has been filled but not
2019 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2020 the raw stream by itself).
2021 Fixes issue #6629.
2022 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002023 offset = RAW_OFFSET(self);
2024 if (offset != 0) {
2025 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002026 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002027 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002028 }
2029
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 /* Then write buf itself. At this point the buffer has been emptied. */
2031 remaining = buf.len;
2032 written = 0;
2033 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002034 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035 self, (char *) buf.buf + written, buf.len - written);
2036 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002037 goto error;
2038 } else if (n == -2) {
2039 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002040 if (remaining > self->buffer_size) {
2041 /* Can't buffer everything, still buffer as much as possible */
2042 memcpy(self->buffer,
2043 (char *) buf.buf + written, self->buffer_size);
2044 self->raw_pos = 0;
2045 ADJUST_POSITION(self, self->buffer_size);
2046 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002047 written += self->buffer_size;
2048 _set_BlockingIOError("write could not complete without "
2049 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002050 goto error;
2051 }
2052 PyErr_Clear();
2053 break;
2054 }
2055 written += n;
2056 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002057 /* Partial writes can return successfully when interrupted by a
2058 signal (see write(2)). We must run signal handlers before
2059 blocking another time, possibly indefinitely. */
2060 if (PyErr_CheckSignals() < 0)
2061 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002062 }
2063 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002064 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002065 if (remaining > 0) {
2066 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2067 written += remaining;
2068 }
2069 self->write_pos = 0;
2070 /* TODO: sanity check (remaining >= 0) */
2071 self->write_end = remaining;
2072 ADJUST_POSITION(self, remaining);
2073 self->raw_pos = 0;
2074
2075end:
2076 res = PyLong_FromSsize_t(written);
2077
2078error:
2079 LEAVE_BUFFERED(self)
2080 PyBuffer_Release(&buf);
2081 return res;
2082}
2083
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002084static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002085 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002086 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2087 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2088 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2089 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2090 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2091 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2092 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002093 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002094 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002096 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2097 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2098 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2099 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2100 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002101 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002102 {NULL, NULL}
2103};
2104
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002106 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107 {NULL}
2108};
2109
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110static PyGetSetDef bufferedwriter_getset[] = {
2111 {"closed", (getter)buffered_closed_get, NULL, NULL},
2112 {"name", (getter)buffered_name_get, NULL, NULL},
2113 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002114 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002115};
2116
2117
2118PyTypeObject PyBufferedWriter_Type = {
2119 PyVarObject_HEAD_INIT(NULL, 0)
2120 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002122 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124 0, /*tp_print*/
2125 0, /*tp_getattr*/
2126 0, /*tp_setattr*/
2127 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002128 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002129 0, /*tp_as_number*/
2130 0, /*tp_as_sequence*/
2131 0, /*tp_as_mapping*/
2132 0, /*tp_hash */
2133 0, /*tp_call*/
2134 0, /*tp_str*/
2135 0, /*tp_getattro*/
2136 0, /*tp_setattro*/
2137 0, /*tp_as_buffer*/
2138 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2139 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002140 bufferedwriter_doc, /* tp_doc */
2141 (traverseproc)buffered_traverse, /* tp_traverse */
2142 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002144 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145 0, /* tp_iter */
2146 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147 bufferedwriter_methods, /* tp_methods */
2148 bufferedwriter_members, /* tp_members */
2149 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150 0, /* tp_base */
2151 0, /* tp_dict */
2152 0, /* tp_descr_get */
2153 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002154 offsetof(buffered, dict), /* tp_dictoffset */
2155 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 0, /* tp_alloc */
2157 PyType_GenericNew, /* tp_new */
2158};
2159
2160
2161
2162/*
2163 * BufferedRWPair
2164 */
2165
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002166PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167 "A buffered reader and writer object together.\n"
2168 "\n"
2169 "A buffered reader object and buffered writer object put together to\n"
2170 "form a sequential IO object that can read and write. This is typically\n"
2171 "used with a socket or two-way pipe.\n"
2172 "\n"
2173 "reader and writer are RawIOBase objects that are readable and\n"
2174 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002175 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002176 );
2177
2178/* XXX The usefulness of this (compared to having two separate IO objects) is
2179 * questionable.
2180 */
2181
2182typedef struct {
2183 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184 buffered *reader;
2185 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186 PyObject *dict;
2187 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002188} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189
2190static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002191bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192{
2193 PyObject *reader, *writer;
2194 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195
Florent Xicluna109d5732012-07-07 17:03:22 +02002196 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2197 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002198 return -1;
2199 }
2200
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002201 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002203 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002204 return -1;
2205
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002206 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002207 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208 if (self->reader == NULL)
2209 return -1;
2210
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002211 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002212 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213 if (self->writer == NULL) {
2214 Py_CLEAR(self->reader);
2215 return -1;
2216 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002217
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218 return 0;
2219}
2220
2221static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
2224 Py_VISIT(self->dict);
2225 return 0;
2226}
2227
2228static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002229bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230{
2231 Py_CLEAR(self->reader);
2232 Py_CLEAR(self->writer);
2233 Py_CLEAR(self->dict);
2234 return 0;
2235}
2236
2237static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002238bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239{
2240 _PyObject_GC_UNTRACK(self);
2241 Py_CLEAR(self->reader);
2242 Py_CLEAR(self->writer);
2243 Py_CLEAR(self->dict);
2244 Py_TYPE(self)->tp_free((PyObject *) self);
2245}
2246
2247static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002248_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002250 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251 PyObject *ret;
2252
2253 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002254 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255 return NULL;
2256 }
2257
2258 ret = PyObject_CallObject(func, args);
2259 Py_DECREF(func);
2260 return ret;
2261}
2262
2263static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002264bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002266 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267}
2268
2269static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002270bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002272 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273}
2274
2275static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002276bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002278 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002279}
2280
2281static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002282bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002283{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002284 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002285}
2286
2287static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002288bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002290 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291}
2292
2293static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002294bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002295{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002296 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297}
2298
2299static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002300bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002301{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002302 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303}
2304
2305static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002306bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002308 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002309}
2310
2311static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002312bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002314 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002315 if (ret == NULL)
2316 return NULL;
2317 Py_DECREF(ret);
2318
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002319 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002320}
2321
2322static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002323bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002324{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002325 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002326
2327 if (ret != Py_False) {
2328 /* either True or exception */
2329 return ret;
2330 }
2331 Py_DECREF(ret);
2332
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002333 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334}
2335
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002336static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002337bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002338{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002339 if (self->writer == NULL) {
2340 PyErr_SetString(PyExc_RuntimeError,
2341 "the BufferedRWPair object is being garbage-collected");
2342 return NULL;
2343 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002344 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2345}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002346
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002347static PyMethodDef bufferedrwpair_methods[] = {
2348 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2349 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2350 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2351 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002352
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002353 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2354 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002356 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2357 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002358
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002359 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2360 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361
Antoine Pitrou243757e2010-11-05 21:15:39 +00002362 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2363
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002364 {NULL, NULL}
2365};
2366
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002367static PyGetSetDef bufferedrwpair_getset[] = {
2368 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002369 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002370};
2371
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002372PyTypeObject PyBufferedRWPair_Type = {
2373 PyVarObject_HEAD_INIT(NULL, 0)
2374 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002375 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002376 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002377 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002378 0, /*tp_print*/
2379 0, /*tp_getattr*/
2380 0, /*tp_setattr*/
2381 0, /*tp_compare */
2382 0, /*tp_repr*/
2383 0, /*tp_as_number*/
2384 0, /*tp_as_sequence*/
2385 0, /*tp_as_mapping*/
2386 0, /*tp_hash */
2387 0, /*tp_call*/
2388 0, /*tp_str*/
2389 0, /*tp_getattro*/
2390 0, /*tp_setattro*/
2391 0, /*tp_as_buffer*/
2392 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2393 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002394 bufferedrwpair_doc, /* tp_doc */
2395 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2396 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002397 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002398 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002399 0, /* tp_iter */
2400 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002401 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002402 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002403 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002404 0, /* tp_base */
2405 0, /* tp_dict */
2406 0, /* tp_descr_get */
2407 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002408 offsetof(rwpair, dict), /* tp_dictoffset */
2409 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002410 0, /* tp_alloc */
2411 PyType_GenericNew, /* tp_new */
2412};
2413
2414
2415
2416/*
2417 * BufferedRandom
2418 */
2419
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002420PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421 "A buffered interface to random access streams.\n"
2422 "\n"
2423 "The constructor creates a reader and writer for a seekable stream,\n"
2424 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002425 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426 );
2427
2428static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430{
Florent Xicluna109d5732012-07-07 17:03:22 +02002431 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002433 PyObject *raw;
2434
2435 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002436 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002437
Florent Xicluna109d5732012-07-07 17:03:22 +02002438 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
2439 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002440 return -1;
2441 }
2442
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002443 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002444 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002445 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002446 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002447 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002448 return -1;
2449
2450 Py_CLEAR(self->raw);
2451 Py_INCREF(raw);
2452 self->raw = raw;
2453 self->buffer_size = buffer_size;
2454 self->readable = 1;
2455 self->writable = 1;
2456
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002457 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 _bufferedreader_reset_buf(self);
2460 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461 self->pos = 0;
2462
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002463 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2464 Py_TYPE(raw) == &PyFileIO_Type);
2465
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466 self->ok = 1;
2467 return 0;
2468}
2469
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002470static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002471 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002472 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2473 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2474 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2475 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2476 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2477 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2478 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002479 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002480 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002481
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002482 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002483
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002484 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2485 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2486 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2487 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2488 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2489 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2490 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2491 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2492 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002493 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494 {NULL, NULL}
2495};
2496
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002497static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002498 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002499 {NULL}
2500};
2501
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002502static PyGetSetDef bufferedrandom_getset[] = {
2503 {"closed", (getter)buffered_closed_get, NULL, NULL},
2504 {"name", (getter)buffered_name_get, NULL, NULL},
2505 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002506 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507};
2508
2509
2510PyTypeObject PyBufferedRandom_Type = {
2511 PyVarObject_HEAD_INIT(NULL, 0)
2512 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002513 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002514 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002515 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002516 0, /*tp_print*/
2517 0, /*tp_getattr*/
2518 0, /*tp_setattr*/
2519 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002520 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002521 0, /*tp_as_number*/
2522 0, /*tp_as_sequence*/
2523 0, /*tp_as_mapping*/
2524 0, /*tp_hash */
2525 0, /*tp_call*/
2526 0, /*tp_str*/
2527 0, /*tp_getattro*/
2528 0, /*tp_setattro*/
2529 0, /*tp_as_buffer*/
2530 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2531 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002532 bufferedrandom_doc, /* tp_doc */
2533 (traverseproc)buffered_traverse, /* tp_traverse */
2534 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002538 (iternextfunc)buffered_iternext, /* tp_iternext */
2539 bufferedrandom_methods, /* tp_methods */
2540 bufferedrandom_members, /* tp_members */
2541 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002542 0, /* tp_base */
2543 0, /*tp_dict*/
2544 0, /* tp_descr_get */
2545 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002546 offsetof(buffered, dict), /*tp_dictoffset*/
2547 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002548 0, /* tp_alloc */
2549 PyType_GenericNew, /* tp_new */
2550};