blob: 8a9ae4704e45539cfafab68aa7554c368ae0d7cd [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
401static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000402buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000403{
404 Py_VISIT(self->raw);
405 Py_VISIT(self->dict);
406 return 0;
407}
408
409static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000410buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000411{
412 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
413 return -1;
414 self->ok = 0;
415 Py_CLEAR(self->raw);
416 Py_CLEAR(self->dict);
417 return 0;
418}
419
Antoine Pitroue033e062010-10-29 10:38:18 +0000420/* Because this can call arbitrary code, it shouldn't be called when
421 the refcount is 0 (that is, not directly from tp_dealloc unless
422 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000423static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000424buffered_dealloc_warn(buffered *self, PyObject *source)
425{
426 if (self->ok && self->raw) {
427 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200428 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000429 if (r)
430 Py_DECREF(r);
431 else
432 PyErr_Clear();
433 }
434 Py_RETURN_NONE;
435}
436
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000437/*
438 * _BufferedIOMixin methods
439 * This is not a class, just a collection of methods that will be reused
440 * by BufferedReader and BufferedWriter
441 */
442
443/* Flush and close */
444
445static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000446buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000447{
448 CHECK_INITIALIZED(self)
449 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
450}
451
452static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000453buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000454{
455 int closed;
456 PyObject *res;
457 CHECK_INITIALIZED_INT(self)
458 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
459 if (res == NULL)
460 return -1;
461 closed = PyObject_IsTrue(res);
462 Py_DECREF(res);
463 return closed;
464}
465
466static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000467buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000468{
469 CHECK_INITIALIZED(self)
470 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
471}
472
473static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000474buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000475{
476 PyObject *res = NULL;
477 int r;
478
479 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000480 if (!ENTER_BUFFERED(self))
481 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000483 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000484 if (r < 0)
485 goto end;
486 if (r > 0) {
487 res = Py_None;
488 Py_INCREF(res);
489 goto end;
490 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000491
492 if (self->deallocating) {
493 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
494 if (r)
495 Py_DECREF(r);
496 else
497 PyErr_Clear();
498 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000499 /* flush() will most probably re-take the lock, so drop it first */
500 LEAVE_BUFFERED(self)
501 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000502 if (!ENTER_BUFFERED(self))
503 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504 if (res == NULL) {
Antoine Pitrou6be88762010-05-03 16:48:20 +0000505 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506 }
507 Py_XDECREF(res);
508
509 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
510
511end:
512 LEAVE_BUFFERED(self)
513 return res;
514}
515
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000516/* detach */
517
518static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000519buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000520{
521 PyObject *raw, *res;
522 CHECK_INITIALIZED(self)
523 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
524 if (res == NULL)
525 return NULL;
526 Py_DECREF(res);
527 raw = self->raw;
528 self->raw = NULL;
529 self->detached = 1;
530 self->ok = 0;
531 return raw;
532}
533
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000534/* Inquiries */
535
536static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000537buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000538{
539 CHECK_INITIALIZED(self)
540 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
541}
542
543static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000544buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000545{
546 CHECK_INITIALIZED(self)
547 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
548}
549
550static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000551buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000552{
553 CHECK_INITIALIZED(self)
554 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
555}
556
557static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000558buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000559{
560 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200561 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562}
563
564static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000565buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000566{
567 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200568 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569}
570
571/* Lower-level APIs */
572
573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000574buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575{
576 CHECK_INITIALIZED(self)
577 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
578}
579
580static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000581buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582{
583 CHECK_INITIALIZED(self)
584 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
585}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000586
Antoine Pitrou243757e2010-11-05 21:15:39 +0000587/* Serialization */
588
589static PyObject *
590buffered_getstate(buffered *self, PyObject *args)
591{
592 PyErr_Format(PyExc_TypeError,
593 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
594 return NULL;
595}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000596
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597/* Forward decls */
598static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100599_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000601_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000603_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200607_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000611_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200614static Py_ssize_t
615_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616
617/*
618 * Helpers
619 */
620
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100621/* Sets the current error to BlockingIOError */
622static void
623_set_BlockingIOError(char *msg, Py_ssize_t written)
624{
625 PyObject *err;
626 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
627 errno, msg, written);
628 if (err)
629 PyErr_SetObject(PyExc_BlockingIOError, err);
630 Py_XDECREF(err);
631}
632
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633/* Returns the address of the `written` member if a BlockingIOError was
634 raised, NULL otherwise. The error is always re-raised. */
635static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637{
638 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200639 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640
641 PyErr_Fetch(&t, &v, &tb);
642 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
643 PyErr_Restore(t, v, tb);
644 return NULL;
645 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200646 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647 /* TODO: sanity check (err->written >= 0) */
648 PyErr_Restore(t, v, tb);
649 return &err->written;
650}
651
652static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000656 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
658 if (res == NULL)
659 return -1;
660 n = PyNumber_AsOff_t(res, PyExc_ValueError);
661 Py_DECREF(res);
662 if (n < 0) {
663 if (!PyErr_Occurred())
664 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000665 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200666 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000667 return -1;
668 }
669 self->abs_pos = n;
670 return n;
671}
672
673static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000674_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675{
676 PyObject *res, *posobj, *whenceobj;
677 Py_off_t n;
678
679 posobj = PyLong_FromOff_t(target);
680 if (posobj == NULL)
681 return -1;
682 whenceobj = PyLong_FromLong(whence);
683 if (whenceobj == NULL) {
684 Py_DECREF(posobj);
685 return -1;
686 }
687 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
688 posobj, whenceobj, NULL);
689 Py_DECREF(posobj);
690 Py_DECREF(whenceobj);
691 if (res == NULL)
692 return -1;
693 n = PyNumber_AsOff_t(res, PyExc_ValueError);
694 Py_DECREF(res);
695 if (n < 0) {
696 if (!PyErr_Occurred())
697 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000698 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200699 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700 return -1;
701 }
702 self->abs_pos = n;
703 return n;
704}
705
706static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000707_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708{
709 Py_ssize_t n;
710 if (self->buffer_size <= 0) {
711 PyErr_SetString(PyExc_ValueError,
712 "buffer size must be strictly positive");
713 return -1;
714 }
715 if (self->buffer)
716 PyMem_Free(self->buffer);
717 self->buffer = PyMem_Malloc(self->buffer_size);
718 if (self->buffer == NULL) {
719 PyErr_NoMemory();
720 return -1;
721 }
Georg Brandldfd73442009-04-05 11:47:34 +0000722#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000723 if (self->lock)
724 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000725 self->lock = PyThread_allocate_lock();
726 if (self->lock == NULL) {
727 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
728 return -1;
729 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000730 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000731#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732 /* Find out whether buffer_size is a power of 2 */
733 /* XXX is this optimization useful? */
734 for (n = self->buffer_size - 1; n & 1; n >>= 1)
735 ;
736 if (n == 0)
737 self->buffer_mask = self->buffer_size - 1;
738 else
739 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000740 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 PyErr_Clear();
742 return 0;
743}
744
Antoine Pitrou707ce822011-02-25 21:24:11 +0000745/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
746 clears the error indicator), 0 otherwise.
747 Should only be called when PyErr_Occurred() is true.
748*/
749static int
750_trap_eintr(void)
751{
752 static PyObject *eintr_int = NULL;
753 PyObject *typ, *val, *tb;
754 PyEnvironmentErrorObject *env_err;
755
756 if (eintr_int == NULL) {
757 eintr_int = PyLong_FromLong(EINTR);
758 assert(eintr_int != NULL);
759 }
760 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
761 return 0;
762 PyErr_Fetch(&typ, &val, &tb);
763 PyErr_NormalizeException(&typ, &val, &tb);
764 env_err = (PyEnvironmentErrorObject *) val;
765 assert(env_err != NULL);
766 if (env_err->myerrno != NULL &&
767 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
768 Py_DECREF(typ);
769 Py_DECREF(val);
770 Py_XDECREF(tb);
771 return 1;
772 }
773 /* This silences any error set by PyObject_RichCompareBool() */
774 PyErr_Restore(typ, val, tb);
775 return 0;
776}
777
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778/*
779 * Shared methods and wrappers
780 */
781
782static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200783buffered_flush_and_rewind_unlocked(buffered *self)
784{
785 PyObject *res;
786
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100787 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200788 if (res == NULL)
789 return NULL;
790 Py_DECREF(res);
791
792 if (self->readable) {
793 /* Rewind the raw stream so that its position corresponds to
794 the current logical position. */
795 Py_off_t n;
796 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
797 _bufferedreader_reset_buf(self);
798 if (n == -1)
799 return NULL;
800 }
801 Py_RETURN_NONE;
802}
803
804static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000805buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000806{
807 PyObject *res;
808
809 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000810 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000811
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000812 if (!ENTER_BUFFERED(self))
813 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200814 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000815 LEAVE_BUFFERED(self)
816
817 return res;
818}
819
820static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000821buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822{
823 Py_ssize_t n = 0;
824 PyObject *res = NULL;
825
826 CHECK_INITIALIZED(self)
827 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
828 return NULL;
829 }
830
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000831 if (!ENTER_BUFFERED(self))
832 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833
834 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200835 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000836 if (res == NULL)
837 goto end;
838 Py_CLEAR(res);
839 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200840 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841
842end:
843 LEAVE_BUFFERED(self)
844 return res;
845}
846
847static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000848buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849{
850 Py_ssize_t n = -1;
851 PyObject *res;
852
853 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000854 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855 return NULL;
856 }
857 if (n < -1) {
858 PyErr_SetString(PyExc_ValueError,
859 "read length must be positive or -1");
860 return NULL;
861 }
862
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000863 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000865 if (n == -1) {
866 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000867 if (!ENTER_BUFFERED(self))
868 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000869 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000870 }
871 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000872 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200873 if (res != Py_None)
874 return res;
875 Py_DECREF(res);
876 if (!ENTER_BUFFERED(self))
877 return NULL;
878 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000879 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880
Antoine Pitroue05565e2011-08-20 14:39:23 +0200881 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882 return res;
883}
884
885static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000886buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887{
888 Py_ssize_t n, have, r;
889 PyObject *res = NULL;
890
891 CHECK_INITIALIZED(self)
892 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
893 return NULL;
894 }
895
896 if (n < 0) {
897 PyErr_SetString(PyExc_ValueError,
898 "read length must be positive");
899 return NULL;
900 }
901 if (n == 0)
902 return PyBytes_FromStringAndSize(NULL, 0);
903
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000904 /* Return up to n bytes. If at least one byte is buffered, we
905 only return buffered bytes. Otherwise, we do one raw read. */
906
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000907 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
908 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100909 n = Py_MIN(have, n);
910 res = _bufferedreader_read_fast(self, n);
911 assert(res != Py_None);
912 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100914 res = PyBytes_FromStringAndSize(NULL, n);
915 if (res == NULL)
916 return NULL;
917 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200918 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100919 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200920 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000921 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100922 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
923 LEAVE_BUFFERED(self)
924 if (r == -1) {
925 Py_DECREF(res);
926 return NULL;
927 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000928 if (r == -2)
929 r = 0;
930 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100931 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932 return res;
933}
934
935static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000936buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000937{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200938 Py_buffer buf;
939 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940 PyObject *res = NULL;
941
942 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200943
944 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
945 return NULL;
946
947 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
948 if (n > 0) {
949 if (n >= buf.len) {
950 memcpy(buf.buf, self->buffer + self->pos, buf.len);
951 self->pos += buf.len;
952 res = PyLong_FromSsize_t(buf.len);
953 goto end_unlocked;
954 }
955 memcpy(buf.buf, self->buffer + self->pos, n);
956 self->pos += n;
957 written = n;
958 }
959
960 if (!ENTER_BUFFERED(self))
961 goto end_unlocked;
962
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200964 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000965 if (res == NULL)
966 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200967 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200969
970 _bufferedreader_reset_buf(self);
971 self->pos = 0;
972
973 for (remaining = buf.len - written;
974 remaining > 0;
975 written += n, remaining -= n) {
976 /* If remaining bytes is larger than internal buffer size, copy
977 * directly into caller's buffer. */
978 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200979 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
980 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200981 }
982 else {
983 n = _bufferedreader_fill_buffer(self);
984 if (n > 0) {
985 if (n > remaining)
986 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200987 memcpy((char *) buf.buf + written,
988 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200989 self->pos += n;
990 continue; /* short circuit */
991 }
992 }
993 if (n == 0 || (n == -2 && written > 0))
994 break;
995 if (n < 0) {
996 if (n == -2) {
997 Py_INCREF(Py_None);
998 res = Py_None;
999 }
1000 goto end;
1001 }
1002 }
1003 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001004
1005end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001006 LEAVE_BUFFERED(self);
1007end_unlocked:
1008 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001009 return res;
1010}
1011
1012static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001013_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014{
1015 PyObject *res = NULL;
1016 PyObject *chunks = NULL;
1017 Py_ssize_t n, written = 0;
1018 const char *start, *s, *end;
1019
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001020 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001022 /* First, try to find a line in the buffer. This can run unlocked because
1023 the calls to the C API are simple enough that they can't trigger
1024 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001025 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1026 if (limit >= 0 && n > limit)
1027 n = limit;
1028 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001029 s = memchr(start, '\n', n);
1030 if (s != NULL) {
1031 res = PyBytes_FromStringAndSize(start, s - start + 1);
1032 if (res != NULL)
1033 self->pos += s - start + 1;
1034 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001035 }
1036 if (n == limit) {
1037 res = PyBytes_FromStringAndSize(start, n);
1038 if (res != NULL)
1039 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001040 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 }
1042
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001043 if (!ENTER_BUFFERED(self))
1044 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001045
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 chunks = PyList_New(0);
1048 if (chunks == NULL)
1049 goto end;
1050 if (n > 0) {
1051 res = PyBytes_FromStringAndSize(start, n);
1052 if (res == NULL)
1053 goto end;
1054 if (PyList_Append(chunks, res) < 0) {
1055 Py_CLEAR(res);
1056 goto end;
1057 }
1058 Py_CLEAR(res);
1059 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001060 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001061 if (limit >= 0)
1062 limit -= n;
1063 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001064 if (self->writable) {
1065 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1066 if (r == NULL)
1067 goto end;
1068 Py_DECREF(r);
1069 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070
1071 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001072 _bufferedreader_reset_buf(self);
1073 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001074 if (n == -1)
1075 goto end;
1076 if (n <= 0)
1077 break;
1078 if (limit >= 0 && n > limit)
1079 n = limit;
1080 start = self->buffer;
1081 end = start + n;
1082 s = start;
1083 while (s < end) {
1084 if (*s++ == '\n') {
1085 res = PyBytes_FromStringAndSize(start, s - start);
1086 if (res == NULL)
1087 goto end;
1088 self->pos = s - start;
1089 goto found;
1090 }
1091 }
1092 res = PyBytes_FromStringAndSize(start, n);
1093 if (res == NULL)
1094 goto end;
1095 if (n == limit) {
1096 self->pos = n;
1097 break;
1098 }
1099 if (PyList_Append(chunks, res) < 0) {
1100 Py_CLEAR(res);
1101 goto end;
1102 }
1103 Py_CLEAR(res);
1104 written += n;
1105 if (limit >= 0)
1106 limit -= n;
1107 }
1108found:
1109 if (res != NULL && PyList_Append(chunks, res) < 0) {
1110 Py_CLEAR(res);
1111 goto end;
1112 }
1113 Py_CLEAR(res);
1114 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1115
1116end:
1117 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001118end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 Py_XDECREF(chunks);
1120 return res;
1121}
1122
1123static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001124buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001125{
1126 Py_ssize_t limit = -1;
1127
1128 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001129 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001130 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001131 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132}
1133
1134
1135static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001136buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001137{
1138 Py_off_t pos;
1139
1140 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001141 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001142 if (pos == -1)
1143 return NULL;
1144 pos -= RAW_OFFSET(self);
1145 /* TODO: sanity check (pos >= 0) */
1146 return PyLong_FromOff_t(pos);
1147}
1148
1149static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001150buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001151{
1152 Py_off_t target, n;
1153 int whence = 0;
1154 PyObject *targetobj, *res = NULL;
1155
1156 CHECK_INITIALIZED(self)
1157 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1158 return NULL;
1159 }
Jesus Cea990eff02012-04-26 17:05:31 +02001160 if (whence < 0 || whence > 2) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001161 PyErr_Format(PyExc_ValueError,
Jesus Cea990eff02012-04-26 17:05:31 +02001162 "whence must be between 0 and 2, not %d", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001163 return NULL;
1164 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001165
1166 CHECK_CLOSED(self, "seek of closed file")
1167
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001168 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1169 return NULL;
1170
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001171 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1172 if (target == -1 && PyErr_Occurred())
1173 return NULL;
1174
Jesus Cea990eff02012-04-26 17:05:31 +02001175 if (whence != 2 && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176 Py_off_t current, avail;
1177 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001178 so as to return quickly if possible. Also, we needn't take the
1179 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001180 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001181 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1182 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183 current = RAW_TELL(self);
1184 avail = READAHEAD(self);
1185 if (avail > 0) {
1186 Py_off_t offset;
1187 if (whence == 0)
1188 offset = target - (current - RAW_OFFSET(self));
1189 else
1190 offset = target;
1191 if (offset >= -self->pos && offset <= avail) {
1192 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001193 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001194 }
1195 }
1196 }
1197
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001198 if (!ENTER_BUFFERED(self))
1199 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001200
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201 /* Fallback: invoke raw seek() method and clear buffer */
1202 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001203 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204 if (res == NULL)
1205 goto end;
1206 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001207 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001208 }
1209
1210 /* TODO: align on block boundary and read buffer if needed? */
1211 if (whence == 1)
1212 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001213 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001214 if (n == -1)
1215 goto end;
1216 self->raw_pos = -1;
1217 res = PyLong_FromOff_t(n);
1218 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001219 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220
1221end:
1222 LEAVE_BUFFERED(self)
1223 return res;
1224}
1225
1226static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001227buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001228{
1229 PyObject *pos = Py_None;
1230 PyObject *res = NULL;
1231
1232 CHECK_INITIALIZED(self)
1233 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1234 return NULL;
1235 }
1236
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001237 if (!ENTER_BUFFERED(self))
1238 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239
1240 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001241 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001242 if (res == NULL)
1243 goto end;
1244 Py_CLEAR(res);
1245 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1247 if (res == NULL)
1248 goto end;
1249 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001250 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 PyErr_Clear();
1252
1253end:
1254 LEAVE_BUFFERED(self)
1255 return res;
1256}
1257
1258static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001259buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260{
1261 PyObject *line;
1262 PyTypeObject *tp;
1263
1264 CHECK_INITIALIZED(self);
1265
1266 tp = Py_TYPE(self);
1267 if (tp == &PyBufferedReader_Type ||
1268 tp == &PyBufferedRandom_Type) {
1269 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001270 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001271 }
1272 else {
1273 line = PyObject_CallMethodObjArgs((PyObject *)self,
1274 _PyIO_str_readline, NULL);
1275 if (line && !PyBytes_Check(line)) {
1276 PyErr_Format(PyExc_IOError,
1277 "readline() should have returned a bytes object, "
1278 "not '%.200s'", Py_TYPE(line)->tp_name);
1279 Py_DECREF(line);
1280 return NULL;
1281 }
1282 }
1283
1284 if (line == NULL)
1285 return NULL;
1286
1287 if (PyBytes_GET_SIZE(line) == 0) {
1288 /* Reached EOF or would have blocked */
1289 Py_DECREF(line);
1290 return NULL;
1291 }
1292
1293 return line;
1294}
1295
Antoine Pitrou716c4442009-05-23 19:04:03 +00001296static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001297buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001298{
1299 PyObject *nameobj, *res;
1300
Martin v. Löwis767046a2011-10-14 15:35:36 +02001301 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001302 if (nameobj == NULL) {
1303 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1304 PyErr_Clear();
1305 else
1306 return NULL;
1307 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1308 }
1309 else {
1310 res = PyUnicode_FromFormat("<%s name=%R>",
1311 Py_TYPE(self)->tp_name, nameobj);
1312 Py_DECREF(nameobj);
1313 }
1314 return res;
1315}
1316
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001317/*
1318 * class BufferedReader
1319 */
1320
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001321PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 "Create a new buffered reader using the given readable raw IO object.");
1323
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001324static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001325{
1326 self->read_end = -1;
1327}
1328
1329static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001330bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331{
1332 char *kwlist[] = {"raw", "buffer_size", NULL};
1333 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1334 PyObject *raw;
1335
1336 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001337 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001338
1339 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1340 &raw, &buffer_size)) {
1341 return -1;
1342 }
1343
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001344 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001345 return -1;
1346
1347 Py_CLEAR(self->raw);
1348 Py_INCREF(raw);
1349 self->raw = raw;
1350 self->buffer_size = buffer_size;
1351 self->readable = 1;
1352 self->writable = 0;
1353
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001354 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001356 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001357
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001358 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1359 Py_TYPE(raw) == &PyFileIO_Type);
1360
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361 self->ok = 1;
1362 return 0;
1363}
1364
1365static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001366_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367{
1368 Py_buffer buf;
1369 PyObject *memobj, *res;
1370 Py_ssize_t n;
1371 /* NOTE: the buffer needn't be released as its object is NULL. */
1372 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1373 return -1;
1374 memobj = PyMemoryView_FromBuffer(&buf);
1375 if (memobj == NULL)
1376 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001377 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1378 occurs so we needn't do it ourselves.
1379 We then retry reading, ignoring the signal if no handler has
1380 raised (see issue #10956).
1381 */
1382 do {
1383 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1384 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001385 Py_DECREF(memobj);
1386 if (res == NULL)
1387 return -1;
1388 if (res == Py_None) {
1389 /* Non-blocking stream would have blocked. Special return code! */
1390 Py_DECREF(res);
1391 return -2;
1392 }
1393 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1394 Py_DECREF(res);
1395 if (n < 0 || n > len) {
1396 PyErr_Format(PyExc_IOError,
1397 "raw readinto() returned invalid length %zd "
1398 "(should have been between 0 and %zd)", n, len);
1399 return -1;
1400 }
1401 if (n > 0 && self->abs_pos != -1)
1402 self->abs_pos += n;
1403 return n;
1404}
1405
1406static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001407_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001408{
1409 Py_ssize_t start, len, n;
1410 if (VALID_READ_BUFFER(self))
1411 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1412 else
1413 start = 0;
1414 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001415 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416 if (n <= 0)
1417 return n;
1418 self->read_end = start + n;
1419 self->raw_pos = start + n;
1420 return n;
1421}
1422
1423static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001424_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001425{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001426 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001427 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001428
1429 /* First copy what we have in the current buffer. */
1430 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1431 if (current_size) {
1432 data = PyBytes_FromStringAndSize(
1433 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001434 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001436 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001438 /* We're going past the buffer's bounds, flush it */
1439 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001440 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001441 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001442 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001443 Py_CLEAR(res);
1444 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001445 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001446
1447 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1448 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1449 if (chunk == NULL)
1450 return NULL;
1451 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1452 Py_XDECREF(data);
1453 Py_DECREF(chunk);
1454 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1455 return NULL;
1456 }
1457 if (chunk == Py_None) {
1458 if (current_size == 0)
1459 return chunk;
1460 else {
1461 Py_DECREF(chunk);
1462 return data;
1463 }
1464 }
1465 else if (current_size) {
1466 PyBytes_Concat(&data, chunk);
1467 Py_DECREF(chunk);
1468 if (data == NULL)
1469 return NULL;
1470 return data;
1471 } else
1472 return chunk;
1473 }
1474
1475 chunks = PyList_New(0);
1476 if (chunks == NULL)
1477 return NULL;
1478
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001479 while (1) {
1480 if (data) {
1481 if (PyList_Append(chunks, data) < 0) {
1482 Py_DECREF(data);
1483 Py_DECREF(chunks);
1484 return NULL;
1485 }
1486 Py_DECREF(data);
1487 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001488
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001489 /* Read until EOF or until read() would block. */
1490 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1491 if (data == NULL) {
1492 Py_DECREF(chunks);
1493 return NULL;
1494 }
1495 if (data != Py_None && !PyBytes_Check(data)) {
1496 Py_DECREF(data);
1497 Py_DECREF(chunks);
1498 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1499 return NULL;
1500 }
1501 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1502 if (current_size == 0) {
1503 Py_DECREF(chunks);
1504 return data;
1505 }
1506 else {
1507 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1508 Py_DECREF(data);
1509 Py_DECREF(chunks);
1510 return res;
1511 }
1512 }
1513 current_size += PyBytes_GET_SIZE(data);
1514 if (self->abs_pos != -1)
1515 self->abs_pos += PyBytes_GET_SIZE(data);
1516 }
1517}
1518
1519/* Read n bytes from the buffer if it can, otherwise return None.
1520 This function is simple enough that it can run unlocked. */
1521static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001522_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001523{
1524 Py_ssize_t current_size;
1525
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001526 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1527 if (n <= current_size) {
1528 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001529 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1530 if (res != NULL)
1531 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532 return res;
1533 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001534 Py_RETURN_NONE;
1535}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001536
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001537/* Generic read function: read from the stream until enough bytes are read,
1538 * or until an EOF occurs or until read() would block.
1539 */
1540static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001541_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001542{
1543 PyObject *res = NULL;
1544 Py_ssize_t current_size, remaining, written;
1545 char *out;
1546
1547 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1548 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001549 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001551 res = PyBytes_FromStringAndSize(NULL, n);
1552 if (res == NULL)
1553 goto error;
1554 out = PyBytes_AS_STRING(res);
1555 remaining = n;
1556 written = 0;
1557 if (current_size > 0) {
1558 memcpy(out, self->buffer + self->pos, current_size);
1559 remaining -= current_size;
1560 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001561 self->pos += current_size;
1562 }
1563 /* Flush the write buffer if necessary */
1564 if (self->writable) {
1565 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1566 if (r == NULL)
1567 goto error;
1568 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001569 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001570 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001571 while (remaining > 0) {
1572 /* We want to read a whole block at the end into buffer.
1573 If we had readv() we could do this in one pass. */
1574 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1575 if (r == 0)
1576 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001577 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001578 if (r == -1)
1579 goto error;
1580 if (r == 0 || r == -2) {
1581 /* EOF occurred or read() would block. */
1582 if (r == 0 || written > 0) {
1583 if (_PyBytes_Resize(&res, written))
1584 goto error;
1585 return res;
1586 }
1587 Py_DECREF(res);
1588 Py_INCREF(Py_None);
1589 return Py_None;
1590 }
1591 remaining -= r;
1592 written += r;
1593 }
1594 assert(remaining <= self->buffer_size);
1595 self->pos = 0;
1596 self->raw_pos = 0;
1597 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001598 /* NOTE: when the read is satisfied, we avoid issuing any additional
1599 reads, which could block indefinitely (e.g. on a socket).
1600 See issue #9550. */
1601 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001602 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001603 if (r == -1)
1604 goto error;
1605 if (r == 0 || r == -2) {
1606 /* EOF occurred or read() would block. */
1607 if (r == 0 || written > 0) {
1608 if (_PyBytes_Resize(&res, written))
1609 goto error;
1610 return res;
1611 }
1612 Py_DECREF(res);
1613 Py_INCREF(Py_None);
1614 return Py_None;
1615 }
1616 if (remaining > r) {
1617 memcpy(out + written, self->buffer + self->pos, r);
1618 written += r;
1619 self->pos += r;
1620 remaining -= r;
1621 }
1622 else if (remaining > 0) {
1623 memcpy(out + written, self->buffer + self->pos, remaining);
1624 written += remaining;
1625 self->pos += remaining;
1626 remaining = 0;
1627 }
1628 if (remaining == 0)
1629 break;
1630 }
1631
1632 return res;
1633
1634error:
1635 Py_XDECREF(res);
1636 return NULL;
1637}
1638
1639static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001640_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001641{
1642 Py_ssize_t have, r;
1643
1644 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1645 /* Constraints:
1646 1. we don't want to advance the file position.
1647 2. we don't want to lose block alignment, so we can't shift the buffer
1648 to make some place.
1649 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1650 */
1651 if (have > 0) {
1652 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1653 }
1654
1655 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001656 _bufferedreader_reset_buf(self);
1657 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001658 if (r == -1)
1659 return NULL;
1660 if (r == -2)
1661 r = 0;
1662 self->pos = 0;
1663 return PyBytes_FromStringAndSize(self->buffer, r);
1664}
1665
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001666static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001667 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001668 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1669 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1670 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1671 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1672 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1673 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1674 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1675 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001676 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001677 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001678
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001679 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1680 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1681 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001682 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001683 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1684 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1685 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1686 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001687 {NULL, NULL}
1688};
1689
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001690static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001691 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001692 {NULL}
1693};
1694
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001695static PyGetSetDef bufferedreader_getset[] = {
1696 {"closed", (getter)buffered_closed_get, NULL, NULL},
1697 {"name", (getter)buffered_name_get, NULL, NULL},
1698 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001699 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700};
1701
1702
1703PyTypeObject PyBufferedReader_Type = {
1704 PyVarObject_HEAD_INIT(NULL, 0)
1705 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001706 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001707 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001708 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001709 0, /*tp_print*/
1710 0, /*tp_getattr*/
1711 0, /*tp_setattr*/
1712 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001713 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001714 0, /*tp_as_number*/
1715 0, /*tp_as_sequence*/
1716 0, /*tp_as_mapping*/
1717 0, /*tp_hash */
1718 0, /*tp_call*/
1719 0, /*tp_str*/
1720 0, /*tp_getattro*/
1721 0, /*tp_setattro*/
1722 0, /*tp_as_buffer*/
1723 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1724 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001725 bufferedreader_doc, /* tp_doc */
1726 (traverseproc)buffered_traverse, /* tp_traverse */
1727 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001728 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001729 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001730 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001731 (iternextfunc)buffered_iternext, /* tp_iternext */
1732 bufferedreader_methods, /* tp_methods */
1733 bufferedreader_members, /* tp_members */
1734 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001735 0, /* tp_base */
1736 0, /* tp_dict */
1737 0, /* tp_descr_get */
1738 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001739 offsetof(buffered, dict), /* tp_dictoffset */
1740 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001741 0, /* tp_alloc */
1742 PyType_GenericNew, /* tp_new */
1743};
1744
1745
Benjamin Peterson59406a92009-03-26 17:10:29 +00001746
1747static int
1748complain_about_max_buffer_size(void)
1749{
1750 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1751 "max_buffer_size is deprecated", 1) < 0)
1752 return 0;
1753 return 1;
1754}
1755
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001756/*
1757 * class BufferedWriter
1758 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001759PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760 "A buffer for a writeable sequential RawIO object.\n"
1761 "\n"
1762 "The constructor creates a BufferedWriter for the given writeable raw\n"
1763 "stream. If the buffer_size is not given, it defaults to\n"
1764 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1765 );
1766
1767static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001768_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769{
1770 self->write_pos = 0;
1771 self->write_end = -1;
1772}
1773
1774static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001775bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776{
1777 /* TODO: properly deprecate max_buffer_size */
1778 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1779 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001780 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781 PyObject *raw;
1782
1783 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001784 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785
1786 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1787 &raw, &buffer_size, &max_buffer_size)) {
1788 return -1;
1789 }
1790
Benjamin Peterson59406a92009-03-26 17:10:29 +00001791 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1792 return -1;
1793
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001794 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 return -1;
1796
1797 Py_CLEAR(self->raw);
1798 Py_INCREF(raw);
1799 self->raw = raw;
1800 self->readable = 0;
1801 self->writable = 1;
1802
1803 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001804 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001806 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807 self->pos = 0;
1808
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001809 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1810 Py_TYPE(raw) == &PyFileIO_Type);
1811
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812 self->ok = 1;
1813 return 0;
1814}
1815
1816static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001817_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818{
1819 Py_buffer buf;
1820 PyObject *memobj, *res;
1821 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001822 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823 /* NOTE: the buffer needn't be released as its object is NULL. */
1824 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1825 return -1;
1826 memobj = PyMemoryView_FromBuffer(&buf);
1827 if (memobj == NULL)
1828 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001829 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1830 occurs so we needn't do it ourselves.
1831 We then retry writing, ignoring the signal if no handler has
1832 raised (see issue #10956).
1833 */
1834 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001835 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001836 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001837 errnum = errno;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001838 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001839 Py_DECREF(memobj);
1840 if (res == NULL)
1841 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001842 if (res == Py_None) {
1843 /* Non-blocking stream would have blocked. Special return code!
1844 Being paranoid we reset errno in case it is changed by code
1845 triggered by a decref. errno is used by _set_BlockingIOError(). */
1846 Py_DECREF(res);
1847 errno = errnum;
1848 return -2;
1849 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001850 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1851 Py_DECREF(res);
1852 if (n < 0 || n > len) {
1853 PyErr_Format(PyExc_IOError,
1854 "raw write() returned invalid length %zd "
1855 "(should have been between 0 and %zd)", n, len);
1856 return -1;
1857 }
1858 if (n > 0 && self->abs_pos != -1)
1859 self->abs_pos += n;
1860 return n;
1861}
1862
1863/* `restore_pos` is 1 if we need to restore the raw stream position at
1864 the end, 0 otherwise. */
1865static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001866_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001867{
1868 Py_ssize_t written = 0;
1869 Py_off_t n, rewind;
1870
1871 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1872 goto end;
1873 /* First, rewind */
1874 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1875 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001876 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001877 if (n < 0) {
1878 goto error;
1879 }
1880 self->raw_pos -= rewind;
1881 }
1882 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001883 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884 self->buffer + self->write_pos,
1885 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1886 Py_off_t, Py_ssize_t));
1887 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001888 goto error;
1889 }
1890 else if (n == -2) {
1891 _set_BlockingIOError("write could not complete without blocking",
1892 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001893 goto error;
1894 }
1895 self->write_pos += n;
1896 self->raw_pos = self->write_pos;
1897 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001898 /* Partial writes can return successfully when interrupted by a
1899 signal (see write(2)). We must run signal handlers before
1900 blocking another time, possibly indefinitely. */
1901 if (PyErr_CheckSignals() < 0)
1902 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001903 }
1904
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001905 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906
1907end:
1908 Py_RETURN_NONE;
1909
1910error:
1911 return NULL;
1912}
1913
1914static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001915bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916{
1917 PyObject *res = NULL;
1918 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001919 Py_ssize_t written, avail, remaining;
1920 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921
1922 CHECK_INITIALIZED(self)
1923 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1924 return NULL;
1925 }
1926
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001927 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928 PyErr_SetString(PyExc_ValueError, "write to closed file");
1929 PyBuffer_Release(&buf);
1930 return NULL;
1931 }
1932
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001933 if (!ENTER_BUFFERED(self)) {
1934 PyBuffer_Release(&buf);
1935 return NULL;
1936 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937
1938 /* Fast path: the data to write can be fully buffered. */
1939 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1940 self->pos = 0;
1941 self->raw_pos = 0;
1942 }
1943 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1944 if (buf.len <= avail) {
1945 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001946 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947 self->write_pos = self->pos;
1948 }
1949 ADJUST_POSITION(self, self->pos + buf.len);
1950 if (self->pos > self->write_end)
1951 self->write_end = self->pos;
1952 written = buf.len;
1953 goto end;
1954 }
1955
1956 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001957 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001959 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001960 if (w == NULL)
1961 goto error;
1962 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001963 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 /* Make some place by shifting the buffer. */
1965 assert(VALID_WRITE_BUFFER(self));
1966 memmove(self->buffer, self->buffer + self->write_pos,
1967 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1968 Py_off_t, Py_ssize_t));
1969 self->write_end -= self->write_pos;
1970 self->raw_pos -= self->write_pos;
1971 self->pos -= self->write_pos;
1972 self->write_pos = 0;
1973 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1974 Py_off_t, Py_ssize_t);
1975 if (buf.len <= avail) {
1976 /* Everything can be buffered */
1977 PyErr_Clear();
1978 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1979 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001980 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981 written = buf.len;
1982 goto end;
1983 }
1984 /* Buffer as much as possible. */
1985 memcpy(self->buffer + self->write_end, buf.buf, avail);
1986 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001987 self->pos += avail;
1988 /* XXX Modifying the existing exception e using the pointer w
1989 will change e.characters_written but not e.args[2].
1990 Therefore we just replace with a new error. */
1991 _set_BlockingIOError("write could not complete without blocking",
1992 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993 goto error;
1994 }
1995 Py_CLEAR(res);
1996
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001997 /* Adjust the raw stream position if it is away from the logical stream
1998 position. This happens if the read buffer has been filled but not
1999 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2000 the raw stream by itself).
2001 Fixes issue #6629.
2002 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002003 offset = RAW_OFFSET(self);
2004 if (offset != 0) {
2005 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002006 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002007 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002008 }
2009
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 /* Then write buf itself. At this point the buffer has been emptied. */
2011 remaining = buf.len;
2012 written = 0;
2013 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002014 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 self, (char *) buf.buf + written, buf.len - written);
2016 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002017 goto error;
2018 } else if (n == -2) {
2019 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 if (remaining > self->buffer_size) {
2021 /* Can't buffer everything, still buffer as much as possible */
2022 memcpy(self->buffer,
2023 (char *) buf.buf + written, self->buffer_size);
2024 self->raw_pos = 0;
2025 ADJUST_POSITION(self, self->buffer_size);
2026 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002027 written += self->buffer_size;
2028 _set_BlockingIOError("write could not complete without "
2029 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 goto error;
2031 }
2032 PyErr_Clear();
2033 break;
2034 }
2035 written += n;
2036 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002037 /* Partial writes can return successfully when interrupted by a
2038 signal (see write(2)). We must run signal handlers before
2039 blocking another time, possibly indefinitely. */
2040 if (PyErr_CheckSignals() < 0)
2041 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002042 }
2043 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002044 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002045 if (remaining > 0) {
2046 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2047 written += remaining;
2048 }
2049 self->write_pos = 0;
2050 /* TODO: sanity check (remaining >= 0) */
2051 self->write_end = remaining;
2052 ADJUST_POSITION(self, remaining);
2053 self->raw_pos = 0;
2054
2055end:
2056 res = PyLong_FromSsize_t(written);
2057
2058error:
2059 LEAVE_BUFFERED(self)
2060 PyBuffer_Release(&buf);
2061 return res;
2062}
2063
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002064static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002065 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002066 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2067 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2068 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2069 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2070 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2071 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2072 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002073 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002074 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002076 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2077 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2078 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2079 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2080 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 {NULL, NULL}
2082};
2083
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002084static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002085 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086 {NULL}
2087};
2088
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002089static PyGetSetDef bufferedwriter_getset[] = {
2090 {"closed", (getter)buffered_closed_get, NULL, NULL},
2091 {"name", (getter)buffered_name_get, NULL, NULL},
2092 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002093 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002094};
2095
2096
2097PyTypeObject PyBufferedWriter_Type = {
2098 PyVarObject_HEAD_INIT(NULL, 0)
2099 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002102 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002103 0, /*tp_print*/
2104 0, /*tp_getattr*/
2105 0, /*tp_setattr*/
2106 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002107 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108 0, /*tp_as_number*/
2109 0, /*tp_as_sequence*/
2110 0, /*tp_as_mapping*/
2111 0, /*tp_hash */
2112 0, /*tp_call*/
2113 0, /*tp_str*/
2114 0, /*tp_getattro*/
2115 0, /*tp_setattro*/
2116 0, /*tp_as_buffer*/
2117 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2118 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002119 bufferedwriter_doc, /* tp_doc */
2120 (traverseproc)buffered_traverse, /* tp_traverse */
2121 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002122 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124 0, /* tp_iter */
2125 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126 bufferedwriter_methods, /* tp_methods */
2127 bufferedwriter_members, /* tp_members */
2128 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002129 0, /* tp_base */
2130 0, /* tp_dict */
2131 0, /* tp_descr_get */
2132 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002133 offsetof(buffered, dict), /* tp_dictoffset */
2134 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002135 0, /* tp_alloc */
2136 PyType_GenericNew, /* tp_new */
2137};
2138
2139
2140
2141/*
2142 * BufferedRWPair
2143 */
2144
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002145PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002146 "A buffered reader and writer object together.\n"
2147 "\n"
2148 "A buffered reader object and buffered writer object put together to\n"
2149 "form a sequential IO object that can read and write. This is typically\n"
2150 "used with a socket or two-way pipe.\n"
2151 "\n"
2152 "reader and writer are RawIOBase objects that are readable and\n"
2153 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002154 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155 );
2156
2157/* XXX The usefulness of this (compared to having two separate IO objects) is
2158 * questionable.
2159 */
2160
2161typedef struct {
2162 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002163 buffered *reader;
2164 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165 PyObject *dict;
2166 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002167} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168
2169static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171{
2172 PyObject *reader, *writer;
2173 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002174 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175
2176 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2177 &buffer_size, &max_buffer_size)) {
2178 return -1;
2179 }
2180
Benjamin Peterson59406a92009-03-26 17:10:29 +00002181 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2182 return -1;
2183
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002185 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187 return -1;
2188
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002189 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002190 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191 if (self->reader == NULL)
2192 return -1;
2193
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002194 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002195 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002196 if (self->writer == NULL) {
2197 Py_CLEAR(self->reader);
2198 return -1;
2199 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002200
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201 return 0;
2202}
2203
2204static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002205bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002206{
2207 Py_VISIT(self->dict);
2208 return 0;
2209}
2210
2211static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002212bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213{
2214 Py_CLEAR(self->reader);
2215 Py_CLEAR(self->writer);
2216 Py_CLEAR(self->dict);
2217 return 0;
2218}
2219
2220static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002221bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222{
2223 _PyObject_GC_UNTRACK(self);
2224 Py_CLEAR(self->reader);
2225 Py_CLEAR(self->writer);
2226 Py_CLEAR(self->dict);
2227 Py_TYPE(self)->tp_free((PyObject *) self);
2228}
2229
2230static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002231_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002233 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234 PyObject *ret;
2235
2236 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002237 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238 return NULL;
2239 }
2240
2241 ret = PyObject_CallObject(func, args);
2242 Py_DECREF(func);
2243 return ret;
2244}
2245
2246static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002247bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002248{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002249 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250}
2251
2252static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002253bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002255 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002256}
2257
2258static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259bufferedrwpair_read1(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_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262}
2263
2264static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002266{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002267 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002268}
2269
2270static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002271bufferedrwpair_write(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->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002274}
2275
2276static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002277bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002278{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002279 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002280}
2281
2282static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002283bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002284{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002285 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286}
2287
2288static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289bufferedrwpair_writable(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_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002292}
2293
2294static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002295bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002297 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298 if (ret == NULL)
2299 return NULL;
2300 Py_DECREF(ret);
2301
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002302 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303}
2304
2305static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002306bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002308 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002309
2310 if (ret != Py_False) {
2311 /* either True or exception */
2312 return ret;
2313 }
2314 Py_DECREF(ret);
2315
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002316 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317}
2318
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002319static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002320bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002321{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002322 if (self->writer == NULL) {
2323 PyErr_SetString(PyExc_RuntimeError,
2324 "the BufferedRWPair object is being garbage-collected");
2325 return NULL;
2326 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002327 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2328}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002330static PyMethodDef bufferedrwpair_methods[] = {
2331 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2332 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2333 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2334 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002335
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002336 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2337 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002338
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2340 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002341
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002342 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2343 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002344
Antoine Pitrou243757e2010-11-05 21:15:39 +00002345 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2346
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347 {NULL, NULL}
2348};
2349
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002350static PyGetSetDef bufferedrwpair_getset[] = {
2351 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002352 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002353};
2354
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355PyTypeObject PyBufferedRWPair_Type = {
2356 PyVarObject_HEAD_INIT(NULL, 0)
2357 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002358 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002359 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002360 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361 0, /*tp_print*/
2362 0, /*tp_getattr*/
2363 0, /*tp_setattr*/
2364 0, /*tp_compare */
2365 0, /*tp_repr*/
2366 0, /*tp_as_number*/
2367 0, /*tp_as_sequence*/
2368 0, /*tp_as_mapping*/
2369 0, /*tp_hash */
2370 0, /*tp_call*/
2371 0, /*tp_str*/
2372 0, /*tp_getattro*/
2373 0, /*tp_setattro*/
2374 0, /*tp_as_buffer*/
2375 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2376 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002377 bufferedrwpair_doc, /* tp_doc */
2378 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2379 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002380 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002381 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002382 0, /* tp_iter */
2383 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002384 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002385 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002386 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002387 0, /* tp_base */
2388 0, /* tp_dict */
2389 0, /* tp_descr_get */
2390 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002391 offsetof(rwpair, dict), /* tp_dictoffset */
2392 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002393 0, /* tp_alloc */
2394 PyType_GenericNew, /* tp_new */
2395};
2396
2397
2398
2399/*
2400 * BufferedRandom
2401 */
2402
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002403PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002404 "A buffered interface to random access streams.\n"
2405 "\n"
2406 "The constructor creates a reader and writer for a seekable stream,\n"
2407 "raw, given in the first argument. If the buffer_size is omitted it\n"
2408 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2409 );
2410
2411static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002412bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002413{
2414 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2415 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002416 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002417 PyObject *raw;
2418
2419 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002420 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421
2422 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2423 &raw, &buffer_size, &max_buffer_size)) {
2424 return -1;
2425 }
2426
Benjamin Peterson59406a92009-03-26 17:10:29 +00002427 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2428 return -1;
2429
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002430 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002431 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002432 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002433 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002434 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002435 return -1;
2436
2437 Py_CLEAR(self->raw);
2438 Py_INCREF(raw);
2439 self->raw = raw;
2440 self->buffer_size = buffer_size;
2441 self->readable = 1;
2442 self->writable = 1;
2443
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002444 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002445 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002446 _bufferedreader_reset_buf(self);
2447 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002448 self->pos = 0;
2449
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002450 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2451 Py_TYPE(raw) == &PyFileIO_Type);
2452
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453 self->ok = 1;
2454 return 0;
2455}
2456
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002457static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2460 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2461 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2462 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2463 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2464 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2465 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002466 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002467 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002468
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002469 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002470
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002471 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2472 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2473 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2474 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2475 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2476 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2477 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2478 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2479 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002480 {NULL, NULL}
2481};
2482
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002483static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002484 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485 {NULL}
2486};
2487
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002488static PyGetSetDef bufferedrandom_getset[] = {
2489 {"closed", (getter)buffered_closed_get, NULL, NULL},
2490 {"name", (getter)buffered_name_get, NULL, NULL},
2491 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002492 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002493};
2494
2495
2496PyTypeObject PyBufferedRandom_Type = {
2497 PyVarObject_HEAD_INIT(NULL, 0)
2498 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002499 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002501 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002502 0, /*tp_print*/
2503 0, /*tp_getattr*/
2504 0, /*tp_setattr*/
2505 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002506 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507 0, /*tp_as_number*/
2508 0, /*tp_as_sequence*/
2509 0, /*tp_as_mapping*/
2510 0, /*tp_hash */
2511 0, /*tp_call*/
2512 0, /*tp_str*/
2513 0, /*tp_getattro*/
2514 0, /*tp_setattro*/
2515 0, /*tp_as_buffer*/
2516 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2517 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002518 bufferedrandom_doc, /* tp_doc */
2519 (traverseproc)buffered_traverse, /* tp_traverse */
2520 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002521 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002522 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002523 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002524 (iternextfunc)buffered_iternext, /* tp_iternext */
2525 bufferedrandom_methods, /* tp_methods */
2526 bufferedrandom_members, /* tp_members */
2527 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002528 0, /* tp_base */
2529 0, /*tp_dict*/
2530 0, /* tp_descr_get */
2531 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002532 offsetof(buffered, dict), /*tp_dictoffset*/
2533 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002534 0, /* tp_alloc */
2535 PyType_GenericNew, /* tp_new */
2536};