blob: 334734beccbae8d3d4271eaeb973c46460a620cd [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
522end:
523 LEAVE_BUFFERED(self)
524 return res;
525}
526
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000527/* detach */
528
529static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000530buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000531{
532 PyObject *raw, *res;
533 CHECK_INITIALIZED(self)
534 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
535 if (res == NULL)
536 return NULL;
537 Py_DECREF(res);
538 raw = self->raw;
539 self->raw = NULL;
540 self->detached = 1;
541 self->ok = 0;
542 return raw;
543}
544
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000545/* Inquiries */
546
547static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000548buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000549{
550 CHECK_INITIALIZED(self)
551 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
552}
553
554static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000555buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000556{
557 CHECK_INITIALIZED(self)
558 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
559}
560
561static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000562buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000563{
564 CHECK_INITIALIZED(self)
565 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
566}
567
568static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000569buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570{
571 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200572 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573}
574
575static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000576buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000577{
578 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200579 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580}
581
582/* Lower-level APIs */
583
584static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000585buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586{
587 CHECK_INITIALIZED(self)
588 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
589}
590
591static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000592buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593{
594 CHECK_INITIALIZED(self)
595 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
596}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000597
Antoine Pitrou243757e2010-11-05 21:15:39 +0000598/* Serialization */
599
600static PyObject *
601buffered_getstate(buffered *self, PyObject *args)
602{
603 PyErr_Format(PyExc_TypeError,
604 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
605 return NULL;
606}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000607
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608/* Forward decls */
609static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100610_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000612_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000613static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000616_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200618_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000621static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000622_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000623static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000624_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200625static Py_ssize_t
626_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627
628/*
629 * Helpers
630 */
631
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100632/* Sets the current error to BlockingIOError */
633static void
634_set_BlockingIOError(char *msg, Py_ssize_t written)
635{
636 PyObject *err;
637 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
638 errno, msg, written);
639 if (err)
640 PyErr_SetObject(PyExc_BlockingIOError, err);
641 Py_XDECREF(err);
642}
643
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644/* Returns the address of the `written` member if a BlockingIOError was
645 raised, NULL otherwise. The error is always re-raised. */
646static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000647_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648{
649 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200650 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651
652 PyErr_Fetch(&t, &v, &tb);
653 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
654 PyErr_Restore(t, v, tb);
655 return NULL;
656 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200657 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658 /* TODO: sanity check (err->written >= 0) */
659 PyErr_Restore(t, v, tb);
660 return &err->written;
661}
662
663static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000664_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000666 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000667 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
669 if (res == NULL)
670 return -1;
671 n = PyNumber_AsOff_t(res, PyExc_ValueError);
672 Py_DECREF(res);
673 if (n < 0) {
674 if (!PyErr_Occurred())
675 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000676 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200677 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678 return -1;
679 }
680 self->abs_pos = n;
681 return n;
682}
683
684static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000685_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000686{
687 PyObject *res, *posobj, *whenceobj;
688 Py_off_t n;
689
690 posobj = PyLong_FromOff_t(target);
691 if (posobj == NULL)
692 return -1;
693 whenceobj = PyLong_FromLong(whence);
694 if (whenceobj == NULL) {
695 Py_DECREF(posobj);
696 return -1;
697 }
698 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
699 posobj, whenceobj, NULL);
700 Py_DECREF(posobj);
701 Py_DECREF(whenceobj);
702 if (res == NULL)
703 return -1;
704 n = PyNumber_AsOff_t(res, PyExc_ValueError);
705 Py_DECREF(res);
706 if (n < 0) {
707 if (!PyErr_Occurred())
708 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000709 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200710 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711 return -1;
712 }
713 self->abs_pos = n;
714 return n;
715}
716
717static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000718_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000719{
720 Py_ssize_t n;
721 if (self->buffer_size <= 0) {
722 PyErr_SetString(PyExc_ValueError,
723 "buffer size must be strictly positive");
724 return -1;
725 }
726 if (self->buffer)
727 PyMem_Free(self->buffer);
728 self->buffer = PyMem_Malloc(self->buffer_size);
729 if (self->buffer == NULL) {
730 PyErr_NoMemory();
731 return -1;
732 }
Georg Brandldfd73442009-04-05 11:47:34 +0000733#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000734 if (self->lock)
735 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000736 self->lock = PyThread_allocate_lock();
737 if (self->lock == NULL) {
738 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
739 return -1;
740 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000741 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000742#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000743 /* Find out whether buffer_size is a power of 2 */
744 /* XXX is this optimization useful? */
745 for (n = self->buffer_size - 1; n & 1; n >>= 1)
746 ;
747 if (n == 0)
748 self->buffer_mask = self->buffer_size - 1;
749 else
750 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000751 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000752 PyErr_Clear();
753 return 0;
754}
755
Antoine Pitrou707ce822011-02-25 21:24:11 +0000756/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
757 clears the error indicator), 0 otherwise.
758 Should only be called when PyErr_Occurred() is true.
759*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700760int
761_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000762{
763 static PyObject *eintr_int = NULL;
764 PyObject *typ, *val, *tb;
765 PyEnvironmentErrorObject *env_err;
766
767 if (eintr_int == NULL) {
768 eintr_int = PyLong_FromLong(EINTR);
769 assert(eintr_int != NULL);
770 }
771 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
772 return 0;
773 PyErr_Fetch(&typ, &val, &tb);
774 PyErr_NormalizeException(&typ, &val, &tb);
775 env_err = (PyEnvironmentErrorObject *) val;
776 assert(env_err != NULL);
777 if (env_err->myerrno != NULL &&
778 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
779 Py_DECREF(typ);
780 Py_DECREF(val);
781 Py_XDECREF(tb);
782 return 1;
783 }
784 /* This silences any error set by PyObject_RichCompareBool() */
785 PyErr_Restore(typ, val, tb);
786 return 0;
787}
788
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000789/*
790 * Shared methods and wrappers
791 */
792
793static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200794buffered_flush_and_rewind_unlocked(buffered *self)
795{
796 PyObject *res;
797
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100798 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200799 if (res == NULL)
800 return NULL;
801 Py_DECREF(res);
802
803 if (self->readable) {
804 /* Rewind the raw stream so that its position corresponds to
805 the current logical position. */
806 Py_off_t n;
807 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
808 _bufferedreader_reset_buf(self);
809 if (n == -1)
810 return NULL;
811 }
812 Py_RETURN_NONE;
813}
814
815static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000816buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000817{
818 PyObject *res;
819
820 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000821 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000823 if (!ENTER_BUFFERED(self))
824 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200825 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000826 LEAVE_BUFFERED(self)
827
828 return res;
829}
830
831static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000832buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833{
834 Py_ssize_t n = 0;
835 PyObject *res = NULL;
836
837 CHECK_INITIALIZED(self)
838 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
839 return NULL;
840 }
841
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000842 if (!ENTER_BUFFERED(self))
843 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000844
845 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200846 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000847 if (res == NULL)
848 goto end;
849 Py_CLEAR(res);
850 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200851 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852
853end:
854 LEAVE_BUFFERED(self)
855 return res;
856}
857
858static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000859buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860{
861 Py_ssize_t n = -1;
862 PyObject *res;
863
864 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000865 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866 return NULL;
867 }
868 if (n < -1) {
869 PyErr_SetString(PyExc_ValueError,
870 "read length must be positive or -1");
871 return NULL;
872 }
873
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000874 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000876 if (n == -1) {
877 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000878 if (!ENTER_BUFFERED(self))
879 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000880 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000881 }
882 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000883 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200884 if (res != Py_None)
885 return res;
886 Py_DECREF(res);
887 if (!ENTER_BUFFERED(self))
888 return NULL;
889 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000890 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000891
Antoine Pitroue05565e2011-08-20 14:39:23 +0200892 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000893 return res;
894}
895
896static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000897buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000898{
899 Py_ssize_t n, have, r;
900 PyObject *res = NULL;
901
902 CHECK_INITIALIZED(self)
903 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
904 return NULL;
905 }
906
907 if (n < 0) {
908 PyErr_SetString(PyExc_ValueError,
909 "read length must be positive");
910 return NULL;
911 }
912 if (n == 0)
913 return PyBytes_FromStringAndSize(NULL, 0);
914
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915 /* Return up to n bytes. If at least one byte is buffered, we
916 only return buffered bytes. Otherwise, we do one raw read. */
917
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000918 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
919 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100920 n = Py_MIN(have, n);
921 res = _bufferedreader_read_fast(self, n);
922 assert(res != Py_None);
923 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100925 res = PyBytes_FromStringAndSize(NULL, n);
926 if (res == NULL)
927 return NULL;
928 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200929 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100930 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200931 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000932 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100933 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
934 LEAVE_BUFFERED(self)
935 if (r == -1) {
936 Py_DECREF(res);
937 return NULL;
938 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 if (r == -2)
940 r = 0;
941 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100942 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943 return res;
944}
945
946static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000947buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200949 Py_buffer buf;
950 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000951 PyObject *res = NULL;
952
953 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200954
955 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
956 return NULL;
957
958 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
959 if (n > 0) {
960 if (n >= buf.len) {
961 memcpy(buf.buf, self->buffer + self->pos, buf.len);
962 self->pos += buf.len;
963 res = PyLong_FromSsize_t(buf.len);
964 goto end_unlocked;
965 }
966 memcpy(buf.buf, self->buffer + self->pos, n);
967 self->pos += n;
968 written = n;
969 }
970
971 if (!ENTER_BUFFERED(self))
972 goto end_unlocked;
973
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000974 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200975 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000976 if (res == NULL)
977 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200978 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000979 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200980
981 _bufferedreader_reset_buf(self);
982 self->pos = 0;
983
984 for (remaining = buf.len - written;
985 remaining > 0;
986 written += n, remaining -= n) {
987 /* If remaining bytes is larger than internal buffer size, copy
988 * directly into caller's buffer. */
989 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200990 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
991 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200992 }
993 else {
994 n = _bufferedreader_fill_buffer(self);
995 if (n > 0) {
996 if (n > remaining)
997 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200998 memcpy((char *) buf.buf + written,
999 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001000 self->pos += n;
1001 continue; /* short circuit */
1002 }
1003 }
1004 if (n == 0 || (n == -2 && written > 0))
1005 break;
1006 if (n < 0) {
1007 if (n == -2) {
1008 Py_INCREF(Py_None);
1009 res = Py_None;
1010 }
1011 goto end;
1012 }
1013 }
1014 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001015
1016end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001017 LEAVE_BUFFERED(self);
1018end_unlocked:
1019 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001020 return res;
1021}
1022
1023static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001024_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001025{
1026 PyObject *res = NULL;
1027 PyObject *chunks = NULL;
1028 Py_ssize_t n, written = 0;
1029 const char *start, *s, *end;
1030
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001031 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001032
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001033 /* First, try to find a line in the buffer. This can run unlocked because
1034 the calls to the C API are simple enough that they can't trigger
1035 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001036 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1037 if (limit >= 0 && n > limit)
1038 n = limit;
1039 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001040 s = memchr(start, '\n', n);
1041 if (s != NULL) {
1042 res = PyBytes_FromStringAndSize(start, s - start + 1);
1043 if (res != NULL)
1044 self->pos += s - start + 1;
1045 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046 }
1047 if (n == limit) {
1048 res = PyBytes_FromStringAndSize(start, n);
1049 if (res != NULL)
1050 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001051 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001052 }
1053
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001054 if (!ENTER_BUFFERED(self))
1055 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001056
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001057 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058 chunks = PyList_New(0);
1059 if (chunks == NULL)
1060 goto end;
1061 if (n > 0) {
1062 res = PyBytes_FromStringAndSize(start, n);
1063 if (res == NULL)
1064 goto end;
1065 if (PyList_Append(chunks, res) < 0) {
1066 Py_CLEAR(res);
1067 goto end;
1068 }
1069 Py_CLEAR(res);
1070 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001071 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001072 if (limit >= 0)
1073 limit -= n;
1074 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001075 if (self->writable) {
1076 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1077 if (r == NULL)
1078 goto end;
1079 Py_DECREF(r);
1080 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081
1082 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001083 _bufferedreader_reset_buf(self);
1084 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001085 if (n == -1)
1086 goto end;
1087 if (n <= 0)
1088 break;
1089 if (limit >= 0 && n > limit)
1090 n = limit;
1091 start = self->buffer;
1092 end = start + n;
1093 s = start;
1094 while (s < end) {
1095 if (*s++ == '\n') {
1096 res = PyBytes_FromStringAndSize(start, s - start);
1097 if (res == NULL)
1098 goto end;
1099 self->pos = s - start;
1100 goto found;
1101 }
1102 }
1103 res = PyBytes_FromStringAndSize(start, n);
1104 if (res == NULL)
1105 goto end;
1106 if (n == limit) {
1107 self->pos = n;
1108 break;
1109 }
1110 if (PyList_Append(chunks, res) < 0) {
1111 Py_CLEAR(res);
1112 goto end;
1113 }
1114 Py_CLEAR(res);
1115 written += n;
1116 if (limit >= 0)
1117 limit -= n;
1118 }
1119found:
1120 if (res != NULL && PyList_Append(chunks, res) < 0) {
1121 Py_CLEAR(res);
1122 goto end;
1123 }
1124 Py_CLEAR(res);
1125 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1126
1127end:
1128 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001129end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001130 Py_XDECREF(chunks);
1131 return res;
1132}
1133
1134static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001135buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001136{
1137 Py_ssize_t limit = -1;
1138
1139 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001140 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001141 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001142 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001143}
1144
1145
1146static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001147buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001148{
1149 Py_off_t pos;
1150
1151 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001152 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001153 if (pos == -1)
1154 return NULL;
1155 pos -= RAW_OFFSET(self);
1156 /* TODO: sanity check (pos >= 0) */
1157 return PyLong_FromOff_t(pos);
1158}
1159
1160static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001161buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001162{
1163 Py_off_t target, n;
1164 int whence = 0;
1165 PyObject *targetobj, *res = NULL;
1166
1167 CHECK_INITIALIZED(self)
1168 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1169 return NULL;
1170 }
Jesus Cea94363612012-06-22 18:32:07 +02001171
1172 /* Do some error checking instead of trusting OS 'seek()'
1173 ** error detection, just in case.
1174 */
1175 if ((whence < 0 || whence >2)
1176#ifdef SEEK_HOLE
1177 && (whence != SEEK_HOLE)
1178#endif
1179#ifdef SEEK_DATA
1180 && (whence != SEEK_DATA)
1181#endif
1182 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001184 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185 return NULL;
1186 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001187
1188 CHECK_CLOSED(self, "seek of closed file")
1189
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001190 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1191 return NULL;
1192
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001193 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1194 if (target == -1 && PyErr_Occurred())
1195 return NULL;
1196
Jesus Cea94363612012-06-22 18:32:07 +02001197 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1198 buffer. Other whence values must be managed without this optimization.
1199 Some Operating Systems can provide additional values, like
1200 SEEK_HOLE/SEEK_DATA. */
1201 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202 Py_off_t current, avail;
1203 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001204 so as to return quickly if possible. Also, we needn't take the
1205 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001207 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1208 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209 current = RAW_TELL(self);
1210 avail = READAHEAD(self);
1211 if (avail > 0) {
1212 Py_off_t offset;
1213 if (whence == 0)
1214 offset = target - (current - RAW_OFFSET(self));
1215 else
1216 offset = target;
1217 if (offset >= -self->pos && offset <= avail) {
1218 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001219 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220 }
1221 }
1222 }
1223
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001224 if (!ENTER_BUFFERED(self))
1225 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001226
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227 /* Fallback: invoke raw seek() method and clear buffer */
1228 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001229 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 if (res == NULL)
1231 goto end;
1232 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001233 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001234 }
1235
1236 /* TODO: align on block boundary and read buffer if needed? */
1237 if (whence == 1)
1238 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001239 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001240 if (n == -1)
1241 goto end;
1242 self->raw_pos = -1;
1243 res = PyLong_FromOff_t(n);
1244 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001245 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246
1247end:
1248 LEAVE_BUFFERED(self)
1249 return res;
1250}
1251
1252static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001253buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254{
1255 PyObject *pos = Py_None;
1256 PyObject *res = NULL;
1257
1258 CHECK_INITIALIZED(self)
1259 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1260 return NULL;
1261 }
1262
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001263 if (!ENTER_BUFFERED(self))
1264 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265
1266 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001267 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001268 if (res == NULL)
1269 goto end;
1270 Py_CLEAR(res);
1271 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001272 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1273 if (res == NULL)
1274 goto end;
1275 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001276 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001277 PyErr_Clear();
1278
1279end:
1280 LEAVE_BUFFERED(self)
1281 return res;
1282}
1283
1284static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001285buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286{
1287 PyObject *line;
1288 PyTypeObject *tp;
1289
1290 CHECK_INITIALIZED(self);
1291
1292 tp = Py_TYPE(self);
1293 if (tp == &PyBufferedReader_Type ||
1294 tp == &PyBufferedRandom_Type) {
1295 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001296 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001297 }
1298 else {
1299 line = PyObject_CallMethodObjArgs((PyObject *)self,
1300 _PyIO_str_readline, NULL);
1301 if (line && !PyBytes_Check(line)) {
1302 PyErr_Format(PyExc_IOError,
1303 "readline() should have returned a bytes object, "
1304 "not '%.200s'", Py_TYPE(line)->tp_name);
1305 Py_DECREF(line);
1306 return NULL;
1307 }
1308 }
1309
1310 if (line == NULL)
1311 return NULL;
1312
1313 if (PyBytes_GET_SIZE(line) == 0) {
1314 /* Reached EOF or would have blocked */
1315 Py_DECREF(line);
1316 return NULL;
1317 }
1318
1319 return line;
1320}
1321
Antoine Pitrou716c4442009-05-23 19:04:03 +00001322static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001323buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001324{
1325 PyObject *nameobj, *res;
1326
Martin v. Löwis767046a2011-10-14 15:35:36 +02001327 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001328 if (nameobj == NULL) {
1329 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1330 PyErr_Clear();
1331 else
1332 return NULL;
1333 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1334 }
1335 else {
1336 res = PyUnicode_FromFormat("<%s name=%R>",
1337 Py_TYPE(self)->tp_name, nameobj);
1338 Py_DECREF(nameobj);
1339 }
1340 return res;
1341}
1342
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343/*
1344 * class BufferedReader
1345 */
1346
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001347PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001348 "Create a new buffered reader using the given readable raw IO object.");
1349
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001350static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001351{
1352 self->read_end = -1;
1353}
1354
1355static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001356bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001357{
1358 char *kwlist[] = {"raw", "buffer_size", NULL};
1359 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1360 PyObject *raw;
1361
1362 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001363 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001364
1365 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1366 &raw, &buffer_size)) {
1367 return -1;
1368 }
1369
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001370 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001371 return -1;
1372
1373 Py_CLEAR(self->raw);
1374 Py_INCREF(raw);
1375 self->raw = raw;
1376 self->buffer_size = buffer_size;
1377 self->readable = 1;
1378 self->writable = 0;
1379
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001380 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001382 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001383
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001384 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1385 Py_TYPE(raw) == &PyFileIO_Type);
1386
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001387 self->ok = 1;
1388 return 0;
1389}
1390
1391static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001392_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393{
1394 Py_buffer buf;
1395 PyObject *memobj, *res;
1396 Py_ssize_t n;
1397 /* NOTE: the buffer needn't be released as its object is NULL. */
1398 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1399 return -1;
1400 memobj = PyMemoryView_FromBuffer(&buf);
1401 if (memobj == NULL)
1402 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001403 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1404 occurs so we needn't do it ourselves.
1405 We then retry reading, ignoring the signal if no handler has
1406 raised (see issue #10956).
1407 */
1408 do {
1409 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001410 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411 Py_DECREF(memobj);
1412 if (res == NULL)
1413 return -1;
1414 if (res == Py_None) {
1415 /* Non-blocking stream would have blocked. Special return code! */
1416 Py_DECREF(res);
1417 return -2;
1418 }
1419 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1420 Py_DECREF(res);
1421 if (n < 0 || n > len) {
1422 PyErr_Format(PyExc_IOError,
1423 "raw readinto() returned invalid length %zd "
1424 "(should have been between 0 and %zd)", n, len);
1425 return -1;
1426 }
1427 if (n > 0 && self->abs_pos != -1)
1428 self->abs_pos += n;
1429 return n;
1430}
1431
1432static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001433_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001434{
1435 Py_ssize_t start, len, n;
1436 if (VALID_READ_BUFFER(self))
1437 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1438 else
1439 start = 0;
1440 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001441 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001442 if (n <= 0)
1443 return n;
1444 self->read_end = start + n;
1445 self->raw_pos = start + n;
1446 return n;
1447}
1448
1449static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001450_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001451{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001452 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001453 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001454
1455 /* First copy what we have in the current buffer. */
1456 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1457 if (current_size) {
1458 data = PyBytes_FromStringAndSize(
1459 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001460 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001461 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001462 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001464 /* We're going past the buffer's bounds, flush it */
1465 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001466 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001467 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001468 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001469 Py_CLEAR(res);
1470 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001471 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001472
1473 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1474 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1475 if (chunk == NULL)
1476 return NULL;
1477 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1478 Py_XDECREF(data);
1479 Py_DECREF(chunk);
1480 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1481 return NULL;
1482 }
1483 if (chunk == Py_None) {
1484 if (current_size == 0)
1485 return chunk;
1486 else {
1487 Py_DECREF(chunk);
1488 return data;
1489 }
1490 }
1491 else if (current_size) {
1492 PyBytes_Concat(&data, chunk);
1493 Py_DECREF(chunk);
1494 if (data == NULL)
1495 return NULL;
1496 return data;
1497 } else
1498 return chunk;
1499 }
1500
1501 chunks = PyList_New(0);
Christian Heimes8f734eb2012-09-10 17:46:09 +02001502 if (chunks == NULL) {
1503 Py_XDECREF(data);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001504 return NULL;
Christian Heimes8f734eb2012-09-10 17:46:09 +02001505 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001506
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001507 while (1) {
1508 if (data) {
1509 if (PyList_Append(chunks, data) < 0) {
1510 Py_DECREF(data);
1511 Py_DECREF(chunks);
1512 return NULL;
1513 }
1514 Py_DECREF(data);
1515 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001516
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001517 /* Read until EOF or until read() would block. */
1518 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1519 if (data == NULL) {
1520 Py_DECREF(chunks);
1521 return NULL;
1522 }
1523 if (data != Py_None && !PyBytes_Check(data)) {
1524 Py_DECREF(data);
1525 Py_DECREF(chunks);
1526 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1527 return NULL;
1528 }
1529 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1530 if (current_size == 0) {
1531 Py_DECREF(chunks);
1532 return data;
1533 }
1534 else {
1535 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1536 Py_DECREF(data);
1537 Py_DECREF(chunks);
1538 return res;
1539 }
1540 }
1541 current_size += PyBytes_GET_SIZE(data);
1542 if (self->abs_pos != -1)
1543 self->abs_pos += PyBytes_GET_SIZE(data);
1544 }
1545}
1546
1547/* Read n bytes from the buffer if it can, otherwise return None.
1548 This function is simple enough that it can run unlocked. */
1549static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001550_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001551{
1552 Py_ssize_t current_size;
1553
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001554 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1555 if (n <= current_size) {
1556 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001557 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1558 if (res != NULL)
1559 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001560 return res;
1561 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001562 Py_RETURN_NONE;
1563}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001564
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001565/* Generic read function: read from the stream until enough bytes are read,
1566 * or until an EOF occurs or until read() would block.
1567 */
1568static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001569_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001570{
1571 PyObject *res = NULL;
1572 Py_ssize_t current_size, remaining, written;
1573 char *out;
1574
1575 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1576 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001577 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001579 res = PyBytes_FromStringAndSize(NULL, n);
1580 if (res == NULL)
1581 goto error;
1582 out = PyBytes_AS_STRING(res);
1583 remaining = n;
1584 written = 0;
1585 if (current_size > 0) {
1586 memcpy(out, self->buffer + self->pos, current_size);
1587 remaining -= current_size;
1588 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001589 self->pos += current_size;
1590 }
1591 /* Flush the write buffer if necessary */
1592 if (self->writable) {
1593 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1594 if (r == NULL)
1595 goto error;
1596 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001597 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001598 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001599 while (remaining > 0) {
1600 /* We want to read a whole block at the end into buffer.
1601 If we had readv() we could do this in one pass. */
1602 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1603 if (r == 0)
1604 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001605 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606 if (r == -1)
1607 goto error;
1608 if (r == 0 || r == -2) {
1609 /* EOF occurred or read() would block. */
1610 if (r == 0 || written > 0) {
1611 if (_PyBytes_Resize(&res, written))
1612 goto error;
1613 return res;
1614 }
1615 Py_DECREF(res);
1616 Py_INCREF(Py_None);
1617 return Py_None;
1618 }
1619 remaining -= r;
1620 written += r;
1621 }
1622 assert(remaining <= self->buffer_size);
1623 self->pos = 0;
1624 self->raw_pos = 0;
1625 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001626 /* NOTE: when the read is satisfied, we avoid issuing any additional
1627 reads, which could block indefinitely (e.g. on a socket).
1628 See issue #9550. */
1629 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001630 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001631 if (r == -1)
1632 goto error;
1633 if (r == 0 || r == -2) {
1634 /* EOF occurred or read() would block. */
1635 if (r == 0 || written > 0) {
1636 if (_PyBytes_Resize(&res, written))
1637 goto error;
1638 return res;
1639 }
1640 Py_DECREF(res);
1641 Py_INCREF(Py_None);
1642 return Py_None;
1643 }
1644 if (remaining > r) {
1645 memcpy(out + written, self->buffer + self->pos, r);
1646 written += r;
1647 self->pos += r;
1648 remaining -= r;
1649 }
1650 else if (remaining > 0) {
1651 memcpy(out + written, self->buffer + self->pos, remaining);
1652 written += remaining;
1653 self->pos += remaining;
1654 remaining = 0;
1655 }
1656 if (remaining == 0)
1657 break;
1658 }
1659
1660 return res;
1661
1662error:
1663 Py_XDECREF(res);
1664 return NULL;
1665}
1666
1667static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001668_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001669{
1670 Py_ssize_t have, r;
1671
1672 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1673 /* Constraints:
1674 1. we don't want to advance the file position.
1675 2. we don't want to lose block alignment, so we can't shift the buffer
1676 to make some place.
1677 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1678 */
1679 if (have > 0) {
1680 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1681 }
1682
1683 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001684 _bufferedreader_reset_buf(self);
1685 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001686 if (r == -1)
1687 return NULL;
1688 if (r == -2)
1689 r = 0;
1690 self->pos = 0;
1691 return PyBytes_FromStringAndSize(self->buffer, r);
1692}
1693
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001694static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001695 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001696 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1697 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1698 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1699 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1700 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1701 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1702 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1703 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001704 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001705 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001707 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1708 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1709 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001710 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001711 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1712 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1713 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1714 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001715 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001716 {NULL, NULL}
1717};
1718
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001719static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001720 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001721 {NULL}
1722};
1723
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001724static PyGetSetDef bufferedreader_getset[] = {
1725 {"closed", (getter)buffered_closed_get, NULL, NULL},
1726 {"name", (getter)buffered_name_get, NULL, NULL},
1727 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001728 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001729};
1730
1731
1732PyTypeObject PyBufferedReader_Type = {
1733 PyVarObject_HEAD_INIT(NULL, 0)
1734 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001736 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001737 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001738 0, /*tp_print*/
1739 0, /*tp_getattr*/
1740 0, /*tp_setattr*/
1741 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001742 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743 0, /*tp_as_number*/
1744 0, /*tp_as_sequence*/
1745 0, /*tp_as_mapping*/
1746 0, /*tp_hash */
1747 0, /*tp_call*/
1748 0, /*tp_str*/
1749 0, /*tp_getattro*/
1750 0, /*tp_setattro*/
1751 0, /*tp_as_buffer*/
1752 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1753 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001754 bufferedreader_doc, /* tp_doc */
1755 (traverseproc)buffered_traverse, /* tp_traverse */
1756 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001760 (iternextfunc)buffered_iternext, /* tp_iternext */
1761 bufferedreader_methods, /* tp_methods */
1762 bufferedreader_members, /* tp_members */
1763 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 0, /* tp_base */
1765 0, /* tp_dict */
1766 0, /* tp_descr_get */
1767 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001768 offsetof(buffered, dict), /* tp_dictoffset */
1769 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770 0, /* tp_alloc */
1771 PyType_GenericNew, /* tp_new */
1772};
1773
1774
Benjamin Peterson59406a92009-03-26 17:10:29 +00001775
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776/*
1777 * class BufferedWriter
1778 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001779PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 "A buffer for a writeable sequential RawIO object.\n"
1781 "\n"
1782 "The constructor creates a BufferedWriter for the given writeable raw\n"
1783 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001784 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 );
1786
1787static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001788_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789{
1790 self->write_pos = 0;
1791 self->write_end = -1;
1792}
1793
1794static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001795bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001796{
Florent Xicluna109d5732012-07-07 17:03:22 +02001797 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001798 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799 PyObject *raw;
1800
1801 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001802 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001803
Florent Xicluna109d5732012-07-07 17:03:22 +02001804 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1805 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 return -1;
1807 }
1808
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 return -1;
1811
1812 Py_CLEAR(self->raw);
1813 Py_INCREF(raw);
1814 self->raw = raw;
1815 self->readable = 0;
1816 self->writable = 1;
1817
1818 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001819 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001821 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822 self->pos = 0;
1823
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001824 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1825 Py_TYPE(raw) == &PyFileIO_Type);
1826
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 self->ok = 1;
1828 return 0;
1829}
1830
1831static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001832_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001833{
1834 Py_buffer buf;
1835 PyObject *memobj, *res;
1836 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001837 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838 /* NOTE: the buffer needn't be released as its object is NULL. */
1839 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1840 return -1;
1841 memobj = PyMemoryView_FromBuffer(&buf);
1842 if (memobj == NULL)
1843 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001844 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1845 occurs so we needn't do it ourselves.
1846 We then retry writing, ignoring the signal if no handler has
1847 raised (see issue #10956).
1848 */
1849 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001850 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001851 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001852 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001853 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854 Py_DECREF(memobj);
1855 if (res == NULL)
1856 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001857 if (res == Py_None) {
1858 /* Non-blocking stream would have blocked. Special return code!
1859 Being paranoid we reset errno in case it is changed by code
1860 triggered by a decref. errno is used by _set_BlockingIOError(). */
1861 Py_DECREF(res);
1862 errno = errnum;
1863 return -2;
1864 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001865 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1866 Py_DECREF(res);
1867 if (n < 0 || n > len) {
1868 PyErr_Format(PyExc_IOError,
1869 "raw write() returned invalid length %zd "
1870 "(should have been between 0 and %zd)", n, len);
1871 return -1;
1872 }
1873 if (n > 0 && self->abs_pos != -1)
1874 self->abs_pos += n;
1875 return n;
1876}
1877
1878/* `restore_pos` is 1 if we need to restore the raw stream position at
1879 the end, 0 otherwise. */
1880static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001882{
1883 Py_ssize_t written = 0;
1884 Py_off_t n, rewind;
1885
1886 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1887 goto end;
1888 /* First, rewind */
1889 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1890 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001891 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001892 if (n < 0) {
1893 goto error;
1894 }
1895 self->raw_pos -= rewind;
1896 }
1897 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001898 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001899 self->buffer + self->write_pos,
1900 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1901 Py_off_t, Py_ssize_t));
1902 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001903 goto error;
1904 }
1905 else if (n == -2) {
1906 _set_BlockingIOError("write could not complete without blocking",
1907 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908 goto error;
1909 }
1910 self->write_pos += n;
1911 self->raw_pos = self->write_pos;
1912 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001913 /* Partial writes can return successfully when interrupted by a
1914 signal (see write(2)). We must run signal handlers before
1915 blocking another time, possibly indefinitely. */
1916 if (PyErr_CheckSignals() < 0)
1917 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918 }
1919
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001920 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921
1922end:
1923 Py_RETURN_NONE;
1924
1925error:
1926 return NULL;
1927}
1928
1929static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001930bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001931{
1932 PyObject *res = NULL;
1933 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001934 Py_ssize_t written, avail, remaining;
1935 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936
1937 CHECK_INITIALIZED(self)
1938 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1939 return NULL;
1940 }
1941
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001942 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001943 PyErr_SetString(PyExc_ValueError, "write to closed file");
1944 PyBuffer_Release(&buf);
1945 return NULL;
1946 }
1947
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001948 if (!ENTER_BUFFERED(self)) {
1949 PyBuffer_Release(&buf);
1950 return NULL;
1951 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952
1953 /* Fast path: the data to write can be fully buffered. */
1954 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1955 self->pos = 0;
1956 self->raw_pos = 0;
1957 }
1958 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1959 if (buf.len <= avail) {
1960 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001961 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001962 self->write_pos = self->pos;
1963 }
1964 ADJUST_POSITION(self, self->pos + buf.len);
1965 if (self->pos > self->write_end)
1966 self->write_end = self->pos;
1967 written = buf.len;
1968 goto end;
1969 }
1970
1971 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001972 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001974 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001975 if (w == NULL)
1976 goto error;
1977 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001978 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001979 /* Make some place by shifting the buffer. */
1980 assert(VALID_WRITE_BUFFER(self));
1981 memmove(self->buffer, self->buffer + self->write_pos,
1982 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1983 Py_off_t, Py_ssize_t));
1984 self->write_end -= self->write_pos;
1985 self->raw_pos -= self->write_pos;
1986 self->pos -= self->write_pos;
1987 self->write_pos = 0;
1988 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1989 Py_off_t, Py_ssize_t);
1990 if (buf.len <= avail) {
1991 /* Everything can be buffered */
1992 PyErr_Clear();
1993 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1994 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001995 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 written = buf.len;
1997 goto end;
1998 }
1999 /* Buffer as much as possible. */
2000 memcpy(self->buffer + self->write_end, buf.buf, avail);
2001 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002002 self->pos += avail;
2003 /* XXX Modifying the existing exception e using the pointer w
2004 will change e.characters_written but not e.args[2].
2005 Therefore we just replace with a new error. */
2006 _set_BlockingIOError("write could not complete without blocking",
2007 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 goto error;
2009 }
2010 Py_CLEAR(res);
2011
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002012 /* Adjust the raw stream position if it is away from the logical stream
2013 position. This happens if the read buffer has been filled but not
2014 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2015 the raw stream by itself).
2016 Fixes issue #6629.
2017 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002018 offset = RAW_OFFSET(self);
2019 if (offset != 0) {
2020 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002021 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002022 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002023 }
2024
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025 /* Then write buf itself. At this point the buffer has been emptied. */
2026 remaining = buf.len;
2027 written = 0;
2028 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002029 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 self, (char *) buf.buf + written, buf.len - written);
2031 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002032 goto error;
2033 } else if (n == -2) {
2034 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035 if (remaining > self->buffer_size) {
2036 /* Can't buffer everything, still buffer as much as possible */
2037 memcpy(self->buffer,
2038 (char *) buf.buf + written, self->buffer_size);
2039 self->raw_pos = 0;
2040 ADJUST_POSITION(self, self->buffer_size);
2041 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002042 written += self->buffer_size;
2043 _set_BlockingIOError("write could not complete without "
2044 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002045 goto error;
2046 }
2047 PyErr_Clear();
2048 break;
2049 }
2050 written += n;
2051 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002052 /* Partial writes can return successfully when interrupted by a
2053 signal (see write(2)). We must run signal handlers before
2054 blocking another time, possibly indefinitely. */
2055 if (PyErr_CheckSignals() < 0)
2056 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002057 }
2058 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002059 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060 if (remaining > 0) {
2061 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2062 written += remaining;
2063 }
2064 self->write_pos = 0;
2065 /* TODO: sanity check (remaining >= 0) */
2066 self->write_end = remaining;
2067 ADJUST_POSITION(self, remaining);
2068 self->raw_pos = 0;
2069
2070end:
2071 res = PyLong_FromSsize_t(written);
2072
2073error:
2074 LEAVE_BUFFERED(self)
2075 PyBuffer_Release(&buf);
2076 return res;
2077}
2078
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002079static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002080 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002081 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2082 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2083 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2084 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2085 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2086 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2087 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002088 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002089 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002090
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002091 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2092 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2093 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2094 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2095 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002096 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097 {NULL, NULL}
2098};
2099
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002101 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002102 {NULL}
2103};
2104
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105static PyGetSetDef bufferedwriter_getset[] = {
2106 {"closed", (getter)buffered_closed_get, NULL, NULL},
2107 {"name", (getter)buffered_name_get, NULL, NULL},
2108 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002109 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110};
2111
2112
2113PyTypeObject PyBufferedWriter_Type = {
2114 PyVarObject_HEAD_INIT(NULL, 0)
2115 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002116 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002117 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002118 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002119 0, /*tp_print*/
2120 0, /*tp_getattr*/
2121 0, /*tp_setattr*/
2122 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124 0, /*tp_as_number*/
2125 0, /*tp_as_sequence*/
2126 0, /*tp_as_mapping*/
2127 0, /*tp_hash */
2128 0, /*tp_call*/
2129 0, /*tp_str*/
2130 0, /*tp_getattro*/
2131 0, /*tp_setattro*/
2132 0, /*tp_as_buffer*/
2133 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2134 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002135 bufferedwriter_doc, /* tp_doc */
2136 (traverseproc)buffered_traverse, /* tp_traverse */
2137 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140 0, /* tp_iter */
2141 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002142 bufferedwriter_methods, /* tp_methods */
2143 bufferedwriter_members, /* tp_members */
2144 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145 0, /* tp_base */
2146 0, /* tp_dict */
2147 0, /* tp_descr_get */
2148 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002149 offsetof(buffered, dict), /* tp_dictoffset */
2150 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151 0, /* tp_alloc */
2152 PyType_GenericNew, /* tp_new */
2153};
2154
2155
2156
2157/*
2158 * BufferedRWPair
2159 */
2160
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002161PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002162 "A buffered reader and writer object together.\n"
2163 "\n"
2164 "A buffered reader object and buffered writer object put together to\n"
2165 "form a sequential IO object that can read and write. This is typically\n"
2166 "used with a socket or two-way pipe.\n"
2167 "\n"
2168 "reader and writer are RawIOBase objects that are readable and\n"
2169 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002170 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 );
2172
2173/* XXX The usefulness of this (compared to having two separate IO objects) is
2174 * questionable.
2175 */
2176
2177typedef struct {
2178 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002179 buffered *reader;
2180 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181 PyObject *dict;
2182 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002183} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184
2185static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187{
2188 PyObject *reader, *writer;
2189 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002190
Florent Xicluna109d5732012-07-07 17:03:22 +02002191 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2192 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193 return -1;
2194 }
2195
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002196 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002198 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199 return -1;
2200
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002201 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002202 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203 if (self->reader == NULL)
2204 return -1;
2205
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002206 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002207 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208 if (self->writer == NULL) {
2209 Py_CLEAR(self->reader);
2210 return -1;
2211 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002212
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213 return 0;
2214}
2215
2216static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218{
2219 Py_VISIT(self->dict);
2220 return 0;
2221}
2222
2223static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225{
2226 Py_CLEAR(self->reader);
2227 Py_CLEAR(self->writer);
2228 Py_CLEAR(self->dict);
2229 return 0;
2230}
2231
2232static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002233bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234{
2235 _PyObject_GC_UNTRACK(self);
2236 Py_CLEAR(self->reader);
2237 Py_CLEAR(self->writer);
2238 Py_CLEAR(self->dict);
2239 Py_TYPE(self)->tp_free((PyObject *) self);
2240}
2241
2242static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002243_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002245 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246 PyObject *ret;
2247
2248 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002249 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250 return NULL;
2251 }
2252
2253 ret = PyObject_CallObject(func, args);
2254 Py_DECREF(func);
2255 return ret;
2256}
2257
2258static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002261 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262}
2263
2264static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002267 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002268}
2269
2270static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002271bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002272{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002273 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002274}
2275
2276static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002277bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002278{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002279 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002280}
2281
2282static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002283bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002284{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002285 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286}
2287
2288static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002291 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002292}
2293
2294static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002295bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002297 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298}
2299
2300static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002301bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002302{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002303 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002304}
2305
2306static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002307bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002309 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002310 if (ret == NULL)
2311 return NULL;
2312 Py_DECREF(ret);
2313
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002314 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002315}
2316
2317static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002318bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002320 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002321
2322 if (ret != Py_False) {
2323 /* either True or exception */
2324 return ret;
2325 }
2326 Py_DECREF(ret);
2327
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002328 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329}
2330
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002331static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002332bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002333{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002334 if (self->writer == NULL) {
2335 PyErr_SetString(PyExc_RuntimeError,
2336 "the BufferedRWPair object is being garbage-collected");
2337 return NULL;
2338 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002339 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2340}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002341
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002342static PyMethodDef bufferedrwpair_methods[] = {
2343 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2344 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2345 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2346 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002348 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2349 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002350
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002351 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2352 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002353
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002354 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2355 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002356
Antoine Pitrou243757e2010-11-05 21:15:39 +00002357 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2358
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002359 {NULL, NULL}
2360};
2361
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002362static PyGetSetDef bufferedrwpair_getset[] = {
2363 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002364 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002365};
2366
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002367PyTypeObject PyBufferedRWPair_Type = {
2368 PyVarObject_HEAD_INIT(NULL, 0)
2369 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002370 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002372 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002373 0, /*tp_print*/
2374 0, /*tp_getattr*/
2375 0, /*tp_setattr*/
2376 0, /*tp_compare */
2377 0, /*tp_repr*/
2378 0, /*tp_as_number*/
2379 0, /*tp_as_sequence*/
2380 0, /*tp_as_mapping*/
2381 0, /*tp_hash */
2382 0, /*tp_call*/
2383 0, /*tp_str*/
2384 0, /*tp_getattro*/
2385 0, /*tp_setattro*/
2386 0, /*tp_as_buffer*/
2387 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2388 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002389 bufferedrwpair_doc, /* tp_doc */
2390 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2391 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002392 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002393 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394 0, /* tp_iter */
2395 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002396 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002397 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002398 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002399 0, /* tp_base */
2400 0, /* tp_dict */
2401 0, /* tp_descr_get */
2402 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002403 offsetof(rwpair, dict), /* tp_dictoffset */
2404 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002405 0, /* tp_alloc */
2406 PyType_GenericNew, /* tp_new */
2407};
2408
2409
2410
2411/*
2412 * BufferedRandom
2413 */
2414
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002415PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002416 "A buffered interface to random access streams.\n"
2417 "\n"
2418 "The constructor creates a reader and writer for a seekable stream,\n"
2419 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002420 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421 );
2422
2423static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002424bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002425{
Florent Xicluna109d5732012-07-07 17:03:22 +02002426 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002427 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428 PyObject *raw;
2429
2430 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002431 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432
Florent Xicluna109d5732012-07-07 17:03:22 +02002433 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
2434 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002435 return -1;
2436 }
2437
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002438 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002439 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002440 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002441 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002442 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002443 return -1;
2444
2445 Py_CLEAR(self->raw);
2446 Py_INCREF(raw);
2447 self->raw = raw;
2448 self->buffer_size = buffer_size;
2449 self->readable = 1;
2450 self->writable = 1;
2451
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002452 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002454 _bufferedreader_reset_buf(self);
2455 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 self->pos = 0;
2457
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002458 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2459 Py_TYPE(raw) == &PyFileIO_Type);
2460
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461 self->ok = 1;
2462 return 0;
2463}
2464
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002465static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002467 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2468 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2469 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2470 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2471 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2472 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2473 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002474 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002475 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002476
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002477 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002478
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002479 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2480 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2481 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2482 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2483 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2484 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2485 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2486 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2487 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002488 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002489 {NULL, NULL}
2490};
2491
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002492static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002493 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494 {NULL}
2495};
2496
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002497static PyGetSetDef bufferedrandom_getset[] = {
2498 {"closed", (getter)buffered_closed_get, NULL, NULL},
2499 {"name", (getter)buffered_name_get, NULL, NULL},
2500 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002501 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002502};
2503
2504
2505PyTypeObject PyBufferedRandom_Type = {
2506 PyVarObject_HEAD_INIT(NULL, 0)
2507 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002508 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002509 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002510 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002511 0, /*tp_print*/
2512 0, /*tp_getattr*/
2513 0, /*tp_setattr*/
2514 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002515 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002516 0, /*tp_as_number*/
2517 0, /*tp_as_sequence*/
2518 0, /*tp_as_mapping*/
2519 0, /*tp_hash */
2520 0, /*tp_call*/
2521 0, /*tp_str*/
2522 0, /*tp_getattro*/
2523 0, /*tp_setattro*/
2524 0, /*tp_as_buffer*/
2525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2526 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002527 bufferedrandom_doc, /* tp_doc */
2528 (traverseproc)buffered_traverse, /* tp_traverse */
2529 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002530 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002531 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002533 (iternextfunc)buffered_iternext, /* tp_iternext */
2534 bufferedrandom_methods, /* tp_methods */
2535 bufferedrandom_members, /* tp_members */
2536 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 0, /* tp_base */
2538 0, /*tp_dict*/
2539 0, /* tp_descr_get */
2540 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002541 offsetof(buffered, dict), /*tp_dictoffset*/
2542 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002543 0, /* tp_alloc */
2544 PyType_GenericNew, /* tp_new */
2545};