blob: 6ef2c206a239d9f95378f0e878868143da35e6ec [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öwisafe55bb2011-10-09 10:38:36 +020016_Py_identifier(close);
17_Py_identifier(_dealloc_warn);
18_Py_identifier(flush);
19_Py_identifier(isatty);
20_Py_identifier(peek);
21_Py_identifier(read);
22_Py_identifier(read1);
23_Py_identifier(readable);
24_Py_identifier(readinto);
25_Py_identifier(writable);
26_Py_identifier(write);
27
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000028/*
29 * BufferedIOBase class, inherits from IOBase.
30 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000031PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000032 "Base class for buffered IO objects.\n"
33 "\n"
34 "The main difference with RawIOBase is that the read() method\n"
35 "supports omitting the size argument, and does not have a default\n"
36 "implementation that defers to readinto().\n"
37 "\n"
38 "In addition, read(), readinto() and write() may raise\n"
39 "BlockingIOError if the underlying raw stream is in non-blocking\n"
40 "mode and not ready; unlike their raw counterparts, they will never\n"
41 "return None.\n"
42 "\n"
43 "A typical implementation should not inherit from a RawIOBase\n"
44 "implementation, but wrap one.\n"
45 );
46
47static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000048bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000049{
50 Py_buffer buf;
51 Py_ssize_t len;
52 PyObject *data;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020053 _Py_identifier(read);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000054
55 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
56 return NULL;
57 }
58
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020059 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000060 if (data == NULL)
61 goto error;
62
63 if (!PyBytes_Check(data)) {
64 Py_DECREF(data);
65 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
66 goto error;
67 }
68
69 len = Py_SIZE(data);
70 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
71
72 PyBuffer_Release(&buf);
73 Py_DECREF(data);
74
75 return PyLong_FromSsize_t(len);
76
77 error:
78 PyBuffer_Release(&buf);
79 return NULL;
80}
81
82static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000083bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000084{
85 PyErr_SetString(IO_STATE->unsupported_operation, message);
86 return NULL;
87}
88
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000089PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000090 "Disconnect this buffer from its underlying raw stream and return it.\n"
91 "\n"
92 "After the raw stream has been detached, the buffer is in an unusable\n"
93 "state.\n");
94
95static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000096bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +000097{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000098 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +000099}
100
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000101PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000102 "Read and return up to n bytes.\n"
103 "\n"
104 "If the argument is omitted, None, or negative, reads and\n"
105 "returns all data until EOF.\n"
106 "\n"
107 "If the argument is positive, and the underlying raw stream is\n"
108 "not 'interactive', multiple raw reads may be issued to satisfy\n"
109 "the byte count (unless EOF is reached first). But for\n"
110 "interactive raw streams (as well as sockets and pipes), at most\n"
111 "one raw read will be issued, and a short result does not imply\n"
112 "that EOF is imminent.\n"
113 "\n"
114 "Returns an empty bytes object on EOF.\n"
115 "\n"
116 "Returns None if the underlying raw stream was open in non-blocking\n"
117 "mode and no data is available at the moment.\n");
118
119static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000120bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000121{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123}
124
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000125PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000126 "Read and return up to n bytes, with at most one read() call\n"
127 "to the underlying raw stream. A short result does not imply\n"
128 "that EOF is imminent.\n"
129 "\n"
130 "Returns an empty bytes object on EOF.\n");
131
132static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000133bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000134{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136}
137
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000138PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000139 "Write the given buffer to the IO stream.\n"
140 "\n"
141 "Returns the number of bytes written, which is never less than\n"
142 "len(b).\n"
143 "\n"
144 "Raises BlockingIOError if the buffer is full and the\n"
145 "underlying raw stream cannot accept more data at the moment.\n");
146
147static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000151}
152
153
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000154static PyMethodDef bufferediobase_methods[] = {
155 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
156 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
157 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
158 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
159 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000160 {NULL, NULL}
161};
162
163PyTypeObject PyBufferedIOBase_Type = {
164 PyVarObject_HEAD_INIT(NULL, 0)
165 "_io._BufferedIOBase", /*tp_name*/
166 0, /*tp_basicsize*/
167 0, /*tp_itemsize*/
168 0, /*tp_dealloc*/
169 0, /*tp_print*/
170 0, /*tp_getattr*/
171 0, /*tp_setattr*/
172 0, /*tp_compare */
173 0, /*tp_repr*/
174 0, /*tp_as_number*/
175 0, /*tp_as_sequence*/
176 0, /*tp_as_mapping*/
177 0, /*tp_hash */
178 0, /*tp_call*/
179 0, /*tp_str*/
180 0, /*tp_getattro*/
181 0, /*tp_setattro*/
182 0, /*tp_as_buffer*/
183 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000184 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000185 0, /* tp_traverse */
186 0, /* tp_clear */
187 0, /* tp_richcompare */
188 0, /* tp_weaklistoffset */
189 0, /* tp_iter */
190 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000191 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000192 0, /* tp_members */
193 0, /* tp_getset */
194 &PyIOBase_Type, /* tp_base */
195 0, /* tp_dict */
196 0, /* tp_descr_get */
197 0, /* tp_descr_set */
198 0, /* tp_dictoffset */
199 0, /* tp_init */
200 0, /* tp_alloc */
201 0, /* tp_new */
202};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000203
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000204
205typedef struct {
206 PyObject_HEAD
207
208 PyObject *raw;
209 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000210 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000211 int readable;
212 int writable;
Antoine Pitroue033e062010-10-29 10:38:18 +0000213 int deallocating;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200214
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000215 /* True if this is a vanilla Buffered object (rather than a user derived
216 class) *and* the raw stream is a vanilla FileIO object. */
217 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000218
219 /* Absolute position inside the raw stream (-1 if unknown). */
220 Py_off_t abs_pos;
221
222 /* A static buffer of size `buffer_size` */
223 char *buffer;
224 /* Current logical position in the buffer. */
225 Py_off_t pos;
226 /* Position of the raw stream in the buffer. */
227 Py_off_t raw_pos;
228
229 /* Just after the last buffered byte in the buffer, or -1 if the buffer
230 isn't ready for reading. */
231 Py_off_t read_end;
232
233 /* Just after the last byte actually written */
234 Py_off_t write_pos;
235 /* Just after the last byte waiting to be written, or -1 if the buffer
236 isn't ready for writing. */
237 Py_off_t write_end;
238
Georg Brandldfd73442009-04-05 11:47:34 +0000239#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000240 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000241 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000242#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000243
244 Py_ssize_t buffer_size;
245 Py_ssize_t buffer_mask;
246
247 PyObject *dict;
248 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000249} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250
251/*
252 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200253
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000254 * BufferedReader, BufferedWriter and BufferedRandom try to share most
255 methods (this is helped by the members `readable` and `writable`, which
256 are initialized in the respective constructors)
257 * They also share a single buffer for reading and writing. This enables
258 interleaved reads and writes without flushing. It also makes the logic
259 a bit trickier to get right.
260 * The absolute position of the raw stream is cached, if possible, in the
261 `abs_pos` member. It must be updated every time an operation is done
262 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000263 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000265 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
266 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000267
268 NOTE: we should try to maintain block alignment of reads and writes to the
269 raw stream (according to the buffer size), but for now it is only done
270 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200271
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000272*/
273
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000274/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000275
Georg Brandldfd73442009-04-05 11:47:34 +0000276#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000277
278static int
279_enter_buffered_busy(buffered *self)
280{
281 if (self->owner == PyThread_get_thread_ident()) {
282 PyErr_Format(PyExc_RuntimeError,
283 "reentrant call inside %R", self);
284 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000285 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000286 Py_BEGIN_ALLOW_THREADS
287 PyThread_acquire_lock(self->lock, 1);
288 Py_END_ALLOW_THREADS
289 return 1;
290}
291
292#define ENTER_BUFFERED(self) \
293 ( (PyThread_acquire_lock(self->lock, 0) ? \
294 1 : _enter_buffered_busy(self)) \
295 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000296
297#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000298 do { \
299 self->owner = 0; \
300 PyThread_release_lock(self->lock); \
301 } while(0);
302
Georg Brandldfd73442009-04-05 11:47:34 +0000303#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000304#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000305#define LEAVE_BUFFERED(self)
306#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000307
308#define CHECK_INITIALIZED(self) \
309 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000310 if (self->detached) { \
311 PyErr_SetString(PyExc_ValueError, \
312 "raw stream has been detached"); \
313 } else { \
314 PyErr_SetString(PyExc_ValueError, \
315 "I/O operation on uninitialized object"); \
316 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000317 return NULL; \
318 }
319
320#define CHECK_INITIALIZED_INT(self) \
321 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000322 if (self->detached) { \
323 PyErr_SetString(PyExc_ValueError, \
324 "raw stream has been detached"); \
325 } else { \
326 PyErr_SetString(PyExc_ValueError, \
327 "I/O operation on uninitialized object"); \
328 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000329 return -1; \
330 }
331
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000332#define IS_CLOSED(self) \
333 (self->fast_closed_checks \
334 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000335 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000336
337#define CHECK_CLOSED(self, error_msg) \
338 if (IS_CLOSED(self)) { \
339 PyErr_SetString(PyExc_ValueError, error_msg); \
340 return NULL; \
341 }
342
343
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000344#define VALID_READ_BUFFER(self) \
345 (self->readable && self->read_end != -1)
346
347#define VALID_WRITE_BUFFER(self) \
348 (self->writable && self->write_end != -1)
349
350#define ADJUST_POSITION(self, _new_pos) \
351 do { \
352 self->pos = _new_pos; \
353 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
354 self->read_end = self->pos; \
355 } while(0)
356
357#define READAHEAD(self) \
358 ((self->readable && VALID_READ_BUFFER(self)) \
359 ? (self->read_end - self->pos) : 0)
360
361#define RAW_OFFSET(self) \
362 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
363 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
364
365#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000366 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000367
368#define MINUS_LAST_BLOCK(self, size) \
369 (self->buffer_mask ? \
370 (size & ~self->buffer_mask) : \
371 (self->buffer_size * (size / self->buffer_size)))
372
373
374static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000375buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000376{
Antoine Pitroue033e062010-10-29 10:38:18 +0000377 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000378 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
379 return;
380 _PyObject_GC_UNTRACK(self);
381 self->ok = 0;
382 if (self->weakreflist != NULL)
383 PyObject_ClearWeakRefs((PyObject *)self);
384 Py_CLEAR(self->raw);
385 if (self->buffer) {
386 PyMem_Free(self->buffer);
387 self->buffer = NULL;
388 }
Georg Brandldfd73442009-04-05 11:47:34 +0000389#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000390 if (self->lock) {
391 PyThread_free_lock(self->lock);
392 self->lock = NULL;
393 }
Georg Brandldfd73442009-04-05 11:47:34 +0000394#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000395 Py_CLEAR(self->dict);
396 Py_TYPE(self)->tp_free((PyObject *)self);
397}
398
399static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000400buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000401{
402 Py_VISIT(self->raw);
403 Py_VISIT(self->dict);
404 return 0;
405}
406
407static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000408buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000409{
410 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
411 return -1;
412 self->ok = 0;
413 Py_CLEAR(self->raw);
414 Py_CLEAR(self->dict);
415 return 0;
416}
417
Antoine Pitroue033e062010-10-29 10:38:18 +0000418/* Because this can call arbitrary code, it shouldn't be called when
419 the refcount is 0 (that is, not directly from tp_dealloc unless
420 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000421static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000422buffered_dealloc_warn(buffered *self, PyObject *source)
423{
424 if (self->ok && self->raw) {
425 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200426 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000427 if (r)
428 Py_DECREF(r);
429 else
430 PyErr_Clear();
431 }
432 Py_RETURN_NONE;
433}
434
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435/*
436 * _BufferedIOMixin methods
437 * This is not a class, just a collection of methods that will be reused
438 * by BufferedReader and BufferedWriter
439 */
440
441/* Flush and close */
442
443static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000444buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000445{
446 CHECK_INITIALIZED(self)
447 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
448}
449
450static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000451buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000452{
453 int closed;
454 PyObject *res;
455 CHECK_INITIALIZED_INT(self)
456 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
457 if (res == NULL)
458 return -1;
459 closed = PyObject_IsTrue(res);
460 Py_DECREF(res);
461 return closed;
462}
463
464static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000465buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466{
467 CHECK_INITIALIZED(self)
468 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
469}
470
471static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000472buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000473{
474 PyObject *res = NULL;
475 int r;
476
477 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000478 if (!ENTER_BUFFERED(self))
479 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000480
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000481 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482 if (r < 0)
483 goto end;
484 if (r > 0) {
485 res = Py_None;
486 Py_INCREF(res);
487 goto end;
488 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000489
490 if (self->deallocating) {
491 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
492 if (r)
493 Py_DECREF(r);
494 else
495 PyErr_Clear();
496 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000497 /* flush() will most probably re-take the lock, so drop it first */
498 LEAVE_BUFFERED(self)
499 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000500 if (!ENTER_BUFFERED(self))
501 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000502 if (res == NULL) {
Antoine Pitrou6be88762010-05-03 16:48:20 +0000503 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504 }
505 Py_XDECREF(res);
506
507 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
508
509end:
510 LEAVE_BUFFERED(self)
511 return res;
512}
513
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000514/* detach */
515
516static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000517buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000518{
519 PyObject *raw, *res;
520 CHECK_INITIALIZED(self)
521 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
522 if (res == NULL)
523 return NULL;
524 Py_DECREF(res);
525 raw = self->raw;
526 self->raw = NULL;
527 self->detached = 1;
528 self->ok = 0;
529 return raw;
530}
531
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000532/* Inquiries */
533
534static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000535buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000536{
537 CHECK_INITIALIZED(self)
538 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
539}
540
541static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000542buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543{
544 CHECK_INITIALIZED(self)
545 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
546}
547
548static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000549buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000550{
551 CHECK_INITIALIZED(self)
552 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
553}
554
555static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000556buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000557{
558 CHECK_INITIALIZED(self)
559 return PyObject_GetAttrString(self->raw, "name");
560}
561
562static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000563buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000564{
565 CHECK_INITIALIZED(self)
566 return PyObject_GetAttrString(self->raw, "mode");
567}
568
569/* Lower-level APIs */
570
571static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000572buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573{
574 CHECK_INITIALIZED(self)
575 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
576}
577
578static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000579buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580{
581 CHECK_INITIALIZED(self)
582 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
583}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000584
Antoine Pitrou243757e2010-11-05 21:15:39 +0000585/* Serialization */
586
587static PyObject *
588buffered_getstate(buffered *self, PyObject *args)
589{
590 PyErr_Format(PyExc_TypeError,
591 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
592 return NULL;
593}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000594
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000595/* Forward decls */
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597_bufferedwriter_flush_unlocked(buffered *, int);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000599_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000601_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000603_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200605_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000607_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000611_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200612static Py_ssize_t
613_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614
615/*
616 * Helpers
617 */
618
619/* Returns the address of the `written` member if a BlockingIOError was
620 raised, NULL otherwise. The error is always re-raised. */
621static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000622_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623{
624 PyObject *t, *v, *tb;
625 PyBlockingIOErrorObject *err;
626
627 PyErr_Fetch(&t, &v, &tb);
628 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
629 PyErr_Restore(t, v, tb);
630 return NULL;
631 }
632 err = (PyBlockingIOErrorObject *) v;
633 /* TODO: sanity check (err->written >= 0) */
634 PyErr_Restore(t, v, tb);
635 return &err->written;
636}
637
638static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000639_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000642 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
644 if (res == NULL)
645 return -1;
646 n = PyNumber_AsOff_t(res, PyExc_ValueError);
647 Py_DECREF(res);
648 if (n < 0) {
649 if (!PyErr_Occurred())
650 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000651 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200652 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653 return -1;
654 }
655 self->abs_pos = n;
656 return n;
657}
658
659static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000660_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000661{
662 PyObject *res, *posobj, *whenceobj;
663 Py_off_t n;
664
665 posobj = PyLong_FromOff_t(target);
666 if (posobj == NULL)
667 return -1;
668 whenceobj = PyLong_FromLong(whence);
669 if (whenceobj == NULL) {
670 Py_DECREF(posobj);
671 return -1;
672 }
673 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
674 posobj, whenceobj, NULL);
675 Py_DECREF(posobj);
676 Py_DECREF(whenceobj);
677 if (res == NULL)
678 return -1;
679 n = PyNumber_AsOff_t(res, PyExc_ValueError);
680 Py_DECREF(res);
681 if (n < 0) {
682 if (!PyErr_Occurred())
683 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000684 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200685 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000686 return -1;
687 }
688 self->abs_pos = n;
689 return n;
690}
691
692static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000693_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000694{
695 Py_ssize_t n;
696 if (self->buffer_size <= 0) {
697 PyErr_SetString(PyExc_ValueError,
698 "buffer size must be strictly positive");
699 return -1;
700 }
701 if (self->buffer)
702 PyMem_Free(self->buffer);
703 self->buffer = PyMem_Malloc(self->buffer_size);
704 if (self->buffer == NULL) {
705 PyErr_NoMemory();
706 return -1;
707 }
Georg Brandldfd73442009-04-05 11:47:34 +0000708#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000709 if (self->lock)
710 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711 self->lock = PyThread_allocate_lock();
712 if (self->lock == NULL) {
713 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
714 return -1;
715 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000716 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000717#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000718 /* Find out whether buffer_size is a power of 2 */
719 /* XXX is this optimization useful? */
720 for (n = self->buffer_size - 1; n & 1; n >>= 1)
721 ;
722 if (n == 0)
723 self->buffer_mask = self->buffer_size - 1;
724 else
725 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000726 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000727 PyErr_Clear();
728 return 0;
729}
730
Antoine Pitrou707ce822011-02-25 21:24:11 +0000731/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
732 clears the error indicator), 0 otherwise.
733 Should only be called when PyErr_Occurred() is true.
734*/
735static int
736_trap_eintr(void)
737{
738 static PyObject *eintr_int = NULL;
739 PyObject *typ, *val, *tb;
740 PyEnvironmentErrorObject *env_err;
741
742 if (eintr_int == NULL) {
743 eintr_int = PyLong_FromLong(EINTR);
744 assert(eintr_int != NULL);
745 }
746 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
747 return 0;
748 PyErr_Fetch(&typ, &val, &tb);
749 PyErr_NormalizeException(&typ, &val, &tb);
750 env_err = (PyEnvironmentErrorObject *) val;
751 assert(env_err != NULL);
752 if (env_err->myerrno != NULL &&
753 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
754 Py_DECREF(typ);
755 Py_DECREF(val);
756 Py_XDECREF(tb);
757 return 1;
758 }
759 /* This silences any error set by PyObject_RichCompareBool() */
760 PyErr_Restore(typ, val, tb);
761 return 0;
762}
763
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000764/*
765 * Shared methods and wrappers
766 */
767
768static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200769buffered_flush_and_rewind_unlocked(buffered *self)
770{
771 PyObject *res;
772
773 res = _bufferedwriter_flush_unlocked(self, 0);
774 if (res == NULL)
775 return NULL;
776 Py_DECREF(res);
777
778 if (self->readable) {
779 /* Rewind the raw stream so that its position corresponds to
780 the current logical position. */
781 Py_off_t n;
782 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
783 _bufferedreader_reset_buf(self);
784 if (n == -1)
785 return NULL;
786 }
787 Py_RETURN_NONE;
788}
789
790static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000791buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000792{
793 PyObject *res;
794
795 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000796 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000797
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000798 if (!ENTER_BUFFERED(self))
799 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200800 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000801 LEAVE_BUFFERED(self)
802
803 return res;
804}
805
806static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000807buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000808{
809 Py_ssize_t n = 0;
810 PyObject *res = NULL;
811
812 CHECK_INITIALIZED(self)
813 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
814 return NULL;
815 }
816
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000817 if (!ENTER_BUFFERED(self))
818 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819
820 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200821 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822 if (res == NULL)
823 goto end;
824 Py_CLEAR(res);
825 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200826 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000827
828end:
829 LEAVE_BUFFERED(self)
830 return res;
831}
832
833static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000834buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000835{
836 Py_ssize_t n = -1;
837 PyObject *res;
838
839 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000840 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841 return NULL;
842 }
843 if (n < -1) {
844 PyErr_SetString(PyExc_ValueError,
845 "read length must be positive or -1");
846 return NULL;
847 }
848
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000849 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000851 if (n == -1) {
852 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000853 if (!ENTER_BUFFERED(self))
854 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000855 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000856 }
857 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000858 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200859 if (res != Py_None)
860 return res;
861 Py_DECREF(res);
862 if (!ENTER_BUFFERED(self))
863 return NULL;
864 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000865 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866
Antoine Pitroue05565e2011-08-20 14:39:23 +0200867 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868 return res;
869}
870
871static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000872buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000873{
874 Py_ssize_t n, have, r;
875 PyObject *res = NULL;
876
877 CHECK_INITIALIZED(self)
878 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
879 return NULL;
880 }
881
882 if (n < 0) {
883 PyErr_SetString(PyExc_ValueError,
884 "read length must be positive");
885 return NULL;
886 }
887 if (n == 0)
888 return PyBytes_FromStringAndSize(NULL, 0);
889
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000890 if (!ENTER_BUFFERED(self))
891 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200892
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000893 /* Return up to n bytes. If at least one byte is buffered, we
894 only return buffered bytes. Otherwise, we do one raw read. */
895
896 /* XXX: this mimicks the io.py implementation but is probably wrong.
897 If we need to read from the raw stream, then we could actually read
898 all `n` bytes asked by the caller (and possibly more, so as to fill
899 our buffer for the next reads). */
900
901 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
902 if (have > 0) {
903 if (n > have)
904 n = have;
905 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
906 if (res == NULL)
907 goto end;
908 self->pos += n;
909 goto end;
910 }
911
Antoine Pitroue05565e2011-08-20 14:39:23 +0200912 if (self->writable) {
913 res = buffered_flush_and_rewind_unlocked(self);
914 if (res == NULL)
915 goto end;
916 Py_DECREF(res);
917 }
918
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000919 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000920 _bufferedreader_reset_buf(self);
921 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922 if (r == -1)
923 goto end;
924 if (r == -2)
925 r = 0;
926 if (n > r)
927 n = r;
928 res = PyBytes_FromStringAndSize(self->buffer, n);
929 if (res == NULL)
930 goto end;
931 self->pos = n;
932
933end:
934 LEAVE_BUFFERED(self)
935 return res;
936}
937
938static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000939buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200941 Py_buffer buf;
942 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943 PyObject *res = NULL;
944
945 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200946
947 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
948 return NULL;
949
950 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
951 if (n > 0) {
952 if (n >= buf.len) {
953 memcpy(buf.buf, self->buffer + self->pos, buf.len);
954 self->pos += buf.len;
955 res = PyLong_FromSsize_t(buf.len);
956 goto end_unlocked;
957 }
958 memcpy(buf.buf, self->buffer + self->pos, n);
959 self->pos += n;
960 written = n;
961 }
962
963 if (!ENTER_BUFFERED(self))
964 goto end_unlocked;
965
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000966 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200967 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 if (res == NULL)
969 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200970 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000971 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200972
973 _bufferedreader_reset_buf(self);
974 self->pos = 0;
975
976 for (remaining = buf.len - written;
977 remaining > 0;
978 written += n, remaining -= n) {
979 /* If remaining bytes is larger than internal buffer size, copy
980 * directly into caller's buffer. */
981 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200982 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
983 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200984 }
985 else {
986 n = _bufferedreader_fill_buffer(self);
987 if (n > 0) {
988 if (n > remaining)
989 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200990 memcpy((char *) buf.buf + written,
991 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200992 self->pos += n;
993 continue; /* short circuit */
994 }
995 }
996 if (n == 0 || (n == -2 && written > 0))
997 break;
998 if (n < 0) {
999 if (n == -2) {
1000 Py_INCREF(Py_None);
1001 res = Py_None;
1002 }
1003 goto end;
1004 }
1005 }
1006 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001007
1008end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001009 LEAVE_BUFFERED(self);
1010end_unlocked:
1011 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 return res;
1013}
1014
1015static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001016_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001017{
1018 PyObject *res = NULL;
1019 PyObject *chunks = NULL;
1020 Py_ssize_t n, written = 0;
1021 const char *start, *s, *end;
1022
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001023 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001024
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001025 /* First, try to find a line in the buffer. This can run unlocked because
1026 the calls to the C API are simple enough that they can't trigger
1027 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001028 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1029 if (limit >= 0 && n > limit)
1030 n = limit;
1031 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001032 s = memchr(start, '\n', n);
1033 if (s != NULL) {
1034 res = PyBytes_FromStringAndSize(start, s - start + 1);
1035 if (res != NULL)
1036 self->pos += s - start + 1;
1037 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001038 }
1039 if (n == limit) {
1040 res = PyBytes_FromStringAndSize(start, n);
1041 if (res != NULL)
1042 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001043 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044 }
1045
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001046 if (!ENTER_BUFFERED(self))
1047 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001048
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001050 chunks = PyList_New(0);
1051 if (chunks == NULL)
1052 goto end;
1053 if (n > 0) {
1054 res = PyBytes_FromStringAndSize(start, n);
1055 if (res == NULL)
1056 goto end;
1057 if (PyList_Append(chunks, res) < 0) {
1058 Py_CLEAR(res);
1059 goto end;
1060 }
1061 Py_CLEAR(res);
1062 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001063 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001064 if (limit >= 0)
1065 limit -= n;
1066 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001067 if (self->writable) {
1068 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1069 if (r == NULL)
1070 goto end;
1071 Py_DECREF(r);
1072 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001073
1074 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001075 _bufferedreader_reset_buf(self);
1076 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001077 if (n == -1)
1078 goto end;
1079 if (n <= 0)
1080 break;
1081 if (limit >= 0 && n > limit)
1082 n = limit;
1083 start = self->buffer;
1084 end = start + n;
1085 s = start;
1086 while (s < end) {
1087 if (*s++ == '\n') {
1088 res = PyBytes_FromStringAndSize(start, s - start);
1089 if (res == NULL)
1090 goto end;
1091 self->pos = s - start;
1092 goto found;
1093 }
1094 }
1095 res = PyBytes_FromStringAndSize(start, n);
1096 if (res == NULL)
1097 goto end;
1098 if (n == limit) {
1099 self->pos = n;
1100 break;
1101 }
1102 if (PyList_Append(chunks, res) < 0) {
1103 Py_CLEAR(res);
1104 goto end;
1105 }
1106 Py_CLEAR(res);
1107 written += n;
1108 if (limit >= 0)
1109 limit -= n;
1110 }
1111found:
1112 if (res != NULL && PyList_Append(chunks, res) < 0) {
1113 Py_CLEAR(res);
1114 goto end;
1115 }
1116 Py_CLEAR(res);
1117 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1118
1119end:
1120 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001121end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001122 Py_XDECREF(chunks);
1123 return res;
1124}
1125
1126static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001127buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128{
1129 Py_ssize_t limit = -1;
1130
1131 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001132 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001133 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001134 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001135}
1136
1137
1138static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001139buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001140{
1141 Py_off_t pos;
1142
1143 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001144 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001145 if (pos == -1)
1146 return NULL;
1147 pos -= RAW_OFFSET(self);
1148 /* TODO: sanity check (pos >= 0) */
1149 return PyLong_FromOff_t(pos);
1150}
1151
1152static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001153buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001154{
1155 Py_off_t target, n;
1156 int whence = 0;
1157 PyObject *targetobj, *res = NULL;
1158
1159 CHECK_INITIALIZED(self)
1160 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1161 return NULL;
1162 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001163 if (whence < 0 || whence > 2) {
1164 PyErr_Format(PyExc_ValueError,
1165 "whence must be between 0 and 2, not %d", whence);
1166 return NULL;
1167 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001168
1169 CHECK_CLOSED(self, "seek of closed file")
1170
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001171 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1172 return NULL;
1173
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1175 if (target == -1 && PyErr_Occurred())
1176 return NULL;
1177
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001178 if (whence != 2 && self->readable) {
1179 Py_off_t current, avail;
1180 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001181 so as to return quickly if possible. Also, we needn't take the
1182 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001184 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1185 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186 current = RAW_TELL(self);
1187 avail = READAHEAD(self);
1188 if (avail > 0) {
1189 Py_off_t offset;
1190 if (whence == 0)
1191 offset = target - (current - RAW_OFFSET(self));
1192 else
1193 offset = target;
1194 if (offset >= -self->pos && offset <= avail) {
1195 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001196 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197 }
1198 }
1199 }
1200
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001201 if (!ENTER_BUFFERED(self))
1202 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001203
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204 /* Fallback: invoke raw seek() method and clear buffer */
1205 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001206 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207 if (res == NULL)
1208 goto end;
1209 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001210 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001211 }
1212
1213 /* TODO: align on block boundary and read buffer if needed? */
1214 if (whence == 1)
1215 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001216 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 if (n == -1)
1218 goto end;
1219 self->raw_pos = -1;
1220 res = PyLong_FromOff_t(n);
1221 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001222 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001223
1224end:
1225 LEAVE_BUFFERED(self)
1226 return res;
1227}
1228
1229static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001230buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231{
1232 PyObject *pos = Py_None;
1233 PyObject *res = NULL;
1234
1235 CHECK_INITIALIZED(self)
1236 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1237 return NULL;
1238 }
1239
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001240 if (!ENTER_BUFFERED(self))
1241 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001242
1243 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001244 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245 if (res == NULL)
1246 goto end;
1247 Py_CLEAR(res);
1248 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1250 if (res == NULL)
1251 goto end;
1252 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001253 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 PyErr_Clear();
1255
1256end:
1257 LEAVE_BUFFERED(self)
1258 return res;
1259}
1260
1261static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001262buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263{
1264 PyObject *line;
1265 PyTypeObject *tp;
1266
1267 CHECK_INITIALIZED(self);
1268
1269 tp = Py_TYPE(self);
1270 if (tp == &PyBufferedReader_Type ||
1271 tp == &PyBufferedRandom_Type) {
1272 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001273 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 }
1275 else {
1276 line = PyObject_CallMethodObjArgs((PyObject *)self,
1277 _PyIO_str_readline, NULL);
1278 if (line && !PyBytes_Check(line)) {
1279 PyErr_Format(PyExc_IOError,
1280 "readline() should have returned a bytes object, "
1281 "not '%.200s'", Py_TYPE(line)->tp_name);
1282 Py_DECREF(line);
1283 return NULL;
1284 }
1285 }
1286
1287 if (line == NULL)
1288 return NULL;
1289
1290 if (PyBytes_GET_SIZE(line) == 0) {
1291 /* Reached EOF or would have blocked */
1292 Py_DECREF(line);
1293 return NULL;
1294 }
1295
1296 return line;
1297}
1298
Antoine Pitrou716c4442009-05-23 19:04:03 +00001299static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001300buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001301{
1302 PyObject *nameobj, *res;
1303
1304 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1305 if (nameobj == NULL) {
1306 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1307 PyErr_Clear();
1308 else
1309 return NULL;
1310 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1311 }
1312 else {
1313 res = PyUnicode_FromFormat("<%s name=%R>",
1314 Py_TYPE(self)->tp_name, nameobj);
1315 Py_DECREF(nameobj);
1316 }
1317 return res;
1318}
1319
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320/*
1321 * class BufferedReader
1322 */
1323
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001324PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001325 "Create a new buffered reader using the given readable raw IO object.");
1326
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001327static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328{
1329 self->read_end = -1;
1330}
1331
1332static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001333bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001334{
1335 char *kwlist[] = {"raw", "buffer_size", NULL};
1336 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1337 PyObject *raw;
1338
1339 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001340 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341
1342 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1343 &raw, &buffer_size)) {
1344 return -1;
1345 }
1346
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001347 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001348 return -1;
1349
1350 Py_CLEAR(self->raw);
1351 Py_INCREF(raw);
1352 self->raw = raw;
1353 self->buffer_size = buffer_size;
1354 self->readable = 1;
1355 self->writable = 0;
1356
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001357 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001358 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001359 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001361 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1362 Py_TYPE(raw) == &PyFileIO_Type);
1363
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001364 self->ok = 1;
1365 return 0;
1366}
1367
1368static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001369_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001370{
1371 Py_buffer buf;
1372 PyObject *memobj, *res;
1373 Py_ssize_t n;
1374 /* NOTE: the buffer needn't be released as its object is NULL. */
1375 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1376 return -1;
1377 memobj = PyMemoryView_FromBuffer(&buf);
1378 if (memobj == NULL)
1379 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001380 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1381 occurs so we needn't do it ourselves.
1382 We then retry reading, ignoring the signal if no handler has
1383 raised (see issue #10956).
1384 */
1385 do {
1386 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1387 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388 Py_DECREF(memobj);
1389 if (res == NULL)
1390 return -1;
1391 if (res == Py_None) {
1392 /* Non-blocking stream would have blocked. Special return code! */
1393 Py_DECREF(res);
1394 return -2;
1395 }
1396 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1397 Py_DECREF(res);
1398 if (n < 0 || n > len) {
1399 PyErr_Format(PyExc_IOError,
1400 "raw readinto() returned invalid length %zd "
1401 "(should have been between 0 and %zd)", n, len);
1402 return -1;
1403 }
1404 if (n > 0 && self->abs_pos != -1)
1405 self->abs_pos += n;
1406 return n;
1407}
1408
1409static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001410_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411{
1412 Py_ssize_t start, len, n;
1413 if (VALID_READ_BUFFER(self))
1414 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1415 else
1416 start = 0;
1417 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001418 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001419 if (n <= 0)
1420 return n;
1421 self->read_end = start + n;
1422 self->raw_pos = start + n;
1423 return n;
1424}
1425
1426static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001427_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001428{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001429 Py_ssize_t current_size;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001430 PyObject *res, *data = NULL, *chunk, *chunks;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001431
1432 /* First copy what we have in the current buffer. */
1433 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1434 if (current_size) {
1435 data = PyBytes_FromStringAndSize(
1436 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001437 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001439 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001441 /* We're going past the buffer's bounds, flush it */
1442 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001443 res = buffered_flush_and_rewind_unlocked(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001444 if (res == NULL)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001445 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001446 Py_CLEAR(res);
1447 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001448 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001449
1450 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1451 chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1452 if (chunk == NULL)
1453 return NULL;
1454 if (chunk != Py_None && !PyBytes_Check(chunk)) {
1455 Py_XDECREF(data);
1456 Py_DECREF(chunk);
1457 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1458 return NULL;
1459 }
1460 if (chunk == Py_None) {
1461 if (current_size == 0)
1462 return chunk;
1463 else {
1464 Py_DECREF(chunk);
1465 return data;
1466 }
1467 }
1468 else if (current_size) {
1469 PyBytes_Concat(&data, chunk);
1470 Py_DECREF(chunk);
1471 if (data == NULL)
1472 return NULL;
1473 return data;
1474 } else
1475 return chunk;
1476 }
1477
1478 chunks = PyList_New(0);
1479 if (chunks == NULL)
1480 return NULL;
1481
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001482 while (1) {
1483 if (data) {
1484 if (PyList_Append(chunks, data) < 0) {
1485 Py_DECREF(data);
1486 Py_DECREF(chunks);
1487 return NULL;
1488 }
1489 Py_DECREF(data);
1490 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001491
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001492 /* Read until EOF or until read() would block. */
1493 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1494 if (data == NULL) {
1495 Py_DECREF(chunks);
1496 return NULL;
1497 }
1498 if (data != Py_None && !PyBytes_Check(data)) {
1499 Py_DECREF(data);
1500 Py_DECREF(chunks);
1501 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1502 return NULL;
1503 }
1504 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1505 if (current_size == 0) {
1506 Py_DECREF(chunks);
1507 return data;
1508 }
1509 else {
1510 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1511 Py_DECREF(data);
1512 Py_DECREF(chunks);
1513 return res;
1514 }
1515 }
1516 current_size += PyBytes_GET_SIZE(data);
1517 if (self->abs_pos != -1)
1518 self->abs_pos += PyBytes_GET_SIZE(data);
1519 }
1520}
1521
1522/* Read n bytes from the buffer if it can, otherwise return None.
1523 This function is simple enough that it can run unlocked. */
1524static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001525_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001526{
1527 Py_ssize_t current_size;
1528
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001529 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1530 if (n <= current_size) {
1531 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001532 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1533 if (res != NULL)
1534 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001535 return res;
1536 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001537 Py_RETURN_NONE;
1538}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001539
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001540/* Generic read function: read from the stream until enough bytes are read,
1541 * or until an EOF occurs or until read() would block.
1542 */
1543static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001544_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001545{
1546 PyObject *res = NULL;
1547 Py_ssize_t current_size, remaining, written;
1548 char *out;
1549
1550 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1551 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001552 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001553
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001554 res = PyBytes_FromStringAndSize(NULL, n);
1555 if (res == NULL)
1556 goto error;
1557 out = PyBytes_AS_STRING(res);
1558 remaining = n;
1559 written = 0;
1560 if (current_size > 0) {
1561 memcpy(out, self->buffer + self->pos, current_size);
1562 remaining -= current_size;
1563 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001564 self->pos += current_size;
1565 }
1566 /* Flush the write buffer if necessary */
1567 if (self->writable) {
1568 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1569 if (r == NULL)
1570 goto error;
1571 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001572 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001573 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001574 while (remaining > 0) {
1575 /* We want to read a whole block at the end into buffer.
1576 If we had readv() we could do this in one pass. */
1577 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1578 if (r == 0)
1579 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001580 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001581 if (r == -1)
1582 goto error;
1583 if (r == 0 || r == -2) {
1584 /* EOF occurred or read() would block. */
1585 if (r == 0 || written > 0) {
1586 if (_PyBytes_Resize(&res, written))
1587 goto error;
1588 return res;
1589 }
1590 Py_DECREF(res);
1591 Py_INCREF(Py_None);
1592 return Py_None;
1593 }
1594 remaining -= r;
1595 written += r;
1596 }
1597 assert(remaining <= self->buffer_size);
1598 self->pos = 0;
1599 self->raw_pos = 0;
1600 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001601 /* NOTE: when the read is satisfied, we avoid issuing any additional
1602 reads, which could block indefinitely (e.g. on a socket).
1603 See issue #9550. */
1604 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001605 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606 if (r == -1)
1607 goto error;
1608 if (r == 0 || r == -2) {
1609 /* EOF occurred or read() would block. */
1610 if (r == 0 || written > 0) {
1611 if (_PyBytes_Resize(&res, written))
1612 goto error;
1613 return res;
1614 }
1615 Py_DECREF(res);
1616 Py_INCREF(Py_None);
1617 return Py_None;
1618 }
1619 if (remaining > r) {
1620 memcpy(out + written, self->buffer + self->pos, r);
1621 written += r;
1622 self->pos += r;
1623 remaining -= r;
1624 }
1625 else if (remaining > 0) {
1626 memcpy(out + written, self->buffer + self->pos, remaining);
1627 written += remaining;
1628 self->pos += remaining;
1629 remaining = 0;
1630 }
1631 if (remaining == 0)
1632 break;
1633 }
1634
1635 return res;
1636
1637error:
1638 Py_XDECREF(res);
1639 return NULL;
1640}
1641
1642static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001643_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001644{
1645 Py_ssize_t have, r;
1646
1647 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1648 /* Constraints:
1649 1. we don't want to advance the file position.
1650 2. we don't want to lose block alignment, so we can't shift the buffer
1651 to make some place.
1652 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1653 */
1654 if (have > 0) {
1655 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1656 }
1657
1658 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001659 _bufferedreader_reset_buf(self);
1660 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001661 if (r == -1)
1662 return NULL;
1663 if (r == -2)
1664 r = 0;
1665 self->pos = 0;
1666 return PyBytes_FromStringAndSize(self->buffer, r);
1667}
1668
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001669static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001670 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001671 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1672 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1673 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1674 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1675 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1676 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1677 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1678 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001679 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001680 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001681
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001682 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1683 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1684 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001685 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001686 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1687 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1688 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1689 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001690 {NULL, NULL}
1691};
1692
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001693static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001694 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001695 {NULL}
1696};
1697
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001698static PyGetSetDef bufferedreader_getset[] = {
1699 {"closed", (getter)buffered_closed_get, NULL, NULL},
1700 {"name", (getter)buffered_name_get, NULL, NULL},
1701 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001702 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001703};
1704
1705
1706PyTypeObject PyBufferedReader_Type = {
1707 PyVarObject_HEAD_INIT(NULL, 0)
1708 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001709 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001710 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001711 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001712 0, /*tp_print*/
1713 0, /*tp_getattr*/
1714 0, /*tp_setattr*/
1715 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001716 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001717 0, /*tp_as_number*/
1718 0, /*tp_as_sequence*/
1719 0, /*tp_as_mapping*/
1720 0, /*tp_hash */
1721 0, /*tp_call*/
1722 0, /*tp_str*/
1723 0, /*tp_getattro*/
1724 0, /*tp_setattro*/
1725 0, /*tp_as_buffer*/
1726 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1727 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001728 bufferedreader_doc, /* tp_doc */
1729 (traverseproc)buffered_traverse, /* tp_traverse */
1730 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001731 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001732 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001733 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001734 (iternextfunc)buffered_iternext, /* tp_iternext */
1735 bufferedreader_methods, /* tp_methods */
1736 bufferedreader_members, /* tp_members */
1737 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001738 0, /* tp_base */
1739 0, /* tp_dict */
1740 0, /* tp_descr_get */
1741 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001742 offsetof(buffered, dict), /* tp_dictoffset */
1743 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001744 0, /* tp_alloc */
1745 PyType_GenericNew, /* tp_new */
1746};
1747
1748
Benjamin Peterson59406a92009-03-26 17:10:29 +00001749
1750static int
1751complain_about_max_buffer_size(void)
1752{
1753 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1754 "max_buffer_size is deprecated", 1) < 0)
1755 return 0;
1756 return 1;
1757}
1758
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759/*
1760 * class BufferedWriter
1761 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001762PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763 "A buffer for a writeable sequential RawIO object.\n"
1764 "\n"
1765 "The constructor creates a BufferedWriter for the given writeable raw\n"
1766 "stream. If the buffer_size is not given, it defaults to\n"
1767 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1768 );
1769
1770static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001771_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001772{
1773 self->write_pos = 0;
1774 self->write_end = -1;
1775}
1776
1777static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001778bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779{
1780 /* TODO: properly deprecate max_buffer_size */
1781 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1782 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001783 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 PyObject *raw;
1785
1786 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001787 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788
1789 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1790 &raw, &buffer_size, &max_buffer_size)) {
1791 return -1;
1792 }
1793
Benjamin Peterson59406a92009-03-26 17:10:29 +00001794 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1795 return -1;
1796
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001797 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001798 return -1;
1799
1800 Py_CLEAR(self->raw);
1801 Py_INCREF(raw);
1802 self->raw = raw;
1803 self->readable = 0;
1804 self->writable = 1;
1805
1806 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001807 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001808 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 self->pos = 0;
1811
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001812 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1813 Py_TYPE(raw) == &PyFileIO_Type);
1814
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 self->ok = 1;
1816 return 0;
1817}
1818
1819static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001820_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001821{
1822 Py_buffer buf;
1823 PyObject *memobj, *res;
1824 Py_ssize_t n;
1825 /* NOTE: the buffer needn't be released as its object is NULL. */
1826 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1827 return -1;
1828 memobj = PyMemoryView_FromBuffer(&buf);
1829 if (memobj == NULL)
1830 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001831 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1832 occurs so we needn't do it ourselves.
1833 We then retry writing, ignoring the signal if no handler has
1834 raised (see issue #10956).
1835 */
1836 do {
1837 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1838 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001839 Py_DECREF(memobj);
1840 if (res == NULL)
1841 return -1;
1842 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1843 Py_DECREF(res);
1844 if (n < 0 || n > len) {
1845 PyErr_Format(PyExc_IOError,
1846 "raw write() returned invalid length %zd "
1847 "(should have been between 0 and %zd)", n, len);
1848 return -1;
1849 }
1850 if (n > 0 && self->abs_pos != -1)
1851 self->abs_pos += n;
1852 return n;
1853}
1854
1855/* `restore_pos` is 1 if we need to restore the raw stream position at
1856 the end, 0 otherwise. */
1857static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001858_bufferedwriter_flush_unlocked(buffered *self, int restore_pos)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859{
1860 Py_ssize_t written = 0;
1861 Py_off_t n, rewind;
1862
1863 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1864 goto end;
1865 /* First, rewind */
1866 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1867 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001868 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001869 if (n < 0) {
1870 goto error;
1871 }
1872 self->raw_pos -= rewind;
1873 }
1874 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001875 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001876 self->buffer + self->write_pos,
1877 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1878 Py_off_t, Py_ssize_t));
1879 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001880 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001881 if (w == NULL)
1882 goto error;
1883 self->write_pos += *w;
1884 self->raw_pos = self->write_pos;
1885 written += *w;
1886 *w = written;
1887 /* Already re-raised */
1888 goto error;
1889 }
1890 self->write_pos += n;
1891 self->raw_pos = self->write_pos;
1892 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001893 /* Partial writes can return successfully when interrupted by a
1894 signal (see write(2)). We must run signal handlers before
1895 blocking another time, possibly indefinitely. */
1896 if (PyErr_CheckSignals() < 0)
1897 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898 }
1899
1900 if (restore_pos) {
1901 Py_off_t forward = rewind - written;
1902 if (forward != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001903 n = _buffered_raw_seek(self, forward, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001904 if (n < 0) {
1905 goto error;
1906 }
1907 self->raw_pos += forward;
1908 }
1909 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001910 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001911
1912end:
1913 Py_RETURN_NONE;
1914
1915error:
1916 return NULL;
1917}
1918
1919static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001920bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921{
1922 PyObject *res = NULL;
1923 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001924 Py_ssize_t written, avail, remaining;
1925 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926
1927 CHECK_INITIALIZED(self)
1928 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1929 return NULL;
1930 }
1931
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001932 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933 PyErr_SetString(PyExc_ValueError, "write to closed file");
1934 PyBuffer_Release(&buf);
1935 return NULL;
1936 }
1937
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001938 if (!ENTER_BUFFERED(self)) {
1939 PyBuffer_Release(&buf);
1940 return NULL;
1941 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942
1943 /* Fast path: the data to write can be fully buffered. */
1944 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1945 self->pos = 0;
1946 self->raw_pos = 0;
1947 }
1948 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1949 if (buf.len <= avail) {
1950 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001951 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 self->write_pos = self->pos;
1953 }
1954 ADJUST_POSITION(self, self->pos + buf.len);
1955 if (self->pos > self->write_end)
1956 self->write_end = self->pos;
1957 written = buf.len;
1958 goto end;
1959 }
1960
1961 /* First write the current buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001962 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001963 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001964 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965 if (w == NULL)
1966 goto error;
1967 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001968 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969 /* Make some place by shifting the buffer. */
1970 assert(VALID_WRITE_BUFFER(self));
1971 memmove(self->buffer, self->buffer + self->write_pos,
1972 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1973 Py_off_t, Py_ssize_t));
1974 self->write_end -= self->write_pos;
1975 self->raw_pos -= self->write_pos;
1976 self->pos -= self->write_pos;
1977 self->write_pos = 0;
1978 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1979 Py_off_t, Py_ssize_t);
1980 if (buf.len <= avail) {
1981 /* Everything can be buffered */
1982 PyErr_Clear();
1983 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1984 self->write_end += buf.len;
1985 written = buf.len;
1986 goto end;
1987 }
1988 /* Buffer as much as possible. */
1989 memcpy(self->buffer + self->write_end, buf.buf, avail);
1990 self->write_end += avail;
1991 /* Already re-raised */
1992 *w = avail;
1993 goto error;
1994 }
1995 Py_CLEAR(res);
1996
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001997 /* Adjust the raw stream position if it is away from the logical stream
1998 position. This happens if the read buffer has been filled but not
1999 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2000 the raw stream by itself).
2001 Fixes issue #6629.
2002 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002003 offset = RAW_OFFSET(self);
2004 if (offset != 0) {
2005 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002006 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002007 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002008 }
2009
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 /* Then write buf itself. At this point the buffer has been emptied. */
2011 remaining = buf.len;
2012 written = 0;
2013 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002014 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 self, (char *) buf.buf + written, buf.len - written);
2016 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002017 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 if (w == NULL)
2019 goto error;
2020 written += *w;
2021 remaining -= *w;
2022 if (remaining > self->buffer_size) {
2023 /* Can't buffer everything, still buffer as much as possible */
2024 memcpy(self->buffer,
2025 (char *) buf.buf + written, self->buffer_size);
2026 self->raw_pos = 0;
2027 ADJUST_POSITION(self, self->buffer_size);
2028 self->write_end = self->buffer_size;
2029 *w = written + self->buffer_size;
2030 /* Already re-raised */
2031 goto error;
2032 }
2033 PyErr_Clear();
2034 break;
2035 }
2036 written += n;
2037 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002038 /* Partial writes can return successfully when interrupted by a
2039 signal (see write(2)). We must run signal handlers before
2040 blocking another time, possibly indefinitely. */
2041 if (PyErr_CheckSignals() < 0)
2042 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002043 }
2044 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002045 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 if (remaining > 0) {
2047 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2048 written += remaining;
2049 }
2050 self->write_pos = 0;
2051 /* TODO: sanity check (remaining >= 0) */
2052 self->write_end = remaining;
2053 ADJUST_POSITION(self, remaining);
2054 self->raw_pos = 0;
2055
2056end:
2057 res = PyLong_FromSsize_t(written);
2058
2059error:
2060 LEAVE_BUFFERED(self)
2061 PyBuffer_Release(&buf);
2062 return res;
2063}
2064
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002065static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002067 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2068 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2069 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2070 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2071 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2072 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2073 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002074 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002075 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002077 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2078 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2079 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2080 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2081 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002082 {NULL, NULL}
2083};
2084
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002085static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002086 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002087 {NULL}
2088};
2089
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002090static PyGetSetDef bufferedwriter_getset[] = {
2091 {"closed", (getter)buffered_closed_get, NULL, NULL},
2092 {"name", (getter)buffered_name_get, NULL, NULL},
2093 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002094 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095};
2096
2097
2098PyTypeObject PyBufferedWriter_Type = {
2099 PyVarObject_HEAD_INIT(NULL, 0)
2100 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002101 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002102 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104 0, /*tp_print*/
2105 0, /*tp_getattr*/
2106 0, /*tp_setattr*/
2107 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002108 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 0, /*tp_as_number*/
2110 0, /*tp_as_sequence*/
2111 0, /*tp_as_mapping*/
2112 0, /*tp_hash */
2113 0, /*tp_call*/
2114 0, /*tp_str*/
2115 0, /*tp_getattro*/
2116 0, /*tp_setattro*/
2117 0, /*tp_as_buffer*/
2118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2119 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120 bufferedwriter_doc, /* tp_doc */
2121 (traverseproc)buffered_traverse, /* tp_traverse */
2122 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002124 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002125 0, /* tp_iter */
2126 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002127 bufferedwriter_methods, /* tp_methods */
2128 bufferedwriter_members, /* tp_members */
2129 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130 0, /* tp_base */
2131 0, /* tp_dict */
2132 0, /* tp_descr_get */
2133 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002134 offsetof(buffered, dict), /* tp_dictoffset */
2135 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002136 0, /* tp_alloc */
2137 PyType_GenericNew, /* tp_new */
2138};
2139
2140
2141
2142/*
2143 * BufferedRWPair
2144 */
2145
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002146PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147 "A buffered reader and writer object together.\n"
2148 "\n"
2149 "A buffered reader object and buffered writer object put together to\n"
2150 "form a sequential IO object that can read and write. This is typically\n"
2151 "used with a socket or two-way pipe.\n"
2152 "\n"
2153 "reader and writer are RawIOBase objects that are readable and\n"
2154 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002155 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 );
2157
2158/* XXX The usefulness of this (compared to having two separate IO objects) is
2159 * questionable.
2160 */
2161
2162typedef struct {
2163 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002164 buffered *reader;
2165 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 PyObject *dict;
2167 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169
2170static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002171bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172{
2173 PyObject *reader, *writer;
2174 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002175 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002176
2177 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2178 &buffer_size, &max_buffer_size)) {
2179 return -1;
2180 }
2181
Benjamin Peterson59406a92009-03-26 17:10:29 +00002182 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2183 return -1;
2184
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002185 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188 return -1;
2189
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002191 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 if (self->reader == NULL)
2193 return -1;
2194
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002195 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002196 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 if (self->writer == NULL) {
2198 Py_CLEAR(self->reader);
2199 return -1;
2200 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002201
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 return 0;
2203}
2204
2205static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002206bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207{
2208 Py_VISIT(self->dict);
2209 return 0;
2210}
2211
2212static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002213bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214{
2215 Py_CLEAR(self->reader);
2216 Py_CLEAR(self->writer);
2217 Py_CLEAR(self->dict);
2218 return 0;
2219}
2220
2221static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
2224 _PyObject_GC_UNTRACK(self);
2225 Py_CLEAR(self->reader);
2226 Py_CLEAR(self->writer);
2227 Py_CLEAR(self->dict);
2228 Py_TYPE(self)->tp_free((PyObject *) self);
2229}
2230
2231static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002232_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002234 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235 PyObject *ret;
2236
2237 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002238 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239 return NULL;
2240 }
2241
2242 ret = PyObject_CallObject(func, args);
2243 Py_DECREF(func);
2244 return ret;
2245}
2246
2247static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002248bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002250 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251}
2252
2253static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002254bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002256 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002257}
2258
2259static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002260bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002262 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263}
2264
2265static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002266bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002267{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002268 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002269}
2270
2271static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002272bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002274 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002275}
2276
2277static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002278bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002279{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002280 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281}
2282
2283static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002284bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002285{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002286 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002287}
2288
2289static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002290bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002292 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293}
2294
2295static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002296bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002298 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299 if (ret == NULL)
2300 return NULL;
2301 Py_DECREF(ret);
2302
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002303 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002304}
2305
2306static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002307bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002309 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002310
2311 if (ret != Py_False) {
2312 /* either True or exception */
2313 return ret;
2314 }
2315 Py_DECREF(ret);
2316
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002317 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002318}
2319
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002320static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002321bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002322{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002323 if (self->writer == NULL) {
2324 PyErr_SetString(PyExc_RuntimeError,
2325 "the BufferedRWPair object is being garbage-collected");
2326 return NULL;
2327 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002328 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2329}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002330
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002331static PyMethodDef bufferedrwpair_methods[] = {
2332 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2333 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2334 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2335 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002336
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002337 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2338 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002340 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2341 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002342
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002343 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2344 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002345
Antoine Pitrou243757e2010-11-05 21:15:39 +00002346 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2347
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002348 {NULL, NULL}
2349};
2350
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002351static PyGetSetDef bufferedrwpair_getset[] = {
2352 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002353 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002354};
2355
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002356PyTypeObject PyBufferedRWPair_Type = {
2357 PyVarObject_HEAD_INIT(NULL, 0)
2358 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002359 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002360 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002361 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002362 0, /*tp_print*/
2363 0, /*tp_getattr*/
2364 0, /*tp_setattr*/
2365 0, /*tp_compare */
2366 0, /*tp_repr*/
2367 0, /*tp_as_number*/
2368 0, /*tp_as_sequence*/
2369 0, /*tp_as_mapping*/
2370 0, /*tp_hash */
2371 0, /*tp_call*/
2372 0, /*tp_str*/
2373 0, /*tp_getattro*/
2374 0, /*tp_setattro*/
2375 0, /*tp_as_buffer*/
2376 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2377 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002378 bufferedrwpair_doc, /* tp_doc */
2379 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2380 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002381 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002382 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002383 0, /* tp_iter */
2384 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002385 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002386 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002387 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388 0, /* tp_base */
2389 0, /* tp_dict */
2390 0, /* tp_descr_get */
2391 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002392 offsetof(rwpair, dict), /* tp_dictoffset */
2393 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394 0, /* tp_alloc */
2395 PyType_GenericNew, /* tp_new */
2396};
2397
2398
2399
2400/*
2401 * BufferedRandom
2402 */
2403
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002404PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002405 "A buffered interface to random access streams.\n"
2406 "\n"
2407 "The constructor creates a reader and writer for a seekable stream,\n"
2408 "raw, given in the first argument. If the buffer_size is omitted it\n"
2409 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2410 );
2411
2412static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002413bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002414{
2415 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2416 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002417 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 PyObject *raw;
2419
2420 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002421 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002422
2423 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2424 &raw, &buffer_size, &max_buffer_size)) {
2425 return -1;
2426 }
2427
Benjamin Peterson59406a92009-03-26 17:10:29 +00002428 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2429 return -1;
2430
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002431 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002433 if (_PyIOBase_check_readable(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_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436 return -1;
2437
2438 Py_CLEAR(self->raw);
2439 Py_INCREF(raw);
2440 self->raw = raw;
2441 self->buffer_size = buffer_size;
2442 self->readable = 1;
2443 self->writable = 1;
2444
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002445 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002446 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002447 _bufferedreader_reset_buf(self);
2448 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002449 self->pos = 0;
2450
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002451 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2452 Py_TYPE(raw) == &PyFileIO_Type);
2453
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002454 self->ok = 1;
2455 return 0;
2456}
2457
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002458static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002460 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2461 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2462 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2463 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2464 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2465 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2466 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002467 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002468 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002469
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002470 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002471
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002472 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2473 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2474 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2475 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2476 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2477 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2478 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2479 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2480 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002481 {NULL, NULL}
2482};
2483
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002484static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002485 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002486 {NULL}
2487};
2488
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002489static PyGetSetDef bufferedrandom_getset[] = {
2490 {"closed", (getter)buffered_closed_get, NULL, NULL},
2491 {"name", (getter)buffered_name_get, NULL, NULL},
2492 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002493 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494};
2495
2496
2497PyTypeObject PyBufferedRandom_Type = {
2498 PyVarObject_HEAD_INIT(NULL, 0)
2499 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002500 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002501 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002502 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002503 0, /*tp_print*/
2504 0, /*tp_getattr*/
2505 0, /*tp_setattr*/
2506 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002507 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002508 0, /*tp_as_number*/
2509 0, /*tp_as_sequence*/
2510 0, /*tp_as_mapping*/
2511 0, /*tp_hash */
2512 0, /*tp_call*/
2513 0, /*tp_str*/
2514 0, /*tp_getattro*/
2515 0, /*tp_setattro*/
2516 0, /*tp_as_buffer*/
2517 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2518 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002519 bufferedrandom_doc, /* tp_doc */
2520 (traverseproc)buffered_traverse, /* tp_traverse */
2521 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002522 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002523 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002524 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002525 (iternextfunc)buffered_iternext, /* tp_iternext */
2526 bufferedrandom_methods, /* tp_methods */
2527 bufferedrandom_members, /* tp_members */
2528 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002529 0, /* tp_base */
2530 0, /*tp_dict*/
2531 0, /* tp_descr_get */
2532 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002533 offsetof(buffered, dict), /*tp_dictoffset*/
2534 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 0, /* tp_alloc */
2536 PyType_GenericNew, /* tp_new */
2537};