blob: 87fac7cfc757934e2aef04b16dc16cecd0192c67 [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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000599_bufferedwriter_flush_unlocked(buffered *, int);
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
621/* Returns the address of the `written` member if a BlockingIOError was
622 raised, NULL otherwise. The error is always re-raised. */
623static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000624_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000625{
626 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200627 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000628
629 PyErr_Fetch(&t, &v, &tb);
630 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
631 PyErr_Restore(t, v, tb);
632 return NULL;
633 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200634 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635 /* TODO: sanity check (err->written >= 0) */
636 PyErr_Restore(t, v, tb);
637 return &err->written;
638}
639
640static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000644 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000645 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
646 if (res == NULL)
647 return -1;
648 n = PyNumber_AsOff_t(res, PyExc_ValueError);
649 Py_DECREF(res);
650 if (n < 0) {
651 if (!PyErr_Occurred())
652 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000653 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200654 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655 return -1;
656 }
657 self->abs_pos = n;
658 return n;
659}
660
661static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000662_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000663{
664 PyObject *res, *posobj, *whenceobj;
665 Py_off_t n;
666
667 posobj = PyLong_FromOff_t(target);
668 if (posobj == NULL)
669 return -1;
670 whenceobj = PyLong_FromLong(whence);
671 if (whenceobj == NULL) {
672 Py_DECREF(posobj);
673 return -1;
674 }
675 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
676 posobj, whenceobj, NULL);
677 Py_DECREF(posobj);
678 Py_DECREF(whenceobj);
679 if (res == NULL)
680 return -1;
681 n = PyNumber_AsOff_t(res, PyExc_ValueError);
682 Py_DECREF(res);
683 if (n < 0) {
684 if (!PyErr_Occurred())
685 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000686 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200687 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688 return -1;
689 }
690 self->abs_pos = n;
691 return n;
692}
693
694static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000695_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696{
697 Py_ssize_t n;
698 if (self->buffer_size <= 0) {
699 PyErr_SetString(PyExc_ValueError,
700 "buffer size must be strictly positive");
701 return -1;
702 }
703 if (self->buffer)
704 PyMem_Free(self->buffer);
705 self->buffer = PyMem_Malloc(self->buffer_size);
706 if (self->buffer == NULL) {
707 PyErr_NoMemory();
708 return -1;
709 }
Georg Brandldfd73442009-04-05 11:47:34 +0000710#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000711 if (self->lock)
712 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000713 self->lock = PyThread_allocate_lock();
714 if (self->lock == NULL) {
715 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
716 return -1;
717 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000718 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000719#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000720 /* Find out whether buffer_size is a power of 2 */
721 /* XXX is this optimization useful? */
722 for (n = self->buffer_size - 1; n & 1; n >>= 1)
723 ;
724 if (n == 0)
725 self->buffer_mask = self->buffer_size - 1;
726 else
727 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000728 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000729 PyErr_Clear();
730 return 0;
731}
732
Antoine Pitrou707ce822011-02-25 21:24:11 +0000733/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
734 clears the error indicator), 0 otherwise.
735 Should only be called when PyErr_Occurred() is true.
736*/
737static int
738_trap_eintr(void)
739{
740 static PyObject *eintr_int = NULL;
741 PyObject *typ, *val, *tb;
742 PyEnvironmentErrorObject *env_err;
743
744 if (eintr_int == NULL) {
745 eintr_int = PyLong_FromLong(EINTR);
746 assert(eintr_int != NULL);
747 }
748 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
749 return 0;
750 PyErr_Fetch(&typ, &val, &tb);
751 PyErr_NormalizeException(&typ, &val, &tb);
752 env_err = (PyEnvironmentErrorObject *) val;
753 assert(env_err != NULL);
754 if (env_err->myerrno != NULL &&
755 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
756 Py_DECREF(typ);
757 Py_DECREF(val);
758 Py_XDECREF(tb);
759 return 1;
760 }
761 /* This silences any error set by PyObject_RichCompareBool() */
762 PyErr_Restore(typ, val, tb);
763 return 0;
764}
765
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766/*
767 * Shared methods and wrappers
768 */
769
770static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200771buffered_flush_and_rewind_unlocked(buffered *self)
772{
773 PyObject *res;
774
775 res = _bufferedwriter_flush_unlocked(self, 0);
776 if (res == NULL)
777 return NULL;
778 Py_DECREF(res);
779
780 if (self->readable) {
781 /* Rewind the raw stream so that its position corresponds to
782 the current logical position. */
783 Py_off_t n;
784 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
785 _bufferedreader_reset_buf(self);
786 if (n == -1)
787 return NULL;
788 }
789 Py_RETURN_NONE;
790}
791
792static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000793buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000794{
795 PyObject *res;
796
797 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000798 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000799
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000800 if (!ENTER_BUFFERED(self))
801 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200802 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000803 LEAVE_BUFFERED(self)
804
805 return res;
806}
807
808static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000809buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000810{
811 Py_ssize_t n = 0;
812 PyObject *res = NULL;
813
814 CHECK_INITIALIZED(self)
815 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
816 return NULL;
817 }
818
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000819 if (!ENTER_BUFFERED(self))
820 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000821
822 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200823 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000824 if (res == NULL)
825 goto end;
826 Py_CLEAR(res);
827 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200828 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000829
830end:
831 LEAVE_BUFFERED(self)
832 return res;
833}
834
835static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000836buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000837{
838 Py_ssize_t n = -1;
839 PyObject *res;
840
841 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000842 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843 return NULL;
844 }
845 if (n < -1) {
846 PyErr_SetString(PyExc_ValueError,
847 "read length must be positive or -1");
848 return NULL;
849 }
850
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000851 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000853 if (n == -1) {
854 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000855 if (!ENTER_BUFFERED(self))
856 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000857 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000858 }
859 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000860 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200861 if (res != Py_None)
862 return res;
863 Py_DECREF(res);
864 if (!ENTER_BUFFERED(self))
865 return NULL;
866 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000867 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868
Antoine Pitroue05565e2011-08-20 14:39:23 +0200869 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000870 return res;
871}
872
873static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000874buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875{
876 Py_ssize_t n, have, r;
877 PyObject *res = NULL;
878
879 CHECK_INITIALIZED(self)
880 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
881 return NULL;
882 }
883
884 if (n < 0) {
885 PyErr_SetString(PyExc_ValueError,
886 "read length must be positive");
887 return NULL;
888 }
889 if (n == 0)
890 return PyBytes_FromStringAndSize(NULL, 0);
891
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000892 if (!ENTER_BUFFERED(self))
893 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200894
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000895 /* Return up to n bytes. If at least one byte is buffered, we
896 only return buffered bytes. Otherwise, we do one raw read. */
897
898 /* XXX: this mimicks the io.py implementation but is probably wrong.
899 If we need to read from the raw stream, then we could actually read
900 all `n` bytes asked by the caller (and possibly more, so as to fill
901 our buffer for the next reads). */
902
903 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
904 if (have > 0) {
905 if (n > have)
906 n = have;
907 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
908 if (res == NULL)
909 goto end;
910 self->pos += n;
911 goto end;
912 }
913
Antoine Pitroue05565e2011-08-20 14:39:23 +0200914 if (self->writable) {
915 res = buffered_flush_and_rewind_unlocked(self);
916 if (res == NULL)
917 goto end;
918 Py_DECREF(res);
919 }
920
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000921 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000922 _bufferedreader_reset_buf(self);
923 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 if (r == -1)
925 goto end;
926 if (r == -2)
927 r = 0;
928 if (n > r)
929 n = r;
930 res = PyBytes_FromStringAndSize(self->buffer, n);
931 if (res == NULL)
932 goto end;
933 self->pos = n;
934
935end:
936 LEAVE_BUFFERED(self)
937 return res;
938}
939
940static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000941buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200943 Py_buffer buf;
944 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945 PyObject *res = NULL;
946
947 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200948
949 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
950 return NULL;
951
952 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
953 if (n > 0) {
954 if (n >= buf.len) {
955 memcpy(buf.buf, self->buffer + self->pos, buf.len);
956 self->pos += buf.len;
957 res = PyLong_FromSsize_t(buf.len);
958 goto end_unlocked;
959 }
960 memcpy(buf.buf, self->buffer + self->pos, n);
961 self->pos += n;
962 written = n;
963 }
964
965 if (!ENTER_BUFFERED(self))
966 goto end_unlocked;
967
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200969 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000970 if (res == NULL)
971 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200972 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000973 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200974
975 _bufferedreader_reset_buf(self);
976 self->pos = 0;
977
978 for (remaining = buf.len - written;
979 remaining > 0;
980 written += n, remaining -= n) {
981 /* If remaining bytes is larger than internal buffer size, copy
982 * directly into caller's buffer. */
983 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200984 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
985 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200986 }
987 else {
988 n = _bufferedreader_fill_buffer(self);
989 if (n > 0) {
990 if (n > remaining)
991 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200992 memcpy((char *) buf.buf + written,
993 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200994 self->pos += n;
995 continue; /* short circuit */
996 }
997 }
998 if (n == 0 || (n == -2 && written > 0))
999 break;
1000 if (n < 0) {
1001 if (n == -2) {
1002 Py_INCREF(Py_None);
1003 res = Py_None;
1004 }
1005 goto end;
1006 }
1007 }
1008 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001009
1010end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001011 LEAVE_BUFFERED(self);
1012end_unlocked:
1013 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014 return res;
1015}
1016
1017static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001018_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001019{
1020 PyObject *res = NULL;
1021 PyObject *chunks = NULL;
1022 Py_ssize_t n, written = 0;
1023 const char *start, *s, *end;
1024
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001025 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001026
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001027 /* First, try to find a line in the buffer. This can run unlocked because
1028 the calls to the C API are simple enough that they can't trigger
1029 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001030 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1031 if (limit >= 0 && n > limit)
1032 n = limit;
1033 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001034 s = memchr(start, '\n', n);
1035 if (s != NULL) {
1036 res = PyBytes_FromStringAndSize(start, s - start + 1);
1037 if (res != NULL)
1038 self->pos += s - start + 1;
1039 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001040 }
1041 if (n == limit) {
1042 res = PyBytes_FromStringAndSize(start, n);
1043 if (res != NULL)
1044 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001045 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046 }
1047
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001048 if (!ENTER_BUFFERED(self))
1049 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001050
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001051 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001052 chunks = PyList_New(0);
1053 if (chunks == NULL)
1054 goto end;
1055 if (n > 0) {
1056 res = PyBytes_FromStringAndSize(start, n);
1057 if (res == NULL)
1058 goto end;
1059 if (PyList_Append(chunks, res) < 0) {
1060 Py_CLEAR(res);
1061 goto end;
1062 }
1063 Py_CLEAR(res);
1064 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001065 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001066 if (limit >= 0)
1067 limit -= n;
1068 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001069 if (self->writable) {
1070 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1071 if (r == NULL)
1072 goto end;
1073 Py_DECREF(r);
1074 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075
1076 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001077 _bufferedreader_reset_buf(self);
1078 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079 if (n == -1)
1080 goto end;
1081 if (n <= 0)
1082 break;
1083 if (limit >= 0 && n > limit)
1084 n = limit;
1085 start = self->buffer;
1086 end = start + n;
1087 s = start;
1088 while (s < end) {
1089 if (*s++ == '\n') {
1090 res = PyBytes_FromStringAndSize(start, s - start);
1091 if (res == NULL)
1092 goto end;
1093 self->pos = s - start;
1094 goto found;
1095 }
1096 }
1097 res = PyBytes_FromStringAndSize(start, n);
1098 if (res == NULL)
1099 goto end;
1100 if (n == limit) {
1101 self->pos = n;
1102 break;
1103 }
1104 if (PyList_Append(chunks, res) < 0) {
1105 Py_CLEAR(res);
1106 goto end;
1107 }
1108 Py_CLEAR(res);
1109 written += n;
1110 if (limit >= 0)
1111 limit -= n;
1112 }
1113found:
1114 if (res != NULL && PyList_Append(chunks, res) < 0) {
1115 Py_CLEAR(res);
1116 goto end;
1117 }
1118 Py_CLEAR(res);
1119 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1120
1121end:
1122 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001123end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001124 Py_XDECREF(chunks);
1125 return res;
1126}
1127
1128static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001129buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001130{
1131 Py_ssize_t limit = -1;
1132
1133 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001134 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001135 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001136 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001137}
1138
1139
1140static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001141buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001142{
1143 Py_off_t pos;
1144
1145 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001146 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147 if (pos == -1)
1148 return NULL;
1149 pos -= RAW_OFFSET(self);
1150 /* TODO: sanity check (pos >= 0) */
1151 return PyLong_FromOff_t(pos);
1152}
1153
1154static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001155buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001156{
1157 Py_off_t target, n;
1158 int whence = 0;
1159 PyObject *targetobj, *res = NULL;
1160
1161 CHECK_INITIALIZED(self)
1162 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1163 return NULL;
1164 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001165 if (whence < 0 || whence > 2) {
1166 PyErr_Format(PyExc_ValueError,
1167 "whence must be between 0 and 2, not %d", whence);
1168 return NULL;
1169 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001170
1171 CHECK_CLOSED(self, "seek of closed file")
1172
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001173 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1174 return NULL;
1175
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1177 if (target == -1 && PyErr_Occurred())
1178 return NULL;
1179
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001180 if (whence != 2 && self->readable) {
1181 Py_off_t current, avail;
1182 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001183 so as to return quickly if possible. Also, we needn't take the
1184 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001186 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1187 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001188 current = RAW_TELL(self);
1189 avail = READAHEAD(self);
1190 if (avail > 0) {
1191 Py_off_t offset;
1192 if (whence == 0)
1193 offset = target - (current - RAW_OFFSET(self));
1194 else
1195 offset = target;
1196 if (offset >= -self->pos && offset <= avail) {
1197 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001198 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199 }
1200 }
1201 }
1202
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001203 if (!ENTER_BUFFERED(self))
1204 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001205
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206 /* Fallback: invoke raw seek() method and clear buffer */
1207 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001208 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209 if (res == NULL)
1210 goto end;
1211 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001212 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001213 }
1214
1215 /* TODO: align on block boundary and read buffer if needed? */
1216 if (whence == 1)
1217 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001218 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219 if (n == -1)
1220 goto end;
1221 self->raw_pos = -1;
1222 res = PyLong_FromOff_t(n);
1223 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001224 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225
1226end:
1227 LEAVE_BUFFERED(self)
1228 return res;
1229}
1230
1231static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001232buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001233{
1234 PyObject *pos = Py_None;
1235 PyObject *res = NULL;
1236
1237 CHECK_INITIALIZED(self)
1238 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1239 return NULL;
1240 }
1241
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001242 if (!ENTER_BUFFERED(self))
1243 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244
1245 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001246 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001247 if (res == NULL)
1248 goto end;
1249 Py_CLEAR(res);
1250 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1252 if (res == NULL)
1253 goto end;
1254 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001255 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 PyErr_Clear();
1257
1258end:
1259 LEAVE_BUFFERED(self)
1260 return res;
1261}
1262
1263static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001264buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265{
1266 PyObject *line;
1267 PyTypeObject *tp;
1268
1269 CHECK_INITIALIZED(self);
1270
1271 tp = Py_TYPE(self);
1272 if (tp == &PyBufferedReader_Type ||
1273 tp == &PyBufferedRandom_Type) {
1274 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001275 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001276 }
1277 else {
1278 line = PyObject_CallMethodObjArgs((PyObject *)self,
1279 _PyIO_str_readline, NULL);
1280 if (line && !PyBytes_Check(line)) {
1281 PyErr_Format(PyExc_IOError,
1282 "readline() should have returned a bytes object, "
1283 "not '%.200s'", Py_TYPE(line)->tp_name);
1284 Py_DECREF(line);
1285 return NULL;
1286 }
1287 }
1288
1289 if (line == NULL)
1290 return NULL;
1291
1292 if (PyBytes_GET_SIZE(line) == 0) {
1293 /* Reached EOF or would have blocked */
1294 Py_DECREF(line);
1295 return NULL;
1296 }
1297
1298 return line;
1299}
1300
Antoine Pitrou716c4442009-05-23 19:04:03 +00001301static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001302buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001303{
1304 PyObject *nameobj, *res;
1305
Martin v. Löwis767046a2011-10-14 15:35:36 +02001306 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001307 if (nameobj == NULL) {
1308 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1309 PyErr_Clear();
1310 else
1311 return NULL;
1312 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1313 }
1314 else {
1315 res = PyUnicode_FromFormat("<%s name=%R>",
1316 Py_TYPE(self)->tp_name, nameobj);
1317 Py_DECREF(nameobj);
1318 }
1319 return res;
1320}
1321
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322/*
1323 * class BufferedReader
1324 */
1325
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001326PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001327 "Create a new buffered reader using the given readable raw IO object.");
1328
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001329static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330{
1331 self->read_end = -1;
1332}
1333
1334static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001335bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336{
1337 char *kwlist[] = {"raw", "buffer_size", NULL};
1338 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1339 PyObject *raw;
1340
1341 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001342 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343
1344 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1345 &raw, &buffer_size)) {
1346 return -1;
1347 }
1348
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001349 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350 return -1;
1351
1352 Py_CLEAR(self->raw);
1353 Py_INCREF(raw);
1354 self->raw = raw;
1355 self->buffer_size = buffer_size;
1356 self->readable = 1;
1357 self->writable = 0;
1358
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001359 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001361 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001363 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1364 Py_TYPE(raw) == &PyFileIO_Type);
1365
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001366 self->ok = 1;
1367 return 0;
1368}
1369
1370static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372{
1373 Py_buffer buf;
1374 PyObject *memobj, *res;
1375 Py_ssize_t n;
1376 /* NOTE: the buffer needn't be released as its object is NULL. */
1377 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1378 return -1;
1379 memobj = PyMemoryView_FromBuffer(&buf);
1380 if (memobj == NULL)
1381 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001382 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1383 occurs so we needn't do it ourselves.
1384 We then retry reading, ignoring the signal if no handler has
1385 raised (see issue #10956).
1386 */
1387 do {
1388 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1389 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001390 Py_DECREF(memobj);
1391 if (res == NULL)
1392 return -1;
1393 if (res == Py_None) {
1394 /* Non-blocking stream would have blocked. Special return code! */
1395 Py_DECREF(res);
1396 return -2;
1397 }
1398 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1399 Py_DECREF(res);
1400 if (n < 0 || n > len) {
1401 PyErr_Format(PyExc_IOError,
1402 "raw readinto() returned invalid length %zd "
1403 "(should have been between 0 and %zd)", n, len);
1404 return -1;
1405 }
1406 if (n > 0 && self->abs_pos != -1)
1407 self->abs_pos += n;
1408 return n;
1409}
1410
1411static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001412_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001413{
1414 Py_ssize_t start, len, n;
1415 if (VALID_READ_BUFFER(self))
1416 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1417 else
1418 start = 0;
1419 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001420 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001421 if (n <= 0)
1422 return n;
1423 self->read_end = start + n;
1424 self->raw_pos = start + n;
1425 return n;
1426}
1427
1428static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001429_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001430{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001431 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001432 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001433
1434 /* First copy what we have in the current buffer. */
1435 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1436 if (current_size) {
1437 data = PyBytes_FromStringAndSize(
1438 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001439 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001441 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001442 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001443 /* We're going past the buffer's bounds, flush it */
1444 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001445 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001446 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001447 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001448 Py_CLEAR(res);
1449 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001450 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001451
1452 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1453 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1454 if (chunk == NULL)
1455 return NULL;
1456 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1457 Py_XDECREF(data);
1458 Py_DECREF(chunk);
1459 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1460 return NULL;
1461 }
1462 if (chunk == Py_None) {
1463 if (current_size == 0)
1464 return chunk;
1465 else {
1466 Py_DECREF(chunk);
1467 return data;
1468 }
1469 }
1470 else if (current_size) {
1471 PyBytes_Concat(&data, chunk);
1472 Py_DECREF(chunk);
1473 if (data == NULL)
1474 return NULL;
1475 return data;
1476 } else
1477 return chunk;
1478 }
1479
1480 chunks = PyList_New(0);
1481 if (chunks == NULL)
1482 return NULL;
1483
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001484 while (1) {
1485 if (data) {
1486 if (PyList_Append(chunks, data) < 0) {
1487 Py_DECREF(data);
1488 Py_DECREF(chunks);
1489 return NULL;
1490 }
1491 Py_DECREF(data);
1492 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001493
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001494 /* Read until EOF or until read() would block. */
1495 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1496 if (data == NULL) {
1497 Py_DECREF(chunks);
1498 return NULL;
1499 }
1500 if (data != Py_None && !PyBytes_Check(data)) {
1501 Py_DECREF(data);
1502 Py_DECREF(chunks);
1503 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1504 return NULL;
1505 }
1506 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1507 if (current_size == 0) {
1508 Py_DECREF(chunks);
1509 return data;
1510 }
1511 else {
1512 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1513 Py_DECREF(data);
1514 Py_DECREF(chunks);
1515 return res;
1516 }
1517 }
1518 current_size += PyBytes_GET_SIZE(data);
1519 if (self->abs_pos != -1)
1520 self->abs_pos += PyBytes_GET_SIZE(data);
1521 }
1522}
1523
1524/* Read n bytes from the buffer if it can, otherwise return None.
1525 This function is simple enough that it can run unlocked. */
1526static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001527_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001528{
1529 Py_ssize_t current_size;
1530
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001531 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1532 if (n <= current_size) {
1533 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001534 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1535 if (res != NULL)
1536 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 return res;
1538 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001539 Py_RETURN_NONE;
1540}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001541
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001542/* Generic read function: read from the stream until enough bytes are read,
1543 * or until an EOF occurs or until read() would block.
1544 */
1545static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001546_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001547{
1548 PyObject *res = NULL;
1549 Py_ssize_t current_size, remaining, written;
1550 char *out;
1551
1552 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1553 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001554 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001555
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001556 res = PyBytes_FromStringAndSize(NULL, n);
1557 if (res == NULL)
1558 goto error;
1559 out = PyBytes_AS_STRING(res);
1560 remaining = n;
1561 written = 0;
1562 if (current_size > 0) {
1563 memcpy(out, self->buffer + self->pos, current_size);
1564 remaining -= current_size;
1565 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001566 self->pos += current_size;
1567 }
1568 /* Flush the write buffer if necessary */
1569 if (self->writable) {
1570 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1571 if (r == NULL)
1572 goto error;
1573 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001574 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001575 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001576 while (remaining > 0) {
1577 /* We want to read a whole block at the end into buffer.
1578 If we had readv() we could do this in one pass. */
1579 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1580 if (r == 0)
1581 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001582 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001583 if (r == -1)
1584 goto error;
1585 if (r == 0 || r == -2) {
1586 /* EOF occurred or read() would block. */
1587 if (r == 0 || written > 0) {
1588 if (_PyBytes_Resize(&res, written))
1589 goto error;
1590 return res;
1591 }
1592 Py_DECREF(res);
1593 Py_INCREF(Py_None);
1594 return Py_None;
1595 }
1596 remaining -= r;
1597 written += r;
1598 }
1599 assert(remaining <= self->buffer_size);
1600 self->pos = 0;
1601 self->raw_pos = 0;
1602 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001603 /* NOTE: when the read is satisfied, we avoid issuing any additional
1604 reads, which could block indefinitely (e.g. on a socket).
1605 See issue #9550. */
1606 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001607 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001608 if (r == -1)
1609 goto error;
1610 if (r == 0 || r == -2) {
1611 /* EOF occurred or read() would block. */
1612 if (r == 0 || written > 0) {
1613 if (_PyBytes_Resize(&res, written))
1614 goto error;
1615 return res;
1616 }
1617 Py_DECREF(res);
1618 Py_INCREF(Py_None);
1619 return Py_None;
1620 }
1621 if (remaining > r) {
1622 memcpy(out + written, self->buffer + self->pos, r);
1623 written += r;
1624 self->pos += r;
1625 remaining -= r;
1626 }
1627 else if (remaining > 0) {
1628 memcpy(out + written, self->buffer + self->pos, remaining);
1629 written += remaining;
1630 self->pos += remaining;
1631 remaining = 0;
1632 }
1633 if (remaining == 0)
1634 break;
1635 }
1636
1637 return res;
1638
1639error:
1640 Py_XDECREF(res);
1641 return NULL;
1642}
1643
1644static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001645_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001646{
1647 Py_ssize_t have, r;
1648
1649 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1650 /* Constraints:
1651 1. we don't want to advance the file position.
1652 2. we don't want to lose block alignment, so we can't shift the buffer
1653 to make some place.
1654 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1655 */
1656 if (have > 0) {
1657 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1658 }
1659
1660 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001661 _bufferedreader_reset_buf(self);
1662 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001663 if (r == -1)
1664 return NULL;
1665 if (r == -2)
1666 r = 0;
1667 self->pos = 0;
1668 return PyBytes_FromStringAndSize(self->buffer, r);
1669}
1670
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001671static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001672 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001673 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1674 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1675 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1676 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1677 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1678 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1679 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1680 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001681 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001682 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001684 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1685 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1686 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001687 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001688 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1689 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1690 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1691 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001692 {NULL, NULL}
1693};
1694
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001695static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001696 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001697 {NULL}
1698};
1699
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001700static PyGetSetDef bufferedreader_getset[] = {
1701 {"closed", (getter)buffered_closed_get, NULL, NULL},
1702 {"name", (getter)buffered_name_get, NULL, NULL},
1703 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001704 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001705};
1706
1707
1708PyTypeObject PyBufferedReader_Type = {
1709 PyVarObject_HEAD_INIT(NULL, 0)
1710 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001711 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001712 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001713 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001714 0, /*tp_print*/
1715 0, /*tp_getattr*/
1716 0, /*tp_setattr*/
1717 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001718 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719 0, /*tp_as_number*/
1720 0, /*tp_as_sequence*/
1721 0, /*tp_as_mapping*/
1722 0, /*tp_hash */
1723 0, /*tp_call*/
1724 0, /*tp_str*/
1725 0, /*tp_getattro*/
1726 0, /*tp_setattro*/
1727 0, /*tp_as_buffer*/
1728 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1729 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001730 bufferedreader_doc, /* tp_doc */
1731 (traverseproc)buffered_traverse, /* tp_traverse */
1732 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001733 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001734 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001735 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001736 (iternextfunc)buffered_iternext, /* tp_iternext */
1737 bufferedreader_methods, /* tp_methods */
1738 bufferedreader_members, /* tp_members */
1739 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001740 0, /* tp_base */
1741 0, /* tp_dict */
1742 0, /* tp_descr_get */
1743 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001744 offsetof(buffered, dict), /* tp_dictoffset */
1745 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746 0, /* tp_alloc */
1747 PyType_GenericNew, /* tp_new */
1748};
1749
1750
Benjamin Peterson59406a92009-03-26 17:10:29 +00001751
1752static int
1753complain_about_max_buffer_size(void)
1754{
1755 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1756 "max_buffer_size is deprecated", 1) < 0)
1757 return 0;
1758 return 1;
1759}
1760
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761/*
1762 * class BufferedWriter
1763 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001764PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001765 "A buffer for a writeable sequential RawIO object.\n"
1766 "\n"
1767 "The constructor creates a BufferedWriter for the given writeable raw\n"
1768 "stream. If the buffer_size is not given, it defaults to\n"
1769 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1770 );
1771
1772static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001773_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774{
1775 self->write_pos = 0;
1776 self->write_end = -1;
1777}
1778
1779static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001780bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781{
1782 /* TODO: properly deprecate max_buffer_size */
1783 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1784 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001785 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 PyObject *raw;
1787
1788 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001789 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790
1791 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1792 &raw, &buffer_size, &max_buffer_size)) {
1793 return -1;
1794 }
1795
Benjamin Peterson59406a92009-03-26 17:10:29 +00001796 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1797 return -1;
1798
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 return -1;
1801
1802 Py_CLEAR(self->raw);
1803 Py_INCREF(raw);
1804 self->raw = raw;
1805 self->readable = 0;
1806 self->writable = 1;
1807
1808 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001811 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812 self->pos = 0;
1813
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001814 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1815 Py_TYPE(raw) == &PyFileIO_Type);
1816
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001817 self->ok = 1;
1818 return 0;
1819}
1820
1821static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001822_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823{
1824 Py_buffer buf;
1825 PyObject *memobj, *res;
1826 Py_ssize_t n;
1827 /* NOTE: the buffer needn't be released as its object is NULL. */
1828 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1829 return -1;
1830 memobj = PyMemoryView_FromBuffer(&buf);
1831 if (memobj == NULL)
1832 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001833 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1834 occurs so we needn't do it ourselves.
1835 We then retry writing, ignoring the signal if no handler has
1836 raised (see issue #10956).
1837 */
1838 do {
1839 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1840 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841 Py_DECREF(memobj);
1842 if (res == NULL)
1843 return -1;
1844 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1845 Py_DECREF(res);
1846 if (n < 0 || n > len) {
1847 PyErr_Format(PyExc_IOError,
1848 "raw write() returned invalid length %zd "
1849 "(should have been between 0 and %zd)", n, len);
1850 return -1;
1851 }
1852 if (n > 0 && self->abs_pos != -1)
1853 self->abs_pos += n;
1854 return n;
1855}
1856
1857/* `restore_pos` is 1 if we need to restore the raw stream position at
1858 the end, 0 otherwise. */
1859static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001860_bufferedwriter_flush_unlocked(buffered *self, int restore_pos)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001861{
1862 Py_ssize_t written = 0;
1863 Py_off_t n, rewind;
1864
1865 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1866 goto end;
1867 /* First, rewind */
1868 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1869 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001870 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001871 if (n < 0) {
1872 goto error;
1873 }
1874 self->raw_pos -= rewind;
1875 }
1876 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001877 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001878 self->buffer + self->write_pos,
1879 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1880 Py_off_t, Py_ssize_t));
1881 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001882 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001883 if (w == NULL)
1884 goto error;
1885 self->write_pos += *w;
1886 self->raw_pos = self->write_pos;
1887 written += *w;
1888 *w = written;
1889 /* Already re-raised */
1890 goto error;
1891 }
1892 self->write_pos += n;
1893 self->raw_pos = self->write_pos;
1894 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001895 /* Partial writes can return successfully when interrupted by a
1896 signal (see write(2)). We must run signal handlers before
1897 blocking another time, possibly indefinitely. */
1898 if (PyErr_CheckSignals() < 0)
1899 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900 }
1901
1902 if (restore_pos) {
1903 Py_off_t forward = rewind - written;
1904 if (forward != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001905 n = _buffered_raw_seek(self, forward, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906 if (n < 0) {
1907 goto error;
1908 }
1909 self->raw_pos += forward;
1910 }
1911 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001912 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913
1914end:
1915 Py_RETURN_NONE;
1916
1917error:
1918 return NULL;
1919}
1920
1921static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001922bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923{
1924 PyObject *res = NULL;
1925 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001926 Py_ssize_t written, avail, remaining;
1927 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928
1929 CHECK_INITIALIZED(self)
1930 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1931 return NULL;
1932 }
1933
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001934 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935 PyErr_SetString(PyExc_ValueError, "write to closed file");
1936 PyBuffer_Release(&buf);
1937 return NULL;
1938 }
1939
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001940 if (!ENTER_BUFFERED(self)) {
1941 PyBuffer_Release(&buf);
1942 return NULL;
1943 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944
1945 /* Fast path: the data to write can be fully buffered. */
1946 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1947 self->pos = 0;
1948 self->raw_pos = 0;
1949 }
1950 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1951 if (buf.len <= avail) {
1952 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001953 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 self->write_pos = self->pos;
1955 }
1956 ADJUST_POSITION(self, self->pos + buf.len);
1957 if (self->pos > self->write_end)
1958 self->write_end = self->pos;
1959 written = buf.len;
1960 goto end;
1961 }
1962
1963 /* First write the current buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001964 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001966 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 if (w == NULL)
1968 goto error;
1969 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001970 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001971 /* Make some place by shifting the buffer. */
1972 assert(VALID_WRITE_BUFFER(self));
1973 memmove(self->buffer, self->buffer + self->write_pos,
1974 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1975 Py_off_t, Py_ssize_t));
1976 self->write_end -= self->write_pos;
1977 self->raw_pos -= self->write_pos;
1978 self->pos -= self->write_pos;
1979 self->write_pos = 0;
1980 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1981 Py_off_t, Py_ssize_t);
1982 if (buf.len <= avail) {
1983 /* Everything can be buffered */
1984 PyErr_Clear();
1985 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1986 self->write_end += buf.len;
1987 written = buf.len;
1988 goto end;
1989 }
1990 /* Buffer as much as possible. */
1991 memcpy(self->buffer + self->write_end, buf.buf, avail);
1992 self->write_end += avail;
1993 /* Already re-raised */
1994 *w = avail;
1995 goto error;
1996 }
1997 Py_CLEAR(res);
1998
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001999 /* Adjust the raw stream position if it is away from the logical stream
2000 position. This happens if the read buffer has been filled but not
2001 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2002 the raw stream by itself).
2003 Fixes issue #6629.
2004 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002005 offset = RAW_OFFSET(self);
2006 if (offset != 0) {
2007 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002008 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002009 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002010 }
2011
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 /* Then write buf itself. At this point the buffer has been emptied. */
2013 remaining = buf.len;
2014 written = 0;
2015 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002016 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 self, (char *) buf.buf + written, buf.len - written);
2018 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002019 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 if (w == NULL)
2021 goto error;
2022 written += *w;
2023 remaining -= *w;
2024 if (remaining > self->buffer_size) {
2025 /* Can't buffer everything, still buffer as much as possible */
2026 memcpy(self->buffer,
2027 (char *) buf.buf + written, self->buffer_size);
2028 self->raw_pos = 0;
2029 ADJUST_POSITION(self, self->buffer_size);
2030 self->write_end = self->buffer_size;
2031 *w = written + self->buffer_size;
2032 /* Already re-raised */
2033 goto error;
2034 }
2035 PyErr_Clear();
2036 break;
2037 }
2038 written += n;
2039 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002040 /* Partial writes can return successfully when interrupted by a
2041 signal (see write(2)). We must run signal handlers before
2042 blocking another time, possibly indefinitely. */
2043 if (PyErr_CheckSignals() < 0)
2044 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002045 }
2046 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002047 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048 if (remaining > 0) {
2049 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2050 written += remaining;
2051 }
2052 self->write_pos = 0;
2053 /* TODO: sanity check (remaining >= 0) */
2054 self->write_end = remaining;
2055 ADJUST_POSITION(self, remaining);
2056 self->raw_pos = 0;
2057
2058end:
2059 res = PyLong_FromSsize_t(written);
2060
2061error:
2062 LEAVE_BUFFERED(self)
2063 PyBuffer_Release(&buf);
2064 return res;
2065}
2066
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002067static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002069 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2070 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2071 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2072 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2073 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2074 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2075 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002076 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002077 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002079 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2080 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2081 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2082 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2083 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002084 {NULL, NULL}
2085};
2086
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002087static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002088 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002089 {NULL}
2090};
2091
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002092static PyGetSetDef bufferedwriter_getset[] = {
2093 {"closed", (getter)buffered_closed_get, NULL, NULL},
2094 {"name", (getter)buffered_name_get, NULL, NULL},
2095 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002096 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097};
2098
2099
2100PyTypeObject PyBufferedWriter_Type = {
2101 PyVarObject_HEAD_INIT(NULL, 0)
2102 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106 0, /*tp_print*/
2107 0, /*tp_getattr*/
2108 0, /*tp_setattr*/
2109 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 0, /*tp_as_number*/
2112 0, /*tp_as_sequence*/
2113 0, /*tp_as_mapping*/
2114 0, /*tp_hash */
2115 0, /*tp_call*/
2116 0, /*tp_str*/
2117 0, /*tp_getattro*/
2118 0, /*tp_setattro*/
2119 0, /*tp_as_buffer*/
2120 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2121 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002122 bufferedwriter_doc, /* tp_doc */
2123 (traverseproc)buffered_traverse, /* tp_traverse */
2124 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002125 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002127 0, /* tp_iter */
2128 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129 bufferedwriter_methods, /* tp_methods */
2130 bufferedwriter_members, /* tp_members */
2131 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002132 0, /* tp_base */
2133 0, /* tp_dict */
2134 0, /* tp_descr_get */
2135 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002136 offsetof(buffered, dict), /* tp_dictoffset */
2137 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138 0, /* tp_alloc */
2139 PyType_GenericNew, /* tp_new */
2140};
2141
2142
2143
2144/*
2145 * BufferedRWPair
2146 */
2147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002148PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149 "A buffered reader and writer object together.\n"
2150 "\n"
2151 "A buffered reader object and buffered writer object put together to\n"
2152 "form a sequential IO object that can read and write. This is typically\n"
2153 "used with a socket or two-way pipe.\n"
2154 "\n"
2155 "reader and writer are RawIOBase objects that are readable and\n"
2156 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002157 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002158 );
2159
2160/* XXX The usefulness of this (compared to having two separate IO objects) is
2161 * questionable.
2162 */
2163
2164typedef struct {
2165 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002166 buffered *reader;
2167 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168 PyObject *dict;
2169 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171
2172static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002173bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002174{
2175 PyObject *reader, *writer;
2176 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002177 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178
2179 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2180 &buffer_size, &max_buffer_size)) {
2181 return -1;
2182 }
2183
Benjamin Peterson59406a92009-03-26 17:10:29 +00002184 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2185 return -1;
2186
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002189 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002190 return -1;
2191
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002193 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194 if (self->reader == NULL)
2195 return -1;
2196
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002197 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002198 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199 if (self->writer == NULL) {
2200 Py_CLEAR(self->reader);
2201 return -1;
2202 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002203
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002204 return 0;
2205}
2206
2207static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002208bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209{
2210 Py_VISIT(self->dict);
2211 return 0;
2212}
2213
2214static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002215bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216{
2217 Py_CLEAR(self->reader);
2218 Py_CLEAR(self->writer);
2219 Py_CLEAR(self->dict);
2220 return 0;
2221}
2222
2223static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225{
2226 _PyObject_GC_UNTRACK(self);
2227 Py_CLEAR(self->reader);
2228 Py_CLEAR(self->writer);
2229 Py_CLEAR(self->dict);
2230 Py_TYPE(self)->tp_free((PyObject *) self);
2231}
2232
2233static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002234_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002236 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237 PyObject *ret;
2238
2239 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002240 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002241 return NULL;
2242 }
2243
2244 ret = PyObject_CallObject(func, args);
2245 Py_DECREF(func);
2246 return ret;
2247}
2248
2249static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002252 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002253}
2254
2255static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002256bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002257{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002258 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259}
2260
2261static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002264 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265}
2266
2267static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002268bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002269{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002270 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002271}
2272
2273static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002274bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002275{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002276 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277}
2278
2279static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002280bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002282 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002283}
2284
2285static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002286bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002287{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002288 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289}
2290
2291static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002292bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002294 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002295}
2296
2297static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002298bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002300 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002301 if (ret == NULL)
2302 return NULL;
2303 Py_DECREF(ret);
2304
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002305 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002306}
2307
2308static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002309bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002310{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002311 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312
2313 if (ret != Py_False) {
2314 /* either True or exception */
2315 return ret;
2316 }
2317 Py_DECREF(ret);
2318
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002319 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002320}
2321
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002322static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002323bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002324{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002325 if (self->writer == NULL) {
2326 PyErr_SetString(PyExc_RuntimeError,
2327 "the BufferedRWPair object is being garbage-collected");
2328 return NULL;
2329 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002330 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2331}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002332
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002333static PyMethodDef bufferedrwpair_methods[] = {
2334 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2335 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2336 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2337 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002338
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2340 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002341
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002342 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2343 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002344
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002345 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2346 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347
Antoine Pitrou243757e2010-11-05 21:15:39 +00002348 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2349
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002350 {NULL, NULL}
2351};
2352
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002353static PyGetSetDef bufferedrwpair_getset[] = {
2354 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002355 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002356};
2357
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002358PyTypeObject PyBufferedRWPair_Type = {
2359 PyVarObject_HEAD_INIT(NULL, 0)
2360 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002361 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002362 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002363 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002364 0, /*tp_print*/
2365 0, /*tp_getattr*/
2366 0, /*tp_setattr*/
2367 0, /*tp_compare */
2368 0, /*tp_repr*/
2369 0, /*tp_as_number*/
2370 0, /*tp_as_sequence*/
2371 0, /*tp_as_mapping*/
2372 0, /*tp_hash */
2373 0, /*tp_call*/
2374 0, /*tp_str*/
2375 0, /*tp_getattro*/
2376 0, /*tp_setattro*/
2377 0, /*tp_as_buffer*/
2378 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2379 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002380 bufferedrwpair_doc, /* tp_doc */
2381 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2382 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002383 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002384 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002385 0, /* tp_iter */
2386 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002387 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002389 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002390 0, /* tp_base */
2391 0, /* tp_dict */
2392 0, /* tp_descr_get */
2393 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002394 offsetof(rwpair, dict), /* tp_dictoffset */
2395 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002396 0, /* tp_alloc */
2397 PyType_GenericNew, /* tp_new */
2398};
2399
2400
2401
2402/*
2403 * BufferedRandom
2404 */
2405
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002406PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002407 "A buffered interface to random access streams.\n"
2408 "\n"
2409 "The constructor creates a reader and writer for a seekable stream,\n"
2410 "raw, given in the first argument. If the buffer_size is omitted it\n"
2411 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2412 );
2413
2414static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002415bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002416{
2417 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2418 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002419 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 PyObject *raw;
2421
2422 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002423 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002424
2425 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2426 &raw, &buffer_size, &max_buffer_size)) {
2427 return -1;
2428 }
2429
Benjamin Peterson59406a92009-03-26 17:10:29 +00002430 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2431 return -1;
2432
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002433 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002434 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002435 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002437 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002438 return -1;
2439
2440 Py_CLEAR(self->raw);
2441 Py_INCREF(raw);
2442 self->raw = raw;
2443 self->buffer_size = buffer_size;
2444 self->readable = 1;
2445 self->writable = 1;
2446
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002447 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002448 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002449 _bufferedreader_reset_buf(self);
2450 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002451 self->pos = 0;
2452
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002453 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2454 Py_TYPE(raw) == &PyFileIO_Type);
2455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 self->ok = 1;
2457 return 0;
2458}
2459
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002460static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002462 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2463 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2464 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2465 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2466 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2467 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2468 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002469 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002470 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002471
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002472 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002473
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002474 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2475 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2476 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2477 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2478 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2479 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2480 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2481 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2482 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002483 {NULL, NULL}
2484};
2485
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002486static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002487 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002488 {NULL}
2489};
2490
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002491static PyGetSetDef bufferedrandom_getset[] = {
2492 {"closed", (getter)buffered_closed_get, NULL, NULL},
2493 {"name", (getter)buffered_name_get, NULL, NULL},
2494 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002495 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002496};
2497
2498
2499PyTypeObject PyBufferedRandom_Type = {
2500 PyVarObject_HEAD_INIT(NULL, 0)
2501 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002502 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002503 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002504 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002505 0, /*tp_print*/
2506 0, /*tp_getattr*/
2507 0, /*tp_setattr*/
2508 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002509 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002510 0, /*tp_as_number*/
2511 0, /*tp_as_sequence*/
2512 0, /*tp_as_mapping*/
2513 0, /*tp_hash */
2514 0, /*tp_call*/
2515 0, /*tp_str*/
2516 0, /*tp_getattro*/
2517 0, /*tp_setattro*/
2518 0, /*tp_as_buffer*/
2519 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2520 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002521 bufferedrandom_doc, /* tp_doc */
2522 (traverseproc)buffered_traverse, /* tp_traverse */
2523 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002524 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002525 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002526 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002527 (iternextfunc)buffered_iternext, /* tp_iternext */
2528 bufferedrandom_methods, /* tp_methods */
2529 bufferedrandom_members, /* tp_members */
2530 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002531 0, /* tp_base */
2532 0, /*tp_dict*/
2533 0, /* tp_descr_get */
2534 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002535 offsetof(buffered, dict), /*tp_dictoffset*/
2536 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 0, /* tp_alloc */
2538 PyType_GenericNew, /* tp_new */
2539};