blob: 21e6b36068a0c517a3bb6b53f22689be4c6cd18a [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"
3
4 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
6
7 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
16/*
17 * BufferedIOBase class, inherits from IOBase.
18 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000019PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000020 "Base class for buffered IO objects.\n"
21 "\n"
22 "The main difference with RawIOBase is that the read() method\n"
23 "supports omitting the size argument, and does not have a default\n"
24 "implementation that defers to readinto().\n"
25 "\n"
26 "In addition, read(), readinto() and write() may raise\n"
27 "BlockingIOError if the underlying raw stream is in non-blocking\n"
28 "mode and not ready; unlike their raw counterparts, they will never\n"
29 "return None.\n"
30 "\n"
31 "A typical implementation should not inherit from a RawIOBase\n"
32 "implementation, but wrap one.\n"
33 );
34
35static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000036bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000037{
38 Py_buffer buf;
39 Py_ssize_t len;
40 PyObject *data;
41
42 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
43 return NULL;
44 }
45
46 data = PyObject_CallMethod(self, "read", "n", buf.len);
47 if (data == NULL)
48 goto error;
49
50 if (!PyBytes_Check(data)) {
51 Py_DECREF(data);
52 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
53 goto error;
54 }
55
56 len = Py_SIZE(data);
57 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
58
59 PyBuffer_Release(&buf);
60 Py_DECREF(data);
61
62 return PyLong_FromSsize_t(len);
63
64 error:
65 PyBuffer_Release(&buf);
66 return NULL;
67}
68
69static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000070bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071{
72 PyErr_SetString(IO_STATE->unsupported_operation, message);
73 return NULL;
74}
75
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000076PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000077 "Disconnect this buffer from its underlying raw stream and return it.\n"
78 "\n"
79 "After the raw stream has been detached, the buffer is in an unusable\n"
80 "state.\n");
81
82static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000083bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +000084{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000085 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +000086}
87
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000088PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000089 "Read and return up to n bytes.\n"
90 "\n"
91 "If the argument is omitted, None, or negative, reads and\n"
92 "returns all data until EOF.\n"
93 "\n"
94 "If the argument is positive, and the underlying raw stream is\n"
95 "not 'interactive', multiple raw reads may be issued to satisfy\n"
96 "the byte count (unless EOF is reached first). But for\n"
97 "interactive raw streams (as well as sockets and pipes), at most\n"
98 "one raw read will be issued, and a short result does not imply\n"
99 "that EOF is imminent.\n"
100 "\n"
101 "Returns an empty bytes object on EOF.\n"
102 "\n"
103 "Returns None if the underlying raw stream was open in non-blocking\n"
104 "mode and no data is available at the moment.\n");
105
106static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000107bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000108{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000109 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000110}
111
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000112PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000113 "Read and return up to n bytes, with at most one read() call\n"
114 "to the underlying raw stream. A short result does not imply\n"
115 "that EOF is imminent.\n"
116 "\n"
117 "Returns an empty bytes object on EOF.\n");
118
119static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000120bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000121{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123}
124
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000125PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000126 "Write the given buffer to the IO stream.\n"
127 "\n"
128 "Returns the number of bytes written, which is never less than\n"
129 "len(b).\n"
130 "\n"
131 "Raises BlockingIOError if the buffer is full and the\n"
132 "underlying raw stream cannot accept more data at the moment.\n");
133
134static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000137 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000138}
139
140
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000141static PyMethodDef bufferediobase_methods[] = {
142 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
143 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
144 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
145 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
146 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000147 {NULL, NULL}
148};
149
150PyTypeObject PyBufferedIOBase_Type = {
151 PyVarObject_HEAD_INIT(NULL, 0)
152 "_io._BufferedIOBase", /*tp_name*/
153 0, /*tp_basicsize*/
154 0, /*tp_itemsize*/
155 0, /*tp_dealloc*/
156 0, /*tp_print*/
157 0, /*tp_getattr*/
158 0, /*tp_setattr*/
159 0, /*tp_compare */
160 0, /*tp_repr*/
161 0, /*tp_as_number*/
162 0, /*tp_as_sequence*/
163 0, /*tp_as_mapping*/
164 0, /*tp_hash */
165 0, /*tp_call*/
166 0, /*tp_str*/
167 0, /*tp_getattro*/
168 0, /*tp_setattro*/
169 0, /*tp_as_buffer*/
170 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000171 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000172 0, /* tp_traverse */
173 0, /* tp_clear */
174 0, /* tp_richcompare */
175 0, /* tp_weaklistoffset */
176 0, /* tp_iter */
177 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000178 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000179 0, /* tp_members */
180 0, /* tp_getset */
181 &PyIOBase_Type, /* tp_base */
182 0, /* tp_dict */
183 0, /* tp_descr_get */
184 0, /* tp_descr_set */
185 0, /* tp_dictoffset */
186 0, /* tp_init */
187 0, /* tp_alloc */
188 0, /* tp_new */
189};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000190
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000191
192typedef struct {
193 PyObject_HEAD
194
195 PyObject *raw;
196 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000197 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000198 int readable;
199 int writable;
Antoine Pitroue033e062010-10-29 10:38:18 +0000200 int deallocating;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000201
202 /* True if this is a vanilla Buffered object (rather than a user derived
203 class) *and* the raw stream is a vanilla FileIO object. */
204 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000205
206 /* Absolute position inside the raw stream (-1 if unknown). */
207 Py_off_t abs_pos;
208
209 /* A static buffer of size `buffer_size` */
210 char *buffer;
211 /* Current logical position in the buffer. */
212 Py_off_t pos;
213 /* Position of the raw stream in the buffer. */
214 Py_off_t raw_pos;
215
216 /* Just after the last buffered byte in the buffer, or -1 if the buffer
217 isn't ready for reading. */
218 Py_off_t read_end;
219
220 /* Just after the last byte actually written */
221 Py_off_t write_pos;
222 /* Just after the last byte waiting to be written, or -1 if the buffer
223 isn't ready for writing. */
224 Py_off_t write_end;
225
Georg Brandldfd73442009-04-05 11:47:34 +0000226#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000227 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000228 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000229#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000230
231 Py_ssize_t buffer_size;
232 Py_ssize_t buffer_mask;
233
234 PyObject *dict;
235 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000236} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000237
238/*
239 Implementation notes:
240
241 * BufferedReader, BufferedWriter and BufferedRandom try to share most
242 methods (this is helped by the members `readable` and `writable`, which
243 are initialized in the respective constructors)
244 * They also share a single buffer for reading and writing. This enables
245 interleaved reads and writes without flushing. It also makes the logic
246 a bit trickier to get right.
247 * The absolute position of the raw stream is cached, if possible, in the
248 `abs_pos` member. It must be updated every time an operation is done
249 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000250 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000252 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
253 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000254
255 NOTE: we should try to maintain block alignment of reads and writes to the
256 raw stream (according to the buffer size), but for now it is only done
257 in read() and friends.
258
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000259*/
260
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000261/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000262
Georg Brandldfd73442009-04-05 11:47:34 +0000263#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000264
265static int
266_enter_buffered_busy(buffered *self)
267{
268 if (self->owner == PyThread_get_thread_ident()) {
269 PyErr_Format(PyExc_RuntimeError,
270 "reentrant call inside %R", self);
271 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000272 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000273 Py_BEGIN_ALLOW_THREADS
274 PyThread_acquire_lock(self->lock, 1);
275 Py_END_ALLOW_THREADS
276 return 1;
277}
278
279#define ENTER_BUFFERED(self) \
280 ( (PyThread_acquire_lock(self->lock, 0) ? \
281 1 : _enter_buffered_busy(self)) \
282 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000283
284#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000285 do { \
286 self->owner = 0; \
287 PyThread_release_lock(self->lock); \
288 } while(0);
289
Georg Brandldfd73442009-04-05 11:47:34 +0000290#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000291#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000292#define LEAVE_BUFFERED(self)
293#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000294
295#define CHECK_INITIALIZED(self) \
296 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000297 if (self->detached) { \
298 PyErr_SetString(PyExc_ValueError, \
299 "raw stream has been detached"); \
300 } else { \
301 PyErr_SetString(PyExc_ValueError, \
302 "I/O operation on uninitialized object"); \
303 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000304 return NULL; \
305 }
306
307#define CHECK_INITIALIZED_INT(self) \
308 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000309 if (self->detached) { \
310 PyErr_SetString(PyExc_ValueError, \
311 "raw stream has been detached"); \
312 } else { \
313 PyErr_SetString(PyExc_ValueError, \
314 "I/O operation on uninitialized object"); \
315 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000316 return -1; \
317 }
318
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000319#define IS_CLOSED(self) \
320 (self->fast_closed_checks \
321 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000322 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000323
324#define CHECK_CLOSED(self, error_msg) \
325 if (IS_CLOSED(self)) { \
326 PyErr_SetString(PyExc_ValueError, error_msg); \
327 return NULL; \
328 }
329
330
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000331#define VALID_READ_BUFFER(self) \
332 (self->readable && self->read_end != -1)
333
334#define VALID_WRITE_BUFFER(self) \
335 (self->writable && self->write_end != -1)
336
337#define ADJUST_POSITION(self, _new_pos) \
338 do { \
339 self->pos = _new_pos; \
340 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
341 self->read_end = self->pos; \
342 } while(0)
343
344#define READAHEAD(self) \
345 ((self->readable && VALID_READ_BUFFER(self)) \
346 ? (self->read_end - self->pos) : 0)
347
348#define RAW_OFFSET(self) \
349 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
350 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
351
352#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000353 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354
355#define MINUS_LAST_BLOCK(self, size) \
356 (self->buffer_mask ? \
357 (size & ~self->buffer_mask) : \
358 (self->buffer_size * (size / self->buffer_size)))
359
360
361static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000362buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000363{
Antoine Pitroue033e062010-10-29 10:38:18 +0000364 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000365 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
366 return;
367 _PyObject_GC_UNTRACK(self);
368 self->ok = 0;
369 if (self->weakreflist != NULL)
370 PyObject_ClearWeakRefs((PyObject *)self);
371 Py_CLEAR(self->raw);
372 if (self->buffer) {
373 PyMem_Free(self->buffer);
374 self->buffer = NULL;
375 }
Georg Brandldfd73442009-04-05 11:47:34 +0000376#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000377 if (self->lock) {
378 PyThread_free_lock(self->lock);
379 self->lock = NULL;
380 }
Georg Brandldfd73442009-04-05 11:47:34 +0000381#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000382 Py_CLEAR(self->dict);
383 Py_TYPE(self)->tp_free((PyObject *)self);
384}
385
386static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000387buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388{
389 Py_VISIT(self->raw);
390 Py_VISIT(self->dict);
391 return 0;
392}
393
394static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000395buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000396{
397 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
398 return -1;
399 self->ok = 0;
400 Py_CLEAR(self->raw);
401 Py_CLEAR(self->dict);
402 return 0;
403}
404
Antoine Pitroue033e062010-10-29 10:38:18 +0000405/* Because this can call arbitrary code, it shouldn't be called when
406 the refcount is 0 (that is, not directly from tp_dealloc unless
407 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000408static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000409buffered_dealloc_warn(buffered *self, PyObject *source)
410{
411 if (self->ok && self->raw) {
412 PyObject *r;
413 r = PyObject_CallMethod(self->raw, "_dealloc_warn", "O", source);
414 if (r)
415 Py_DECREF(r);
416 else
417 PyErr_Clear();
418 }
419 Py_RETURN_NONE;
420}
421
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422/*
423 * _BufferedIOMixin methods
424 * This is not a class, just a collection of methods that will be reused
425 * by BufferedReader and BufferedWriter
426 */
427
428/* Flush and close */
429
430static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000431buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000432{
433 CHECK_INITIALIZED(self)
434 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
435}
436
437static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000438buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000439{
440 int closed;
441 PyObject *res;
442 CHECK_INITIALIZED_INT(self)
443 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
444 if (res == NULL)
445 return -1;
446 closed = PyObject_IsTrue(res);
447 Py_DECREF(res);
448 return closed;
449}
450
451static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000452buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000453{
454 CHECK_INITIALIZED(self)
455 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
456}
457
458static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000459buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000460{
461 PyObject *res = NULL;
462 int r;
463
464 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000465 if (!ENTER_BUFFERED(self))
466 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000467
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000468 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000469 if (r < 0)
470 goto end;
471 if (r > 0) {
472 res = Py_None;
473 Py_INCREF(res);
474 goto end;
475 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000476
477 if (self->deallocating) {
478 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
479 if (r)
480 Py_DECREF(r);
481 else
482 PyErr_Clear();
483 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000484 /* flush() will most probably re-take the lock, so drop it first */
485 LEAVE_BUFFERED(self)
486 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000487 if (!ENTER_BUFFERED(self))
488 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489 if (res == NULL) {
Antoine Pitrou6be88762010-05-03 16:48:20 +0000490 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491 }
492 Py_XDECREF(res);
493
494 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
495
496end:
497 LEAVE_BUFFERED(self)
498 return res;
499}
500
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000501/* detach */
502
503static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000504buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000505{
506 PyObject *raw, *res;
507 CHECK_INITIALIZED(self)
508 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
509 if (res == NULL)
510 return NULL;
511 Py_DECREF(res);
512 raw = self->raw;
513 self->raw = NULL;
514 self->detached = 1;
515 self->ok = 0;
516 return raw;
517}
518
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519/* Inquiries */
520
521static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000522buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000523{
524 CHECK_INITIALIZED(self)
525 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
526}
527
528static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000529buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000530{
531 CHECK_INITIALIZED(self)
532 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
533}
534
535static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000536buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000537{
538 CHECK_INITIALIZED(self)
539 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
540}
541
542static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000543buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000544{
545 CHECK_INITIALIZED(self)
546 return PyObject_GetAttrString(self->raw, "name");
547}
548
549static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000550buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551{
552 CHECK_INITIALIZED(self)
553 return PyObject_GetAttrString(self->raw, "mode");
554}
555
556/* Lower-level APIs */
557
558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000560{
561 CHECK_INITIALIZED(self)
562 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
563}
564
565static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000566buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000567{
568 CHECK_INITIALIZED(self)
569 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
570}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000571
Antoine Pitrou243757e2010-11-05 21:15:39 +0000572/* Serialization */
573
574static PyObject *
575buffered_getstate(buffered *self, PyObject *args)
576{
577 PyErr_Format(PyExc_TypeError,
578 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
579 return NULL;
580}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000581
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582/* Forward decls */
583static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100584_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000586_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000587static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000590_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000592_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000594_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000595static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000596_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599
600
601/*
602 * Helpers
603 */
604
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100605/* Sets the current error to BlockingIOError */
606static void
607_set_BlockingIOError(char *msg, Py_ssize_t written)
608{
609 PyObject *err;
610 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
611 errno, msg, written);
612 if (err)
613 PyErr_SetObject(PyExc_BlockingIOError, err);
614 Py_XDECREF(err);
615}
616
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617/* Returns the address of the `written` member if a BlockingIOError was
618 raised, NULL otherwise. The error is always re-raised. */
619static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000621{
622 PyObject *t, *v, *tb;
623 PyBlockingIOErrorObject *err;
624
625 PyErr_Fetch(&t, &v, &tb);
626 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
627 PyErr_Restore(t, v, tb);
628 return NULL;
629 }
630 err = (PyBlockingIOErrorObject *) v;
631 /* TODO: sanity check (err->written >= 0) */
632 PyErr_Restore(t, v, tb);
633 return &err->written;
634}
635
636static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000637_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000638{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000640 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
642 if (res == NULL)
643 return -1;
644 n = PyNumber_AsOff_t(res, PyExc_ValueError);
645 Py_DECREF(res);
646 if (n < 0) {
647 if (!PyErr_Occurred())
648 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000649 "Raw stream returned invalid position %" PY_PRIdOFF,
650 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651 return -1;
652 }
653 self->abs_pos = n;
654 return n;
655}
656
657static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000658_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000659{
660 PyObject *res, *posobj, *whenceobj;
661 Py_off_t n;
662
663 posobj = PyLong_FromOff_t(target);
664 if (posobj == NULL)
665 return -1;
666 whenceobj = PyLong_FromLong(whence);
667 if (whenceobj == NULL) {
668 Py_DECREF(posobj);
669 return -1;
670 }
671 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
672 posobj, whenceobj, NULL);
673 Py_DECREF(posobj);
674 Py_DECREF(whenceobj);
675 if (res == NULL)
676 return -1;
677 n = PyNumber_AsOff_t(res, PyExc_ValueError);
678 Py_DECREF(res);
679 if (n < 0) {
680 if (!PyErr_Occurred())
681 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000682 "Raw stream returned invalid position %" PY_PRIdOFF,
683 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684 return -1;
685 }
686 self->abs_pos = n;
687 return n;
688}
689
690static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000691_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692{
693 Py_ssize_t n;
694 if (self->buffer_size <= 0) {
695 PyErr_SetString(PyExc_ValueError,
696 "buffer size must be strictly positive");
697 return -1;
698 }
699 if (self->buffer)
700 PyMem_Free(self->buffer);
701 self->buffer = PyMem_Malloc(self->buffer_size);
702 if (self->buffer == NULL) {
703 PyErr_NoMemory();
704 return -1;
705 }
Georg Brandldfd73442009-04-05 11:47:34 +0000706#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000707 if (self->lock)
708 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709 self->lock = PyThread_allocate_lock();
710 if (self->lock == NULL) {
711 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
712 return -1;
713 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000714 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000715#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716 /* Find out whether buffer_size is a power of 2 */
717 /* XXX is this optimization useful? */
718 for (n = self->buffer_size - 1; n & 1; n >>= 1)
719 ;
720 if (n == 0)
721 self->buffer_mask = self->buffer_size - 1;
722 else
723 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000724 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000725 PyErr_Clear();
726 return 0;
727}
728
Antoine Pitroud843c2d2011-02-25 21:34:39 +0000729/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
730 clears the error indicator), 0 otherwise.
731 Should only be called when PyErr_Occurred() is true.
732*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700733int
734_PyIO_trap_eintr(void)
Antoine Pitroud843c2d2011-02-25 21:34:39 +0000735{
736 static PyObject *eintr_int = NULL;
737 PyObject *typ, *val, *tb;
738 PyEnvironmentErrorObject *env_err;
739
740 if (eintr_int == NULL) {
741 eintr_int = PyLong_FromLong(EINTR);
742 assert(eintr_int != NULL);
743 }
744 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
745 return 0;
746 PyErr_Fetch(&typ, &val, &tb);
747 PyErr_NormalizeException(&typ, &val, &tb);
748 env_err = (PyEnvironmentErrorObject *) val;
749 assert(env_err != NULL);
750 if (env_err->myerrno != NULL &&
751 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
752 Py_DECREF(typ);
753 Py_DECREF(val);
754 Py_XDECREF(tb);
755 return 1;
756 }
757 /* This silences any error set by PyObject_RichCompareBool() */
758 PyErr_Restore(typ, val, tb);
759 return 0;
760}
761
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000762/*
763 * Shared methods and wrappers
764 */
765
766static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200767buffered_flush_and_rewind_unlocked(buffered *self)
768{
769 PyObject *res;
770
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100771 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200772 if (res == NULL)
773 return NULL;
774 Py_DECREF(res);
775
776 if (self->readable) {
777 /* Rewind the raw stream so that its position corresponds to
778 the current logical position. */
779 Py_off_t n;
780 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
781 _bufferedreader_reset_buf(self);
782 if (n == -1)
783 return NULL;
784 }
785 Py_RETURN_NONE;
786}
787
788static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000789buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000790{
791 PyObject *res;
792
793 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000794 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000795
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000796 if (!ENTER_BUFFERED(self))
797 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200798 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000799 LEAVE_BUFFERED(self)
800
801 return res;
802}
803
804static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000805buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000806{
807 Py_ssize_t n = 0;
808 PyObject *res = NULL;
809
810 CHECK_INITIALIZED(self)
811 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
812 return NULL;
813 }
814
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000815 if (!ENTER_BUFFERED(self))
816 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000817
818 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200819 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000820 if (res == NULL)
821 goto end;
822 Py_CLEAR(res);
823 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000824 res = _bufferedreader_peek_unlocked(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000825
826end:
827 LEAVE_BUFFERED(self)
828 return res;
829}
830
831static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000832buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833{
834 Py_ssize_t n = -1;
835 PyObject *res;
836
837 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000838 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000839 return NULL;
840 }
841 if (n < -1) {
842 PyErr_SetString(PyExc_ValueError,
843 "read length must be positive or -1");
844 return NULL;
845 }
846
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000847 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000848
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000849 if (n == -1) {
850 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000851 if (!ENTER_BUFFERED(self))
852 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000853 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000854 }
855 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000856 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200857 if (res != Py_None)
858 return res;
859 Py_DECREF(res);
860 if (!ENTER_BUFFERED(self))
861 return NULL;
862 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000863 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864
Antoine Pitroue05565e2011-08-20 14:39:23 +0200865 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866 return res;
867}
868
869static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000870buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871{
872 Py_ssize_t n, have, r;
873 PyObject *res = NULL;
874
875 CHECK_INITIALIZED(self)
876 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
877 return NULL;
878 }
879
880 if (n < 0) {
881 PyErr_SetString(PyExc_ValueError,
882 "read length must be positive");
883 return NULL;
884 }
885 if (n == 0)
886 return PyBytes_FromStringAndSize(NULL, 0);
887
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000888 if (!ENTER_BUFFERED(self))
889 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000891 /* Return up to n bytes. If at least one byte is buffered, we
892 only return buffered bytes. Otherwise, we do one raw read. */
893
894 /* XXX: this mimicks the io.py implementation but is probably wrong.
895 If we need to read from the raw stream, then we could actually read
896 all `n` bytes asked by the caller (and possibly more, so as to fill
897 our buffer for the next reads). */
898
899 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
900 if (have > 0) {
901 if (n > have)
902 n = have;
903 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
904 if (res == NULL)
905 goto end;
906 self->pos += n;
907 goto end;
908 }
909
Antoine Pitroue05565e2011-08-20 14:39:23 +0200910 if (self->writable) {
911 res = buffered_flush_and_rewind_unlocked(self);
912 if (res == NULL)
913 goto end;
914 Py_DECREF(res);
915 }
916
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000918 _bufferedreader_reset_buf(self);
919 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 if (r == -1)
921 goto end;
922 if (r == -2)
923 r = 0;
924 if (n > r)
925 n = r;
926 res = PyBytes_FromStringAndSize(self->buffer, n);
927 if (res == NULL)
928 goto end;
929 self->pos = n;
930
931end:
932 LEAVE_BUFFERED(self)
933 return res;
934}
935
936static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000937buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 CHECK_INITIALIZED(self)
940
Antoine Pitroue05565e2011-08-20 14:39:23 +0200941 /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
942 return bufferediobase_readinto((PyObject *)self, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943}
944
945static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000946_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947{
948 PyObject *res = NULL;
949 PyObject *chunks = NULL;
950 Py_ssize_t n, written = 0;
951 const char *start, *s, *end;
952
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000953 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000955 /* First, try to find a line in the buffer. This can run unlocked because
956 the calls to the C API are simple enough that they can't trigger
957 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
959 if (limit >= 0 && n > limit)
960 n = limit;
961 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000962 s = memchr(start, '\n', n);
963 if (s != NULL) {
964 res = PyBytes_FromStringAndSize(start, s - start + 1);
965 if (res != NULL)
966 self->pos += s - start + 1;
967 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 }
969 if (n == limit) {
970 res = PyBytes_FromStringAndSize(start, n);
971 if (res != NULL)
972 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000973 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000974 }
975
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000976 if (!ENTER_BUFFERED(self))
977 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000978
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000979 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 chunks = PyList_New(0);
981 if (chunks == NULL)
982 goto end;
983 if (n > 0) {
984 res = PyBytes_FromStringAndSize(start, n);
985 if (res == NULL)
986 goto end;
987 if (PyList_Append(chunks, res) < 0) {
988 Py_CLEAR(res);
989 goto end;
990 }
991 Py_CLEAR(res);
992 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200993 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000994 if (limit >= 0)
995 limit -= n;
996 }
Antoine Pitroue05565e2011-08-20 14:39:23 +0200997 if (self->writable) {
998 PyObject *r = buffered_flush_and_rewind_unlocked(self);
999 if (r == NULL)
1000 goto end;
1001 Py_DECREF(r);
1002 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003
1004 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001005 _bufferedreader_reset_buf(self);
1006 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001007 if (n == -1)
1008 goto end;
1009 if (n <= 0)
1010 break;
1011 if (limit >= 0 && n > limit)
1012 n = limit;
1013 start = self->buffer;
1014 end = start + n;
1015 s = start;
1016 while (s < end) {
1017 if (*s++ == '\n') {
1018 res = PyBytes_FromStringAndSize(start, s - start);
1019 if (res == NULL)
1020 goto end;
1021 self->pos = s - start;
1022 goto found;
1023 }
1024 }
1025 res = PyBytes_FromStringAndSize(start, n);
1026 if (res == NULL)
1027 goto end;
1028 if (n == limit) {
1029 self->pos = n;
1030 break;
1031 }
1032 if (PyList_Append(chunks, res) < 0) {
1033 Py_CLEAR(res);
1034 goto end;
1035 }
1036 Py_CLEAR(res);
1037 written += n;
1038 if (limit >= 0)
1039 limit -= n;
1040 }
1041found:
1042 if (res != NULL && PyList_Append(chunks, res) < 0) {
1043 Py_CLEAR(res);
1044 goto end;
1045 }
1046 Py_CLEAR(res);
1047 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1048
1049end:
1050 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001051end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001052 Py_XDECREF(chunks);
1053 return res;
1054}
1055
1056static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001057buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058{
1059 Py_ssize_t limit = -1;
1060
1061 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001062 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001063 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001064 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065}
1066
1067
1068static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001069buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070{
1071 Py_off_t pos;
1072
1073 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001074 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075 if (pos == -1)
1076 return NULL;
1077 pos -= RAW_OFFSET(self);
1078 /* TODO: sanity check (pos >= 0) */
1079 return PyLong_FromOff_t(pos);
1080}
1081
1082static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001083buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001084{
1085 Py_off_t target, n;
1086 int whence = 0;
1087 PyObject *targetobj, *res = NULL;
1088
1089 CHECK_INITIALIZED(self)
1090 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1091 return NULL;
1092 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001093 if (whence < 0 || whence > 2) {
1094 PyErr_Format(PyExc_ValueError,
1095 "whence must be between 0 and 2, not %d", whence);
1096 return NULL;
1097 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001098
1099 CHECK_CLOSED(self, "seek of closed file")
1100
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001101 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1102 return NULL;
1103
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001104 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1105 if (target == -1 && PyErr_Occurred())
1106 return NULL;
1107
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001108 if (whence != 2 && self->readable) {
1109 Py_off_t current, avail;
1110 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001111 so as to return quickly if possible. Also, we needn't take the
1112 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001114 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1115 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001116 current = RAW_TELL(self);
1117 avail = READAHEAD(self);
1118 if (avail > 0) {
1119 Py_off_t offset;
1120 if (whence == 0)
1121 offset = target - (current - RAW_OFFSET(self));
1122 else
1123 offset = target;
1124 if (offset >= -self->pos && offset <= avail) {
1125 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001126 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127 }
1128 }
1129 }
1130
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001131 if (!ENTER_BUFFERED(self))
1132 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001133
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001134 /* Fallback: invoke raw seek() method and clear buffer */
1135 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001136 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001137 if (res == NULL)
1138 goto end;
1139 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001140 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001141 }
1142
1143 /* TODO: align on block boundary and read buffer if needed? */
1144 if (whence == 1)
1145 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001146 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147 if (n == -1)
1148 goto end;
1149 self->raw_pos = -1;
1150 res = PyLong_FromOff_t(n);
1151 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001152 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001153
1154end:
1155 LEAVE_BUFFERED(self)
1156 return res;
1157}
1158
1159static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001160buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001161{
1162 PyObject *pos = Py_None;
1163 PyObject *res = NULL;
1164
1165 CHECK_INITIALIZED(self)
1166 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1167 return NULL;
1168 }
1169
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001170 if (!ENTER_BUFFERED(self))
1171 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172
1173 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001174 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001175 if (res == NULL)
1176 goto end;
1177 Py_CLEAR(res);
1178 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001179 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1180 if (res == NULL)
1181 goto end;
1182 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001183 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001184 PyErr_Clear();
1185
1186end:
1187 LEAVE_BUFFERED(self)
1188 return res;
1189}
1190
1191static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001192buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001193{
1194 PyObject *line;
1195 PyTypeObject *tp;
1196
1197 CHECK_INITIALIZED(self);
1198
1199 tp = Py_TYPE(self);
1200 if (tp == &PyBufferedReader_Type ||
1201 tp == &PyBufferedRandom_Type) {
1202 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001203 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204 }
1205 else {
1206 line = PyObject_CallMethodObjArgs((PyObject *)self,
1207 _PyIO_str_readline, NULL);
1208 if (line && !PyBytes_Check(line)) {
1209 PyErr_Format(PyExc_IOError,
1210 "readline() should have returned a bytes object, "
1211 "not '%.200s'", Py_TYPE(line)->tp_name);
1212 Py_DECREF(line);
1213 return NULL;
1214 }
1215 }
1216
1217 if (line == NULL)
1218 return NULL;
1219
1220 if (PyBytes_GET_SIZE(line) == 0) {
1221 /* Reached EOF or would have blocked */
1222 Py_DECREF(line);
1223 return NULL;
1224 }
1225
1226 return line;
1227}
1228
Antoine Pitrou716c4442009-05-23 19:04:03 +00001229static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001230buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001231{
1232 PyObject *nameobj, *res;
1233
1234 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1235 if (nameobj == NULL) {
1236 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1237 PyErr_Clear();
1238 else
1239 return NULL;
1240 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1241 }
1242 else {
1243 res = PyUnicode_FromFormat("<%s name=%R>",
1244 Py_TYPE(self)->tp_name, nameobj);
1245 Py_DECREF(nameobj);
1246 }
1247 return res;
1248}
1249
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250/*
1251 * class BufferedReader
1252 */
1253
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001254PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001255 "Create a new buffered reader using the given readable raw IO object.");
1256
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001257static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001258{
1259 self->read_end = -1;
1260}
1261
1262static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001263bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264{
1265 char *kwlist[] = {"raw", "buffer_size", NULL};
1266 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1267 PyObject *raw;
1268
1269 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001270 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001271
1272 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1273 &raw, &buffer_size)) {
1274 return -1;
1275 }
1276
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001277 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278 return -1;
1279
1280 Py_CLEAR(self->raw);
1281 Py_INCREF(raw);
1282 self->raw = raw;
1283 self->buffer_size = buffer_size;
1284 self->readable = 1;
1285 self->writable = 0;
1286
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001287 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001289 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001291 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1292 Py_TYPE(raw) == &PyFileIO_Type);
1293
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001294 self->ok = 1;
1295 return 0;
1296}
1297
1298static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001299_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300{
1301 Py_buffer buf;
1302 PyObject *memobj, *res;
1303 Py_ssize_t n;
1304 /* NOTE: the buffer needn't be released as its object is NULL. */
1305 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1306 return -1;
1307 memobj = PyMemoryView_FromBuffer(&buf);
1308 if (memobj == NULL)
1309 return -1;
Antoine Pitroud843c2d2011-02-25 21:34:39 +00001310 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1311 occurs so we needn't do it ourselves.
1312 We then retry reading, ignoring the signal if no handler has
1313 raised (see issue #10956).
1314 */
1315 do {
1316 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001317 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001318 Py_DECREF(memobj);
1319 if (res == NULL)
1320 return -1;
1321 if (res == Py_None) {
1322 /* Non-blocking stream would have blocked. Special return code! */
1323 Py_DECREF(res);
1324 return -2;
1325 }
1326 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1327 Py_DECREF(res);
1328 if (n < 0 || n > len) {
1329 PyErr_Format(PyExc_IOError,
1330 "raw readinto() returned invalid length %zd "
1331 "(should have been between 0 and %zd)", n, len);
1332 return -1;
1333 }
1334 if (n > 0 && self->abs_pos != -1)
1335 self->abs_pos += n;
1336 return n;
1337}
1338
1339static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001340_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341{
1342 Py_ssize_t start, len, n;
1343 if (VALID_READ_BUFFER(self))
1344 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1345 else
1346 start = 0;
1347 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001348 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349 if (n <= 0)
1350 return n;
1351 self->read_end = start + n;
1352 self->raw_pos = start + n;
1353 return n;
1354}
1355
1356static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001357_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001358{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001359 Py_ssize_t current_size;
1360 PyObject *res, *data = NULL;
1361 PyObject *chunks = PyList_New(0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001363 if (chunks == NULL)
1364 return NULL;
1365
1366 /* First copy what we have in the current buffer. */
1367 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1368 if (current_size) {
1369 data = PyBytes_FromStringAndSize(
1370 self->buffer + self->pos, current_size);
1371 if (data == NULL) {
1372 Py_DECREF(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001373 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001374 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001375 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001376 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001377 /* We're going past the buffer's bounds, flush it */
1378 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001379 res = buffered_flush_and_rewind_unlocked(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001380 if (res == NULL) {
1381 Py_DECREF(chunks);
1382 return NULL;
1383 }
1384 Py_CLEAR(res);
1385 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001386 _bufferedreader_reset_buf(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001387 while (1) {
1388 if (data) {
1389 if (PyList_Append(chunks, data) < 0) {
1390 Py_DECREF(data);
1391 Py_DECREF(chunks);
1392 return NULL;
1393 }
1394 Py_DECREF(data);
1395 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001396
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001397 /* Read until EOF or until read() would block. */
1398 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1399 if (data == NULL) {
1400 Py_DECREF(chunks);
1401 return NULL;
1402 }
1403 if (data != Py_None && !PyBytes_Check(data)) {
1404 Py_DECREF(data);
1405 Py_DECREF(chunks);
1406 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1407 return NULL;
1408 }
1409 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1410 if (current_size == 0) {
1411 Py_DECREF(chunks);
1412 return data;
1413 }
1414 else {
1415 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1416 Py_DECREF(data);
1417 Py_DECREF(chunks);
1418 return res;
1419 }
1420 }
1421 current_size += PyBytes_GET_SIZE(data);
1422 if (self->abs_pos != -1)
1423 self->abs_pos += PyBytes_GET_SIZE(data);
1424 }
1425}
1426
1427/* Read n bytes from the buffer if it can, otherwise return None.
1428 This function is simple enough that it can run unlocked. */
1429static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001430_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001431{
1432 Py_ssize_t current_size;
1433
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001434 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1435 if (n <= current_size) {
1436 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001437 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1438 if (res != NULL)
1439 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440 return res;
1441 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001442 Py_RETURN_NONE;
1443}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001444
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001445/* Generic read function: read from the stream until enough bytes are read,
1446 * or until an EOF occurs or until read() would block.
1447 */
1448static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001449_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001450{
1451 PyObject *res = NULL;
1452 Py_ssize_t current_size, remaining, written;
1453 char *out;
1454
1455 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1456 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001457 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001458
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001459 res = PyBytes_FromStringAndSize(NULL, n);
1460 if (res == NULL)
1461 goto error;
1462 out = PyBytes_AS_STRING(res);
1463 remaining = n;
1464 written = 0;
1465 if (current_size > 0) {
1466 memcpy(out, self->buffer + self->pos, current_size);
1467 remaining -= current_size;
1468 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001469 self->pos += current_size;
1470 }
1471 /* Flush the write buffer if necessary */
1472 if (self->writable) {
1473 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1474 if (r == NULL)
1475 goto error;
1476 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001477 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001478 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 while (remaining > 0) {
1480 /* We want to read a whole block at the end into buffer.
1481 If we had readv() we could do this in one pass. */
1482 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1483 if (r == 0)
1484 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001485 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001486 if (r == -1)
1487 goto error;
1488 if (r == 0 || r == -2) {
1489 /* EOF occurred or read() would block. */
1490 if (r == 0 || written > 0) {
1491 if (_PyBytes_Resize(&res, written))
1492 goto error;
1493 return res;
1494 }
1495 Py_DECREF(res);
1496 Py_INCREF(Py_None);
1497 return Py_None;
1498 }
1499 remaining -= r;
1500 written += r;
1501 }
1502 assert(remaining <= self->buffer_size);
1503 self->pos = 0;
1504 self->raw_pos = 0;
1505 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001506 /* NOTE: when the read is satisfied, we avoid issuing any additional
1507 reads, which could block indefinitely (e.g. on a socket).
1508 See issue #9550. */
1509 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001510 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001511 if (r == -1)
1512 goto error;
1513 if (r == 0 || r == -2) {
1514 /* EOF occurred or read() would block. */
1515 if (r == 0 || written > 0) {
1516 if (_PyBytes_Resize(&res, written))
1517 goto error;
1518 return res;
1519 }
1520 Py_DECREF(res);
1521 Py_INCREF(Py_None);
1522 return Py_None;
1523 }
1524 if (remaining > r) {
1525 memcpy(out + written, self->buffer + self->pos, r);
1526 written += r;
1527 self->pos += r;
1528 remaining -= r;
1529 }
1530 else if (remaining > 0) {
1531 memcpy(out + written, self->buffer + self->pos, remaining);
1532 written += remaining;
1533 self->pos += remaining;
1534 remaining = 0;
1535 }
1536 if (remaining == 0)
1537 break;
1538 }
1539
1540 return res;
1541
1542error:
1543 Py_XDECREF(res);
1544 return NULL;
1545}
1546
1547static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001548_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001549{
1550 Py_ssize_t have, r;
1551
1552 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1553 /* Constraints:
1554 1. we don't want to advance the file position.
1555 2. we don't want to lose block alignment, so we can't shift the buffer
1556 to make some place.
1557 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1558 */
1559 if (have > 0) {
1560 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1561 }
1562
1563 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001564 _bufferedreader_reset_buf(self);
1565 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001566 if (r == -1)
1567 return NULL;
1568 if (r == -2)
1569 r = 0;
1570 self->pos = 0;
1571 return PyBytes_FromStringAndSize(self->buffer, r);
1572}
1573
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001574static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001575 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001576 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1577 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1578 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1579 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1580 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1581 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1582 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1583 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001584 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001585 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001586
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001587 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1588 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1589 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
1590 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1591 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1592 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1593 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001594 {NULL, NULL}
1595};
1596
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001597static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001598 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001599 {NULL}
1600};
1601
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001602static PyGetSetDef bufferedreader_getset[] = {
1603 {"closed", (getter)buffered_closed_get, NULL, NULL},
1604 {"name", (getter)buffered_name_get, NULL, NULL},
1605 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001606 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001607};
1608
1609
1610PyTypeObject PyBufferedReader_Type = {
1611 PyVarObject_HEAD_INIT(NULL, 0)
1612 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001613 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001614 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001615 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001616 0, /*tp_print*/
1617 0, /*tp_getattr*/
1618 0, /*tp_setattr*/
1619 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001620 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001621 0, /*tp_as_number*/
1622 0, /*tp_as_sequence*/
1623 0, /*tp_as_mapping*/
1624 0, /*tp_hash */
1625 0, /*tp_call*/
1626 0, /*tp_str*/
1627 0, /*tp_getattro*/
1628 0, /*tp_setattro*/
1629 0, /*tp_as_buffer*/
1630 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1631 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001632 bufferedreader_doc, /* tp_doc */
1633 (traverseproc)buffered_traverse, /* tp_traverse */
1634 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001635 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001636 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001637 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001638 (iternextfunc)buffered_iternext, /* tp_iternext */
1639 bufferedreader_methods, /* tp_methods */
1640 bufferedreader_members, /* tp_members */
1641 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001642 0, /* tp_base */
1643 0, /* tp_dict */
1644 0, /* tp_descr_get */
1645 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001646 offsetof(buffered, dict), /* tp_dictoffset */
1647 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001648 0, /* tp_alloc */
1649 PyType_GenericNew, /* tp_new */
1650};
1651
1652
Benjamin Peterson59406a92009-03-26 17:10:29 +00001653
1654static int
1655complain_about_max_buffer_size(void)
1656{
1657 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1658 "max_buffer_size is deprecated", 1) < 0)
1659 return 0;
1660 return 1;
1661}
1662
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001663/*
1664 * class BufferedWriter
1665 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001666PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001667 "A buffer for a writeable sequential RawIO object.\n"
1668 "\n"
1669 "The constructor creates a BufferedWriter for the given writeable raw\n"
1670 "stream. If the buffer_size is not given, it defaults to\n"
1671 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1672 );
1673
1674static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001675_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001676{
1677 self->write_pos = 0;
1678 self->write_end = -1;
1679}
1680
1681static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001682bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683{
1684 /* TODO: properly deprecate max_buffer_size */
1685 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1686 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001687 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001688 PyObject *raw;
1689
1690 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001691 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001692
1693 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1694 &raw, &buffer_size, &max_buffer_size)) {
1695 return -1;
1696 }
1697
Benjamin Peterson59406a92009-03-26 17:10:29 +00001698 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1699 return -1;
1700
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001701 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001702 return -1;
1703
1704 Py_CLEAR(self->raw);
1705 Py_INCREF(raw);
1706 self->raw = raw;
1707 self->readable = 0;
1708 self->writable = 1;
1709
1710 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001711 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001712 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001713 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001714 self->pos = 0;
1715
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001716 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1717 Py_TYPE(raw) == &PyFileIO_Type);
1718
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719 self->ok = 1;
1720 return 0;
1721}
1722
1723static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001724_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001725{
1726 Py_buffer buf;
1727 PyObject *memobj, *res;
1728 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001729 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001730 /* NOTE: the buffer needn't be released as its object is NULL. */
1731 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1732 return -1;
1733 memobj = PyMemoryView_FromBuffer(&buf);
1734 if (memobj == NULL)
1735 return -1;
Antoine Pitroud843c2d2011-02-25 21:34:39 +00001736 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1737 occurs so we needn't do it ourselves.
1738 We then retry writing, ignoring the signal if no handler has
1739 raised (see issue #10956).
1740 */
1741 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001742 errno = 0;
Antoine Pitroud843c2d2011-02-25 21:34:39 +00001743 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001744 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001745 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746 Py_DECREF(memobj);
1747 if (res == NULL)
1748 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001749 if (res == Py_None) {
1750 /* Non-blocking stream would have blocked. Special return code!
1751 Being paranoid we reset errno in case it is changed by code
1752 triggered by a decref. errno is used by _set_BlockingIOError(). */
1753 Py_DECREF(res);
1754 errno = errnum;
1755 return -2;
1756 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1758 Py_DECREF(res);
1759 if (n < 0 || n > len) {
1760 PyErr_Format(PyExc_IOError,
1761 "raw write() returned invalid length %zd "
1762 "(should have been between 0 and %zd)", n, len);
1763 return -1;
1764 }
1765 if (n > 0 && self->abs_pos != -1)
1766 self->abs_pos += n;
1767 return n;
1768}
1769
1770/* `restore_pos` is 1 if we need to restore the raw stream position at
1771 the end, 0 otherwise. */
1772static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001773_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774{
1775 Py_ssize_t written = 0;
1776 Py_off_t n, rewind;
1777
1778 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1779 goto end;
1780 /* First, rewind */
1781 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1782 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001783 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 if (n < 0) {
1785 goto error;
1786 }
1787 self->raw_pos -= rewind;
1788 }
1789 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001790 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791 self->buffer + self->write_pos,
1792 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1793 Py_off_t, Py_ssize_t));
1794 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001795 goto error;
1796 }
1797 else if (n == -2) {
1798 _set_BlockingIOError("write could not complete without blocking",
1799 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 goto error;
1801 }
1802 self->write_pos += n;
1803 self->raw_pos = self->write_pos;
1804 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001805 /* Partial writes can return successfully when interrupted by a
1806 signal (see write(2)). We must run signal handlers before
1807 blocking another time, possibly indefinitely. */
1808 if (PyErr_CheckSignals() < 0)
1809 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 }
1811
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813
1814end:
1815 Py_RETURN_NONE;
1816
1817error:
1818 return NULL;
1819}
1820
1821static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001822bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823{
1824 PyObject *res = NULL;
1825 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001826 Py_ssize_t written, avail, remaining;
1827 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828
1829 CHECK_INITIALIZED(self)
1830 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1831 return NULL;
1832 }
1833
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001834 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 PyErr_SetString(PyExc_ValueError, "write to closed file");
1836 PyBuffer_Release(&buf);
1837 return NULL;
1838 }
1839
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001840 if (!ENTER_BUFFERED(self)) {
1841 PyBuffer_Release(&buf);
1842 return NULL;
1843 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844
1845 /* Fast path: the data to write can be fully buffered. */
1846 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1847 self->pos = 0;
1848 self->raw_pos = 0;
1849 }
1850 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1851 if (buf.len <= avail) {
1852 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001853 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854 self->write_pos = self->pos;
1855 }
1856 ADJUST_POSITION(self, self->pos + buf.len);
1857 if (self->pos > self->write_end)
1858 self->write_end = self->pos;
1859 written = buf.len;
1860 goto end;
1861 }
1862
1863 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001864 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001865 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001866 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001867 if (w == NULL)
1868 goto error;
1869 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001870 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001871 /* Make some place by shifting the buffer. */
1872 assert(VALID_WRITE_BUFFER(self));
1873 memmove(self->buffer, self->buffer + self->write_pos,
1874 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1875 Py_off_t, Py_ssize_t));
1876 self->write_end -= self->write_pos;
1877 self->raw_pos -= self->write_pos;
1878 self->pos -= self->write_pos;
1879 self->write_pos = 0;
1880 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1881 Py_off_t, Py_ssize_t);
1882 if (buf.len <= avail) {
1883 /* Everything can be buffered */
1884 PyErr_Clear();
1885 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1886 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001887 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001888 written = buf.len;
1889 goto end;
1890 }
1891 /* Buffer as much as possible. */
1892 memcpy(self->buffer + self->write_end, buf.buf, avail);
1893 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001894 self->pos += avail;
1895 /* XXX Modifying the existing exception e using the pointer w
1896 will change e.characters_written but not e.args[2].
1897 Therefore we just replace with a new error. */
1898 _set_BlockingIOError("write could not complete without blocking",
1899 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900 goto error;
1901 }
1902 Py_CLEAR(res);
1903
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001904 /* Adjust the raw stream position if it is away from the logical stream
1905 position. This happens if the read buffer has been filled but not
1906 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1907 the raw stream by itself).
1908 Fixes issue #6629.
1909 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001910 offset = RAW_OFFSET(self);
1911 if (offset != 0) {
1912 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001913 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001914 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001915 }
1916
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001917 /* Then write buf itself. At this point the buffer has been emptied. */
1918 remaining = buf.len;
1919 written = 0;
1920 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001921 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001922 self, (char *) buf.buf + written, buf.len - written);
1923 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001924 goto error;
1925 } else if (n == -2) {
1926 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001927 if (remaining > self->buffer_size) {
1928 /* Can't buffer everything, still buffer as much as possible */
1929 memcpy(self->buffer,
1930 (char *) buf.buf + written, self->buffer_size);
1931 self->raw_pos = 0;
1932 ADJUST_POSITION(self, self->buffer_size);
1933 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001934 written += self->buffer_size;
1935 _set_BlockingIOError("write could not complete without "
1936 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937 goto error;
1938 }
1939 PyErr_Clear();
1940 break;
1941 }
1942 written += n;
1943 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001944 /* Partial writes can return successfully when interrupted by a
1945 signal (see write(2)). We must run signal handlers before
1946 blocking another time, possibly indefinitely. */
1947 if (PyErr_CheckSignals() < 0)
1948 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 }
1950 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 if (remaining > 0) {
1953 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1954 written += remaining;
1955 }
1956 self->write_pos = 0;
1957 /* TODO: sanity check (remaining >= 0) */
1958 self->write_end = remaining;
1959 ADJUST_POSITION(self, remaining);
1960 self->raw_pos = 0;
1961
1962end:
1963 res = PyLong_FromSsize_t(written);
1964
1965error:
1966 LEAVE_BUFFERED(self)
1967 PyBuffer_Release(&buf);
1968 return res;
1969}
1970
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001971static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001973 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1974 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1975 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1976 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1977 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1978 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1979 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001980 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001981 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001983 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
1984 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1985 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
1986 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1987 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988 {NULL, NULL}
1989};
1990
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001991static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001992 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993 {NULL}
1994};
1995
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001996static PyGetSetDef bufferedwriter_getset[] = {
1997 {"closed", (getter)buffered_closed_get, NULL, NULL},
1998 {"name", (getter)buffered_name_get, NULL, NULL},
1999 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002000 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001};
2002
2003
2004PyTypeObject PyBufferedWriter_Type = {
2005 PyVarObject_HEAD_INIT(NULL, 0)
2006 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002007 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002009 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 0, /*tp_print*/
2011 0, /*tp_getattr*/
2012 0, /*tp_setattr*/
2013 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002014 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 0, /*tp_as_number*/
2016 0, /*tp_as_sequence*/
2017 0, /*tp_as_mapping*/
2018 0, /*tp_hash */
2019 0, /*tp_call*/
2020 0, /*tp_str*/
2021 0, /*tp_getattro*/
2022 0, /*tp_setattro*/
2023 0, /*tp_as_buffer*/
2024 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2025 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002026 bufferedwriter_doc, /* tp_doc */
2027 (traverseproc)buffered_traverse, /* tp_traverse */
2028 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002030 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002031 0, /* tp_iter */
2032 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002033 bufferedwriter_methods, /* tp_methods */
2034 bufferedwriter_members, /* tp_members */
2035 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002036 0, /* tp_base */
2037 0, /* tp_dict */
2038 0, /* tp_descr_get */
2039 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002040 offsetof(buffered, dict), /* tp_dictoffset */
2041 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002042 0, /* tp_alloc */
2043 PyType_GenericNew, /* tp_new */
2044};
2045
2046
2047
2048/*
2049 * BufferedRWPair
2050 */
2051
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002052PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002053 "A buffered reader and writer object together.\n"
2054 "\n"
2055 "A buffered reader object and buffered writer object put together to\n"
2056 "form a sequential IO object that can read and write. This is typically\n"
2057 "used with a socket or two-way pipe.\n"
2058 "\n"
2059 "reader and writer are RawIOBase objects that are readable and\n"
2060 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002061 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002062 );
2063
2064/* XXX The usefulness of this (compared to having two separate IO objects) is
2065 * questionable.
2066 */
2067
2068typedef struct {
2069 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002070 buffered *reader;
2071 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002072 PyObject *dict;
2073 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002074} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075
2076static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002077bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078{
2079 PyObject *reader, *writer;
2080 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002081 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002082
2083 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2084 &buffer_size, &max_buffer_size)) {
2085 return -1;
2086 }
2087
Benjamin Peterson59406a92009-03-26 17:10:29 +00002088 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2089 return -1;
2090
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002091 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002092 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002093 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002094 return -1;
2095
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002096 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002097 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098 if (self->reader == NULL)
2099 return -1;
2100
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002101 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002102 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002103 if (self->writer == NULL) {
2104 Py_CLEAR(self->reader);
2105 return -1;
2106 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002107
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108 return 0;
2109}
2110
2111static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113{
2114 Py_VISIT(self->dict);
2115 return 0;
2116}
2117
2118static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002119bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002120{
2121 Py_CLEAR(self->reader);
2122 Py_CLEAR(self->writer);
2123 Py_CLEAR(self->dict);
2124 return 0;
2125}
2126
2127static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002128bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002129{
2130 _PyObject_GC_UNTRACK(self);
2131 Py_CLEAR(self->reader);
2132 Py_CLEAR(self->writer);
2133 Py_CLEAR(self->dict);
2134 Py_TYPE(self)->tp_free((PyObject *) self);
2135}
2136
2137static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002138_forward_call(buffered *self, const char *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139{
2140 PyObject *func = PyObject_GetAttrString((PyObject *)self, name);
2141 PyObject *ret;
2142
2143 if (func == NULL) {
2144 PyErr_SetString(PyExc_AttributeError, name);
2145 return NULL;
2146 }
2147
2148 ret = PyObject_CallObject(func, args);
2149 Py_DECREF(func);
2150 return ret;
2151}
2152
2153static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002154bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155{
2156 return _forward_call(self->reader, "read", args);
2157}
2158
2159static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002160bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161{
2162 return _forward_call(self->reader, "peek", args);
2163}
2164
2165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002166bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167{
2168 return _forward_call(self->reader, "read1", args);
2169}
2170
2171static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002172bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002173{
2174 return _forward_call(self->reader, "readinto", args);
2175}
2176
2177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002178bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179{
2180 return _forward_call(self->writer, "write", args);
2181}
2182
2183static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002185{
2186 return _forward_call(self->writer, "flush", args);
2187}
2188
2189static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191{
2192 return _forward_call(self->reader, "readable", args);
2193}
2194
2195static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002196bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197{
2198 return _forward_call(self->writer, "writable", args);
2199}
2200
2201static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002202bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203{
2204 PyObject *ret = _forward_call(self->writer, "close", args);
2205 if (ret == NULL)
2206 return NULL;
2207 Py_DECREF(ret);
2208
2209 return _forward_call(self->reader, "close", args);
2210}
2211
2212static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002213bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214{
2215 PyObject *ret = _forward_call(self->writer, "isatty", args);
2216
2217 if (ret != Py_False) {
2218 /* either True or exception */
2219 return ret;
2220 }
2221 Py_DECREF(ret);
2222
2223 return _forward_call(self->reader, "isatty", args);
2224}
2225
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002226static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002228{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002229 if (self->writer == NULL) {
2230 PyErr_SetString(PyExc_RuntimeError,
2231 "the BufferedRWPair object is being garbage-collected");
2232 return NULL;
2233 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002234 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2235}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002237static PyMethodDef bufferedrwpair_methods[] = {
2238 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2239 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2240 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2241 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002243 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2244 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002246 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2247 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002248
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002249 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2250 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251
Antoine Pitrou243757e2010-11-05 21:15:39 +00002252 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2253
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254 {NULL, NULL}
2255};
2256
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002257static PyGetSetDef bufferedrwpair_getset[] = {
2258 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002259 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002260};
2261
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262PyTypeObject PyBufferedRWPair_Type = {
2263 PyVarObject_HEAD_INIT(NULL, 0)
2264 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002267 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002268 0, /*tp_print*/
2269 0, /*tp_getattr*/
2270 0, /*tp_setattr*/
2271 0, /*tp_compare */
2272 0, /*tp_repr*/
2273 0, /*tp_as_number*/
2274 0, /*tp_as_sequence*/
2275 0, /*tp_as_mapping*/
2276 0, /*tp_hash */
2277 0, /*tp_call*/
2278 0, /*tp_str*/
2279 0, /*tp_getattro*/
2280 0, /*tp_setattro*/
2281 0, /*tp_as_buffer*/
2282 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2283 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002284 bufferedrwpair_doc, /* tp_doc */
2285 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2286 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002287 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002288 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289 0, /* tp_iter */
2290 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002291 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002292 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002293 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002294 0, /* tp_base */
2295 0, /* tp_dict */
2296 0, /* tp_descr_get */
2297 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002298 offsetof(rwpair, dict), /* tp_dictoffset */
2299 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300 0, /* tp_alloc */
2301 PyType_GenericNew, /* tp_new */
2302};
2303
2304
2305
2306/*
2307 * BufferedRandom
2308 */
2309
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002310PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002311 "A buffered interface to random access streams.\n"
2312 "\n"
2313 "The constructor creates a reader and writer for a seekable stream,\n"
2314 "raw, given in the first argument. If the buffer_size is omitted it\n"
2315 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2316 );
2317
2318static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002319bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002320{
2321 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2322 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002323 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002324 PyObject *raw;
2325
2326 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002327 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328
2329 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2330 &raw, &buffer_size, &max_buffer_size)) {
2331 return -1;
2332 }
2333
Benjamin Peterson59406a92009-03-26 17:10:29 +00002334 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2335 return -1;
2336
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002337 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002338 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002340 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002341 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002342 return -1;
2343
2344 Py_CLEAR(self->raw);
2345 Py_INCREF(raw);
2346 self->raw = raw;
2347 self->buffer_size = buffer_size;
2348 self->readable = 1;
2349 self->writable = 1;
2350
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002351 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002352 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002353 _bufferedreader_reset_buf(self);
2354 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355 self->pos = 0;
2356
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002357 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2358 Py_TYPE(raw) == &PyFileIO_Type);
2359
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002360 self->ok = 1;
2361 return 0;
2362}
2363
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002364static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002365 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002366 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2367 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2368 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2369 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2370 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2371 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2372 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002373 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002374 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002375
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002376 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002378 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2379 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2380 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2381 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2382 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2383 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2384 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2385 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2386 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002387 {NULL, NULL}
2388};
2389
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002390static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002391 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002392 {NULL}
2393};
2394
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002395static PyGetSetDef bufferedrandom_getset[] = {
2396 {"closed", (getter)buffered_closed_get, NULL, NULL},
2397 {"name", (getter)buffered_name_get, NULL, NULL},
2398 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002399 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002400};
2401
2402
2403PyTypeObject PyBufferedRandom_Type = {
2404 PyVarObject_HEAD_INIT(NULL, 0)
2405 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002406 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002407 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002408 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002409 0, /*tp_print*/
2410 0, /*tp_getattr*/
2411 0, /*tp_setattr*/
2412 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002413 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002414 0, /*tp_as_number*/
2415 0, /*tp_as_sequence*/
2416 0, /*tp_as_mapping*/
2417 0, /*tp_hash */
2418 0, /*tp_call*/
2419 0, /*tp_str*/
2420 0, /*tp_getattro*/
2421 0, /*tp_setattro*/
2422 0, /*tp_as_buffer*/
2423 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2424 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002425 bufferedrandom_doc, /* tp_doc */
2426 (traverseproc)buffered_traverse, /* tp_traverse */
2427 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002431 (iternextfunc)buffered_iternext, /* tp_iternext */
2432 bufferedrandom_methods, /* tp_methods */
2433 bufferedrandom_members, /* tp_members */
2434 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002435 0, /* tp_base */
2436 0, /*tp_dict*/
2437 0, /* tp_descr_get */
2438 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002439 offsetof(buffered, dict), /*tp_dictoffset*/
2440 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002441 0, /* tp_alloc */
2442 PyType_GenericNew, /* tp_new */
2443};