blob: 386a880997192aaab5d19c863a8c419e7b1add29 [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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584_bufferedwriter_flush_unlocked(buffered *, int);
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
605/* Returns the address of the `written` member if a BlockingIOError was
606 raised, NULL otherwise. The error is always re-raised. */
607static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000608_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609{
610 PyObject *t, *v, *tb;
611 PyBlockingIOErrorObject *err;
612
613 PyErr_Fetch(&t, &v, &tb);
614 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
615 PyErr_Restore(t, v, tb);
616 return NULL;
617 }
618 err = (PyBlockingIOErrorObject *) v;
619 /* TODO: sanity check (err->written >= 0) */
620 PyErr_Restore(t, v, tb);
621 return &err->written;
622}
623
624static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000626{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000628 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
630 if (res == NULL)
631 return -1;
632 n = PyNumber_AsOff_t(res, PyExc_ValueError);
633 Py_DECREF(res);
634 if (n < 0) {
635 if (!PyErr_Occurred())
636 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000637 "Raw stream returned invalid position %" PY_PRIdOFF,
638 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639 return -1;
640 }
641 self->abs_pos = n;
642 return n;
643}
644
645static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000646_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647{
648 PyObject *res, *posobj, *whenceobj;
649 Py_off_t n;
650
651 posobj = PyLong_FromOff_t(target);
652 if (posobj == NULL)
653 return -1;
654 whenceobj = PyLong_FromLong(whence);
655 if (whenceobj == NULL) {
656 Py_DECREF(posobj);
657 return -1;
658 }
659 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
660 posobj, whenceobj, NULL);
661 Py_DECREF(posobj);
662 Py_DECREF(whenceobj);
663 if (res == NULL)
664 return -1;
665 n = PyNumber_AsOff_t(res, PyExc_ValueError);
666 Py_DECREF(res);
667 if (n < 0) {
668 if (!PyErr_Occurred())
669 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000670 "Raw stream returned invalid position %" PY_PRIdOFF,
671 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672 return -1;
673 }
674 self->abs_pos = n;
675 return n;
676}
677
678static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000679_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680{
681 Py_ssize_t n;
682 if (self->buffer_size <= 0) {
683 PyErr_SetString(PyExc_ValueError,
684 "buffer size must be strictly positive");
685 return -1;
686 }
687 if (self->buffer)
688 PyMem_Free(self->buffer);
689 self->buffer = PyMem_Malloc(self->buffer_size);
690 if (self->buffer == NULL) {
691 PyErr_NoMemory();
692 return -1;
693 }
Georg Brandldfd73442009-04-05 11:47:34 +0000694#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000695 if (self->lock)
696 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000697 self->lock = PyThread_allocate_lock();
698 if (self->lock == NULL) {
699 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
700 return -1;
701 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000702 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000703#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000704 /* Find out whether buffer_size is a power of 2 */
705 /* XXX is this optimization useful? */
706 for (n = self->buffer_size - 1; n & 1; n >>= 1)
707 ;
708 if (n == 0)
709 self->buffer_mask = self->buffer_size - 1;
710 else
711 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000712 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000713 PyErr_Clear();
714 return 0;
715}
716
Antoine Pitrou707ce822011-02-25 21:24:11 +0000717/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
718 clears the error indicator), 0 otherwise.
719 Should only be called when PyErr_Occurred() is true.
720*/
721static int
722_trap_eintr(void)
723{
724 static PyObject *eintr_int = NULL;
725 PyObject *typ, *val, *tb;
726 PyEnvironmentErrorObject *env_err;
727
728 if (eintr_int == NULL) {
729 eintr_int = PyLong_FromLong(EINTR);
730 assert(eintr_int != NULL);
731 }
732 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
733 return 0;
734 PyErr_Fetch(&typ, &val, &tb);
735 PyErr_NormalizeException(&typ, &val, &tb);
736 env_err = (PyEnvironmentErrorObject *) val;
737 assert(env_err != NULL);
738 if (env_err->myerrno != NULL &&
739 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
740 Py_DECREF(typ);
741 Py_DECREF(val);
742 Py_XDECREF(tb);
743 return 1;
744 }
745 /* This silences any error set by PyObject_RichCompareBool() */
746 PyErr_Restore(typ, val, tb);
747 return 0;
748}
749
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000750/*
751 * Shared methods and wrappers
752 */
753
754static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000755buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000756{
757 PyObject *res;
758
759 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000760 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000761
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000762 if (!ENTER_BUFFERED(self))
763 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000764 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000765 if (res != NULL && self->readable) {
766 /* Rewind the raw stream so that its position corresponds to
767 the current logical position. */
768 Py_off_t n;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000769 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000770 if (n == -1)
771 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000772 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773 }
774 LEAVE_BUFFERED(self)
775
776 return res;
777}
778
779static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000780buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000781{
782 Py_ssize_t n = 0;
783 PyObject *res = NULL;
784
785 CHECK_INITIALIZED(self)
786 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
787 return NULL;
788 }
789
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000790 if (!ENTER_BUFFERED(self))
791 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000792
793 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000794 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000795 if (res == NULL)
796 goto end;
797 Py_CLEAR(res);
798 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000799 res = _bufferedreader_peek_unlocked(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000800
801end:
802 LEAVE_BUFFERED(self)
803 return res;
804}
805
806static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000807buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000808{
809 Py_ssize_t n = -1;
810 PyObject *res;
811
812 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000813 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000814 return NULL;
815 }
816 if (n < -1) {
817 PyErr_SetString(PyExc_ValueError,
818 "read length must be positive or -1");
819 return NULL;
820 }
821
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000822 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000823
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000824 if (n == -1) {
825 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000826 if (!ENTER_BUFFERED(self))
827 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000828 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000829 LEAVE_BUFFERED(self)
830 }
831 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000832 res = _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000833 if (res == Py_None) {
834 Py_DECREF(res);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000835 if (!ENTER_BUFFERED(self))
836 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000837 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000838 LEAVE_BUFFERED(self)
839 }
840 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841
842 return res;
843}
844
845static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000846buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000847{
848 Py_ssize_t n, have, r;
849 PyObject *res = NULL;
850
851 CHECK_INITIALIZED(self)
852 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
853 return NULL;
854 }
855
856 if (n < 0) {
857 PyErr_SetString(PyExc_ValueError,
858 "read length must be positive");
859 return NULL;
860 }
861 if (n == 0)
862 return PyBytes_FromStringAndSize(NULL, 0);
863
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000864 if (!ENTER_BUFFERED(self))
865 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866
867 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000868 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000869 if (res == NULL)
870 goto end;
871 Py_CLEAR(res);
872 }
873
874 /* Return up to n bytes. If at least one byte is buffered, we
875 only return buffered bytes. Otherwise, we do one raw read. */
876
877 /* XXX: this mimicks the io.py implementation but is probably wrong.
878 If we need to read from the raw stream, then we could actually read
879 all `n` bytes asked by the caller (and possibly more, so as to fill
880 our buffer for the next reads). */
881
882 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
883 if (have > 0) {
884 if (n > have)
885 n = have;
886 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
887 if (res == NULL)
888 goto end;
889 self->pos += n;
890 goto end;
891 }
892
893 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000894 _bufferedreader_reset_buf(self);
895 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896 if (r == -1)
897 goto end;
898 if (r == -2)
899 r = 0;
900 if (n > r)
901 n = r;
902 res = PyBytes_FromStringAndSize(self->buffer, n);
903 if (res == NULL)
904 goto end;
905 self->pos = n;
906
907end:
908 LEAVE_BUFFERED(self)
909 return res;
910}
911
912static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000913buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000914{
915 PyObject *res = NULL;
916
917 CHECK_INITIALIZED(self)
918
919 /* TODO: use raw.readinto() instead! */
920 if (self->writable) {
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000921 if (!ENTER_BUFFERED(self))
922 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000923 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 LEAVE_BUFFERED(self)
925 if (res == NULL)
926 goto end;
927 Py_DECREF(res);
928 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000929 res = bufferediobase_readinto((PyObject *)self, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930
931end:
932 return res;
933}
934
935static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000936_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000937{
938 PyObject *res = NULL;
939 PyObject *chunks = NULL;
940 Py_ssize_t n, written = 0;
941 const char *start, *s, *end;
942
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000943 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000944
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000945 /* First, try to find a line in the buffer. This can run unlocked because
946 the calls to the C API are simple enough that they can't trigger
947 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
949 if (limit >= 0 && n > limit)
950 n = limit;
951 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000952 s = memchr(start, '\n', n);
953 if (s != NULL) {
954 res = PyBytes_FromStringAndSize(start, s - start + 1);
955 if (res != NULL)
956 self->pos += s - start + 1;
957 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 }
959 if (n == limit) {
960 res = PyBytes_FromStringAndSize(start, n);
961 if (res != NULL)
962 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000963 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964 }
965
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000966 if (!ENTER_BUFFERED(self))
967 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000968
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969 /* Now we try to get some more from the raw stream */
970 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000971 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 if (res == NULL)
973 goto end;
974 Py_CLEAR(res);
975 }
976 chunks = PyList_New(0);
977 if (chunks == NULL)
978 goto end;
979 if (n > 0) {
980 res = PyBytes_FromStringAndSize(start, n);
981 if (res == NULL)
982 goto end;
983 if (PyList_Append(chunks, res) < 0) {
984 Py_CLEAR(res);
985 goto end;
986 }
987 Py_CLEAR(res);
988 written += n;
989 if (limit >= 0)
990 limit -= n;
991 }
992
993 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000994 _bufferedreader_reset_buf(self);
995 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000996 if (n == -1)
997 goto end;
998 if (n <= 0)
999 break;
1000 if (limit >= 0 && n > limit)
1001 n = limit;
1002 start = self->buffer;
1003 end = start + n;
1004 s = start;
1005 while (s < end) {
1006 if (*s++ == '\n') {
1007 res = PyBytes_FromStringAndSize(start, s - start);
1008 if (res == NULL)
1009 goto end;
1010 self->pos = s - start;
1011 goto found;
1012 }
1013 }
1014 res = PyBytes_FromStringAndSize(start, n);
1015 if (res == NULL)
1016 goto end;
1017 if (n == limit) {
1018 self->pos = n;
1019 break;
1020 }
1021 if (PyList_Append(chunks, res) < 0) {
1022 Py_CLEAR(res);
1023 goto end;
1024 }
1025 Py_CLEAR(res);
1026 written += n;
1027 if (limit >= 0)
1028 limit -= n;
1029 }
1030found:
1031 if (res != NULL && PyList_Append(chunks, res) < 0) {
1032 Py_CLEAR(res);
1033 goto end;
1034 }
1035 Py_CLEAR(res);
1036 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1037
1038end:
1039 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001040end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 Py_XDECREF(chunks);
1042 return res;
1043}
1044
1045static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001046buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047{
1048 Py_ssize_t limit = -1;
1049
1050 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001051 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001052 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001053 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001054}
1055
1056
1057static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001058buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001059{
1060 Py_off_t pos;
1061
1062 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001063 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001064 if (pos == -1)
1065 return NULL;
1066 pos -= RAW_OFFSET(self);
1067 /* TODO: sanity check (pos >= 0) */
1068 return PyLong_FromOff_t(pos);
1069}
1070
1071static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001072buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001073{
1074 Py_off_t target, n;
1075 int whence = 0;
1076 PyObject *targetobj, *res = NULL;
1077
1078 CHECK_INITIALIZED(self)
1079 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1080 return NULL;
1081 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001082 if (whence < 0 || whence > 2) {
1083 PyErr_Format(PyExc_ValueError,
1084 "whence must be between 0 and 2, not %d", whence);
1085 return NULL;
1086 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087
1088 CHECK_CLOSED(self, "seek of closed file")
1089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1091 if (target == -1 && PyErr_Occurred())
1092 return NULL;
1093
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001094 if (whence != 2 && self->readable) {
1095 Py_off_t current, avail;
1096 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001097 so as to return quickly if possible. Also, we needn't take the
1098 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001100 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1101 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102 current = RAW_TELL(self);
1103 avail = READAHEAD(self);
1104 if (avail > 0) {
1105 Py_off_t offset;
1106 if (whence == 0)
1107 offset = target - (current - RAW_OFFSET(self));
1108 else
1109 offset = target;
1110 if (offset >= -self->pos && offset <= avail) {
1111 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001112 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113 }
1114 }
1115 }
1116
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001117 if (!ENTER_BUFFERED(self))
1118 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001119
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001120 /* Fallback: invoke raw seek() method and clear buffer */
1121 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001122 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001123 if (res == NULL)
1124 goto end;
1125 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001126 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127 }
1128
1129 /* TODO: align on block boundary and read buffer if needed? */
1130 if (whence == 1)
1131 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001132 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001133 if (n == -1)
1134 goto end;
1135 self->raw_pos = -1;
1136 res = PyLong_FromOff_t(n);
1137 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001138 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001139
1140end:
1141 LEAVE_BUFFERED(self)
1142 return res;
1143}
1144
1145static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001146buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147{
1148 PyObject *pos = Py_None;
1149 PyObject *res = NULL;
1150
1151 CHECK_INITIALIZED(self)
1152 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1153 return NULL;
1154 }
1155
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001156 if (!ENTER_BUFFERED(self))
1157 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001158
1159 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001160 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001161 if (res == NULL)
1162 goto end;
1163 Py_CLEAR(res);
1164 }
1165 if (self->readable) {
1166 if (pos == Py_None) {
1167 /* Rewind the raw stream so that its position corresponds to
1168 the current logical position. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001169 if (_buffered_raw_seek(self, -RAW_OFFSET(self), 1) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001170 goto end;
1171 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001172 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001173 }
1174 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1175 if (res == NULL)
1176 goto end;
1177 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001178 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001179 PyErr_Clear();
1180
1181end:
1182 LEAVE_BUFFERED(self)
1183 return res;
1184}
1185
1186static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001187buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001188{
1189 PyObject *line;
1190 PyTypeObject *tp;
1191
1192 CHECK_INITIALIZED(self);
1193
1194 tp = Py_TYPE(self);
1195 if (tp == &PyBufferedReader_Type ||
1196 tp == &PyBufferedRandom_Type) {
1197 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001198 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199 }
1200 else {
1201 line = PyObject_CallMethodObjArgs((PyObject *)self,
1202 _PyIO_str_readline, NULL);
1203 if (line && !PyBytes_Check(line)) {
1204 PyErr_Format(PyExc_IOError,
1205 "readline() should have returned a bytes object, "
1206 "not '%.200s'", Py_TYPE(line)->tp_name);
1207 Py_DECREF(line);
1208 return NULL;
1209 }
1210 }
1211
1212 if (line == NULL)
1213 return NULL;
1214
1215 if (PyBytes_GET_SIZE(line) == 0) {
1216 /* Reached EOF or would have blocked */
1217 Py_DECREF(line);
1218 return NULL;
1219 }
1220
1221 return line;
1222}
1223
Antoine Pitrou716c4442009-05-23 19:04:03 +00001224static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001225buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001226{
1227 PyObject *nameobj, *res;
1228
1229 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1230 if (nameobj == NULL) {
1231 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1232 PyErr_Clear();
1233 else
1234 return NULL;
1235 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1236 }
1237 else {
1238 res = PyUnicode_FromFormat("<%s name=%R>",
1239 Py_TYPE(self)->tp_name, nameobj);
1240 Py_DECREF(nameobj);
1241 }
1242 return res;
1243}
1244
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245/*
1246 * class BufferedReader
1247 */
1248
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001249PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250 "Create a new buffered reader using the given readable raw IO object.");
1251
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001252static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001253{
1254 self->read_end = -1;
1255}
1256
1257static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001258bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001259{
1260 char *kwlist[] = {"raw", "buffer_size", NULL};
1261 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1262 PyObject *raw;
1263
1264 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001265 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266
1267 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1268 &raw, &buffer_size)) {
1269 return -1;
1270 }
1271
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001272 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 return -1;
1274
1275 Py_CLEAR(self->raw);
1276 Py_INCREF(raw);
1277 self->raw = raw;
1278 self->buffer_size = buffer_size;
1279 self->readable = 1;
1280 self->writable = 0;
1281
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001282 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001284 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001286 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1287 Py_TYPE(raw) == &PyFileIO_Type);
1288
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 self->ok = 1;
1290 return 0;
1291}
1292
1293static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001294_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001295{
1296 Py_buffer buf;
1297 PyObject *memobj, *res;
1298 Py_ssize_t n;
1299 /* NOTE: the buffer needn't be released as its object is NULL. */
1300 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1301 return -1;
1302 memobj = PyMemoryView_FromBuffer(&buf);
1303 if (memobj == NULL)
1304 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001305 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1306 occurs so we needn't do it ourselves.
1307 We then retry reading, ignoring the signal if no handler has
1308 raised (see issue #10956).
1309 */
1310 do {
1311 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1312 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 Py_DECREF(memobj);
1314 if (res == NULL)
1315 return -1;
1316 if (res == Py_None) {
1317 /* Non-blocking stream would have blocked. Special return code! */
1318 Py_DECREF(res);
1319 return -2;
1320 }
1321 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1322 Py_DECREF(res);
1323 if (n < 0 || n > len) {
1324 PyErr_Format(PyExc_IOError,
1325 "raw readinto() returned invalid length %zd "
1326 "(should have been between 0 and %zd)", n, len);
1327 return -1;
1328 }
1329 if (n > 0 && self->abs_pos != -1)
1330 self->abs_pos += n;
1331 return n;
1332}
1333
1334static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001335_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336{
1337 Py_ssize_t start, len, n;
1338 if (VALID_READ_BUFFER(self))
1339 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1340 else
1341 start = 0;
1342 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001343 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001344 if (n <= 0)
1345 return n;
1346 self->read_end = start + n;
1347 self->raw_pos = start + n;
1348 return n;
1349}
1350
1351static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001352_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001353{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001354 Py_ssize_t current_size;
1355 PyObject *res, *data = NULL;
1356 PyObject *chunks = PyList_New(0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001357
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001358 if (chunks == NULL)
1359 return NULL;
1360
1361 /* First copy what we have in the current buffer. */
1362 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1363 if (current_size) {
1364 data = PyBytes_FromStringAndSize(
1365 self->buffer + self->pos, current_size);
1366 if (data == NULL) {
1367 Py_DECREF(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001368 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001369 }
1370 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371 _bufferedreader_reset_buf(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001372 /* We're going past the buffer's bounds, flush it */
1373 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001374 res = _bufferedwriter_flush_unlocked(self, 1);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001375 if (res == NULL) {
1376 Py_DECREF(chunks);
1377 return NULL;
1378 }
1379 Py_CLEAR(res);
1380 }
1381 while (1) {
1382 if (data) {
1383 if (PyList_Append(chunks, data) < 0) {
1384 Py_DECREF(data);
1385 Py_DECREF(chunks);
1386 return NULL;
1387 }
1388 Py_DECREF(data);
1389 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001390
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001391 /* Read until EOF or until read() would block. */
1392 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1393 if (data == NULL) {
1394 Py_DECREF(chunks);
1395 return NULL;
1396 }
1397 if (data != Py_None && !PyBytes_Check(data)) {
1398 Py_DECREF(data);
1399 Py_DECREF(chunks);
1400 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1401 return NULL;
1402 }
1403 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1404 if (current_size == 0) {
1405 Py_DECREF(chunks);
1406 return data;
1407 }
1408 else {
1409 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1410 Py_DECREF(data);
1411 Py_DECREF(chunks);
1412 return res;
1413 }
1414 }
1415 current_size += PyBytes_GET_SIZE(data);
1416 if (self->abs_pos != -1)
1417 self->abs_pos += PyBytes_GET_SIZE(data);
1418 }
1419}
1420
1421/* Read n bytes from the buffer if it can, otherwise return None.
1422 This function is simple enough that it can run unlocked. */
1423static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001424_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001425{
1426 Py_ssize_t current_size;
1427
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001428 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1429 if (n <= current_size) {
1430 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001431 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1432 if (res != NULL)
1433 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001434 return res;
1435 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001436 Py_RETURN_NONE;
1437}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001439/* Generic read function: read from the stream until enough bytes are read,
1440 * or until an EOF occurs or until read() would block.
1441 */
1442static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001443_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001444{
1445 PyObject *res = NULL;
1446 Py_ssize_t current_size, remaining, written;
1447 char *out;
1448
1449 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1450 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001451 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001452
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001453 res = PyBytes_FromStringAndSize(NULL, n);
1454 if (res == NULL)
1455 goto error;
1456 out = PyBytes_AS_STRING(res);
1457 remaining = n;
1458 written = 0;
1459 if (current_size > 0) {
1460 memcpy(out, self->buffer + self->pos, current_size);
1461 remaining -= current_size;
1462 written += current_size;
1463 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001464 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465 while (remaining > 0) {
1466 /* We want to read a whole block at the end into buffer.
1467 If we had readv() we could do this in one pass. */
1468 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1469 if (r == 0)
1470 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001471 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001472 if (r == -1)
1473 goto error;
1474 if (r == 0 || r == -2) {
1475 /* EOF occurred or read() would block. */
1476 if (r == 0 || written > 0) {
1477 if (_PyBytes_Resize(&res, written))
1478 goto error;
1479 return res;
1480 }
1481 Py_DECREF(res);
1482 Py_INCREF(Py_None);
1483 return Py_None;
1484 }
1485 remaining -= r;
1486 written += r;
1487 }
1488 assert(remaining <= self->buffer_size);
1489 self->pos = 0;
1490 self->raw_pos = 0;
1491 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001492 /* NOTE: when the read is satisfied, we avoid issuing any additional
1493 reads, which could block indefinitely (e.g. on a socket).
1494 See issue #9550. */
1495 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001496 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001497 if (r == -1)
1498 goto error;
1499 if (r == 0 || r == -2) {
1500 /* EOF occurred or read() would block. */
1501 if (r == 0 || written > 0) {
1502 if (_PyBytes_Resize(&res, written))
1503 goto error;
1504 return res;
1505 }
1506 Py_DECREF(res);
1507 Py_INCREF(Py_None);
1508 return Py_None;
1509 }
1510 if (remaining > r) {
1511 memcpy(out + written, self->buffer + self->pos, r);
1512 written += r;
1513 self->pos += r;
1514 remaining -= r;
1515 }
1516 else if (remaining > 0) {
1517 memcpy(out + written, self->buffer + self->pos, remaining);
1518 written += remaining;
1519 self->pos += remaining;
1520 remaining = 0;
1521 }
1522 if (remaining == 0)
1523 break;
1524 }
1525
1526 return res;
1527
1528error:
1529 Py_XDECREF(res);
1530 return NULL;
1531}
1532
1533static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001534_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001535{
1536 Py_ssize_t have, r;
1537
1538 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1539 /* Constraints:
1540 1. we don't want to advance the file position.
1541 2. we don't want to lose block alignment, so we can't shift the buffer
1542 to make some place.
1543 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1544 */
1545 if (have > 0) {
1546 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1547 }
1548
1549 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001550 _bufferedreader_reset_buf(self);
1551 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001552 if (r == -1)
1553 return NULL;
1554 if (r == -2)
1555 r = 0;
1556 self->pos = 0;
1557 return PyBytes_FromStringAndSize(self->buffer, r);
1558}
1559
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001560static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001561 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001562 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1563 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1564 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1565 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1566 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1567 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1568 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1569 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001570 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001571 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001573 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1574 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1575 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
1576 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1577 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1578 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1579 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001580 {NULL, NULL}
1581};
1582
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001583static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001584 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001585 {NULL}
1586};
1587
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001588static PyGetSetDef bufferedreader_getset[] = {
1589 {"closed", (getter)buffered_closed_get, NULL, NULL},
1590 {"name", (getter)buffered_name_get, NULL, NULL},
1591 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001592 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001593};
1594
1595
1596PyTypeObject PyBufferedReader_Type = {
1597 PyVarObject_HEAD_INIT(NULL, 0)
1598 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001599 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001600 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001601 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001602 0, /*tp_print*/
1603 0, /*tp_getattr*/
1604 0, /*tp_setattr*/
1605 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001606 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001607 0, /*tp_as_number*/
1608 0, /*tp_as_sequence*/
1609 0, /*tp_as_mapping*/
1610 0, /*tp_hash */
1611 0, /*tp_call*/
1612 0, /*tp_str*/
1613 0, /*tp_getattro*/
1614 0, /*tp_setattro*/
1615 0, /*tp_as_buffer*/
1616 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1617 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001618 bufferedreader_doc, /* tp_doc */
1619 (traverseproc)buffered_traverse, /* tp_traverse */
1620 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001621 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001622 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001623 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001624 (iternextfunc)buffered_iternext, /* tp_iternext */
1625 bufferedreader_methods, /* tp_methods */
1626 bufferedreader_members, /* tp_members */
1627 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001628 0, /* tp_base */
1629 0, /* tp_dict */
1630 0, /* tp_descr_get */
1631 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001632 offsetof(buffered, dict), /* tp_dictoffset */
1633 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001634 0, /* tp_alloc */
1635 PyType_GenericNew, /* tp_new */
1636};
1637
1638
Benjamin Peterson59406a92009-03-26 17:10:29 +00001639
1640static int
1641complain_about_max_buffer_size(void)
1642{
1643 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1644 "max_buffer_size is deprecated", 1) < 0)
1645 return 0;
1646 return 1;
1647}
1648
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001649/*
1650 * class BufferedWriter
1651 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001652PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001653 "A buffer for a writeable sequential RawIO object.\n"
1654 "\n"
1655 "The constructor creates a BufferedWriter for the given writeable raw\n"
1656 "stream. If the buffer_size is not given, it defaults to\n"
1657 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1658 );
1659
1660static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001661_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001662{
1663 self->write_pos = 0;
1664 self->write_end = -1;
1665}
1666
1667static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001668bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001669{
1670 /* TODO: properly deprecate max_buffer_size */
1671 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1672 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001673 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001674 PyObject *raw;
1675
1676 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001677 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001678
1679 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1680 &raw, &buffer_size, &max_buffer_size)) {
1681 return -1;
1682 }
1683
Benjamin Peterson59406a92009-03-26 17:10:29 +00001684 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1685 return -1;
1686
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001687 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001688 return -1;
1689
1690 Py_CLEAR(self->raw);
1691 Py_INCREF(raw);
1692 self->raw = raw;
1693 self->readable = 0;
1694 self->writable = 1;
1695
1696 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001697 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001698 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001699 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700 self->pos = 0;
1701
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001702 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1703 Py_TYPE(raw) == &PyFileIO_Type);
1704
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001705 self->ok = 1;
1706 return 0;
1707}
1708
1709static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001710_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001711{
1712 Py_buffer buf;
1713 PyObject *memobj, *res;
1714 Py_ssize_t n;
1715 /* NOTE: the buffer needn't be released as its object is NULL. */
1716 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1717 return -1;
1718 memobj = PyMemoryView_FromBuffer(&buf);
1719 if (memobj == NULL)
1720 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001721 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1722 occurs so we needn't do it ourselves.
1723 We then retry writing, ignoring the signal if no handler has
1724 raised (see issue #10956).
1725 */
1726 do {
1727 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1728 } while (res == NULL && _trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001729 Py_DECREF(memobj);
1730 if (res == NULL)
1731 return -1;
1732 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1733 Py_DECREF(res);
1734 if (n < 0 || n > len) {
1735 PyErr_Format(PyExc_IOError,
1736 "raw write() returned invalid length %zd "
1737 "(should have been between 0 and %zd)", n, len);
1738 return -1;
1739 }
1740 if (n > 0 && self->abs_pos != -1)
1741 self->abs_pos += n;
1742 return n;
1743}
1744
1745/* `restore_pos` is 1 if we need to restore the raw stream position at
1746 the end, 0 otherwise. */
1747static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001748_bufferedwriter_flush_unlocked(buffered *self, int restore_pos)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001749{
1750 Py_ssize_t written = 0;
1751 Py_off_t n, rewind;
1752
1753 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1754 goto end;
1755 /* First, rewind */
1756 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1757 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759 if (n < 0) {
1760 goto error;
1761 }
1762 self->raw_pos -= rewind;
1763 }
1764 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001765 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001766 self->buffer + self->write_pos,
1767 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1768 Py_off_t, Py_ssize_t));
1769 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001770 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001771 if (w == NULL)
1772 goto error;
1773 self->write_pos += *w;
1774 self->raw_pos = self->write_pos;
1775 written += *w;
1776 *w = written;
1777 /* Already re-raised */
1778 goto error;
1779 }
1780 self->write_pos += n;
1781 self->raw_pos = self->write_pos;
1782 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001783 /* Partial writes can return successfully when interrupted by a
1784 signal (see write(2)). We must run signal handlers before
1785 blocking another time, possibly indefinitely. */
1786 if (PyErr_CheckSignals() < 0)
1787 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 }
1789
1790 if (restore_pos) {
1791 Py_off_t forward = rewind - written;
1792 if (forward != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001793 n = _buffered_raw_seek(self, forward, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794 if (n < 0) {
1795 goto error;
1796 }
1797 self->raw_pos += forward;
1798 }
1799 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801
1802end:
1803 Py_RETURN_NONE;
1804
1805error:
1806 return NULL;
1807}
1808
1809static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001810bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811{
1812 PyObject *res = NULL;
1813 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001814 Py_ssize_t written, avail, remaining;
1815 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816
1817 CHECK_INITIALIZED(self)
1818 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1819 return NULL;
1820 }
1821
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001822 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823 PyErr_SetString(PyExc_ValueError, "write to closed file");
1824 PyBuffer_Release(&buf);
1825 return NULL;
1826 }
1827
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001828 if (!ENTER_BUFFERED(self)) {
1829 PyBuffer_Release(&buf);
1830 return NULL;
1831 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832
1833 /* Fast path: the data to write can be fully buffered. */
1834 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1835 self->pos = 0;
1836 self->raw_pos = 0;
1837 }
1838 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1839 if (buf.len <= avail) {
1840 memcpy(self->buffer + self->pos, buf.buf, buf.len);
1841 if (!VALID_WRITE_BUFFER(self)) {
1842 self->write_pos = self->pos;
1843 }
1844 ADJUST_POSITION(self, self->pos + buf.len);
1845 if (self->pos > self->write_end)
1846 self->write_end = self->pos;
1847 written = buf.len;
1848 goto end;
1849 }
1850
1851 /* First write the current buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001852 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001854 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001855 if (w == NULL)
1856 goto error;
1857 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001858 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859 /* Make some place by shifting the buffer. */
1860 assert(VALID_WRITE_BUFFER(self));
1861 memmove(self->buffer, self->buffer + self->write_pos,
1862 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1863 Py_off_t, Py_ssize_t));
1864 self->write_end -= self->write_pos;
1865 self->raw_pos -= self->write_pos;
1866 self->pos -= self->write_pos;
1867 self->write_pos = 0;
1868 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1869 Py_off_t, Py_ssize_t);
1870 if (buf.len <= avail) {
1871 /* Everything can be buffered */
1872 PyErr_Clear();
1873 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1874 self->write_end += buf.len;
1875 written = buf.len;
1876 goto end;
1877 }
1878 /* Buffer as much as possible. */
1879 memcpy(self->buffer + self->write_end, buf.buf, avail);
1880 self->write_end += avail;
1881 /* Already re-raised */
1882 *w = avail;
1883 goto error;
1884 }
1885 Py_CLEAR(res);
1886
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001887 /* Adjust the raw stream position if it is away from the logical stream
1888 position. This happens if the read buffer has been filled but not
1889 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1890 the raw stream by itself).
1891 Fixes issue #6629.
1892 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001893 offset = RAW_OFFSET(self);
1894 if (offset != 0) {
1895 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001896 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001897 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001898 }
1899
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900 /* Then write buf itself. At this point the buffer has been emptied. */
1901 remaining = buf.len;
1902 written = 0;
1903 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001904 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001905 self, (char *) buf.buf + written, buf.len - written);
1906 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001907 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908 if (w == NULL)
1909 goto error;
1910 written += *w;
1911 remaining -= *w;
1912 if (remaining > self->buffer_size) {
1913 /* Can't buffer everything, still buffer as much as possible */
1914 memcpy(self->buffer,
1915 (char *) buf.buf + written, self->buffer_size);
1916 self->raw_pos = 0;
1917 ADJUST_POSITION(self, self->buffer_size);
1918 self->write_end = self->buffer_size;
1919 *w = written + self->buffer_size;
1920 /* Already re-raised */
1921 goto error;
1922 }
1923 PyErr_Clear();
1924 break;
1925 }
1926 written += n;
1927 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001928 /* Partial writes can return successfully when interrupted by a
1929 signal (see write(2)). We must run signal handlers before
1930 blocking another time, possibly indefinitely. */
1931 if (PyErr_CheckSignals() < 0)
1932 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933 }
1934 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001935 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936 if (remaining > 0) {
1937 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1938 written += remaining;
1939 }
1940 self->write_pos = 0;
1941 /* TODO: sanity check (remaining >= 0) */
1942 self->write_end = remaining;
1943 ADJUST_POSITION(self, remaining);
1944 self->raw_pos = 0;
1945
1946end:
1947 res = PyLong_FromSsize_t(written);
1948
1949error:
1950 LEAVE_BUFFERED(self)
1951 PyBuffer_Release(&buf);
1952 return res;
1953}
1954
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001955static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001956 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001957 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1958 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1959 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1960 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1961 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1962 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1963 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001964 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001965 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001967 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
1968 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1969 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
1970 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1971 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972 {NULL, NULL}
1973};
1974
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001975static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001976 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001977 {NULL}
1978};
1979
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001980static PyGetSetDef bufferedwriter_getset[] = {
1981 {"closed", (getter)buffered_closed_get, NULL, NULL},
1982 {"name", (getter)buffered_name_get, NULL, NULL},
1983 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001984 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001985};
1986
1987
1988PyTypeObject PyBufferedWriter_Type = {
1989 PyVarObject_HEAD_INIT(NULL, 0)
1990 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001991 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001992 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001993 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001994 0, /*tp_print*/
1995 0, /*tp_getattr*/
1996 0, /*tp_setattr*/
1997 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001998 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 0, /*tp_as_number*/
2000 0, /*tp_as_sequence*/
2001 0, /*tp_as_mapping*/
2002 0, /*tp_hash */
2003 0, /*tp_call*/
2004 0, /*tp_str*/
2005 0, /*tp_getattro*/
2006 0, /*tp_setattro*/
2007 0, /*tp_as_buffer*/
2008 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2009 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002010 bufferedwriter_doc, /* tp_doc */
2011 (traverseproc)buffered_traverse, /* tp_traverse */
2012 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002013 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002014 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 0, /* tp_iter */
2016 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002017 bufferedwriter_methods, /* tp_methods */
2018 bufferedwriter_members, /* tp_members */
2019 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 0, /* tp_base */
2021 0, /* tp_dict */
2022 0, /* tp_descr_get */
2023 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002024 offsetof(buffered, dict), /* tp_dictoffset */
2025 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 0, /* tp_alloc */
2027 PyType_GenericNew, /* tp_new */
2028};
2029
2030
2031
2032/*
2033 * BufferedRWPair
2034 */
2035
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002036PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 "A buffered reader and writer object together.\n"
2038 "\n"
2039 "A buffered reader object and buffered writer object put together to\n"
2040 "form a sequential IO object that can read and write. This is typically\n"
2041 "used with a socket or two-way pipe.\n"
2042 "\n"
2043 "reader and writer are RawIOBase objects that are readable and\n"
2044 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002045 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 );
2047
2048/* XXX The usefulness of this (compared to having two separate IO objects) is
2049 * questionable.
2050 */
2051
2052typedef struct {
2053 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002054 buffered *reader;
2055 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 PyObject *dict;
2057 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002058} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059
2060static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002061bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002062{
2063 PyObject *reader, *writer;
2064 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002065 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066
2067 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
2068 &buffer_size, &max_buffer_size)) {
2069 return -1;
2070 }
2071
Benjamin Peterson59406a92009-03-26 17:10:29 +00002072 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2073 return -1;
2074
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002075 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002077 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078 return -1;
2079
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002080 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002081 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002082 if (self->reader == NULL)
2083 return -1;
2084
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002085 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002086 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002087 if (self->writer == NULL) {
2088 Py_CLEAR(self->reader);
2089 return -1;
2090 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002091
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002092 return 0;
2093}
2094
2095static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002096bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097{
2098 Py_VISIT(self->dict);
2099 return 0;
2100}
2101
2102static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104{
2105 Py_CLEAR(self->reader);
2106 Py_CLEAR(self->writer);
2107 Py_CLEAR(self->dict);
2108 return 0;
2109}
2110
2111static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113{
2114 _PyObject_GC_UNTRACK(self);
2115 Py_CLEAR(self->reader);
2116 Py_CLEAR(self->writer);
2117 Py_CLEAR(self->dict);
2118 Py_TYPE(self)->tp_free((PyObject *) self);
2119}
2120
2121static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002122_forward_call(buffered *self, const char *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123{
2124 PyObject *func = PyObject_GetAttrString((PyObject *)self, name);
2125 PyObject *ret;
2126
2127 if (func == NULL) {
2128 PyErr_SetString(PyExc_AttributeError, name);
2129 return NULL;
2130 }
2131
2132 ret = PyObject_CallObject(func, args);
2133 Py_DECREF(func);
2134 return ret;
2135}
2136
2137static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002138bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139{
2140 return _forward_call(self->reader, "read", args);
2141}
2142
2143static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002144bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145{
2146 return _forward_call(self->reader, "peek", args);
2147}
2148
2149static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002150bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151{
2152 return _forward_call(self->reader, "read1", args);
2153}
2154
2155static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002156bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002157{
2158 return _forward_call(self->reader, "readinto", args);
2159}
2160
2161static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002162bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002163{
2164 return _forward_call(self->writer, "write", args);
2165}
2166
2167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169{
2170 return _forward_call(self->writer, "flush", args);
2171}
2172
2173static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002174bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175{
2176 return _forward_call(self->reader, "readable", args);
2177}
2178
2179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181{
2182 return _forward_call(self->writer, "writable", args);
2183}
2184
2185static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187{
2188 PyObject *ret = _forward_call(self->writer, "close", args);
2189 if (ret == NULL)
2190 return NULL;
2191 Py_DECREF(ret);
2192
2193 return _forward_call(self->reader, "close", args);
2194}
2195
2196static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002197bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002198{
2199 PyObject *ret = _forward_call(self->writer, "isatty", args);
2200
2201 if (ret != Py_False) {
2202 /* either True or exception */
2203 return ret;
2204 }
2205 Py_DECREF(ret);
2206
2207 return _forward_call(self->reader, "isatty", args);
2208}
2209
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002210static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002211bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002212{
2213 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2214}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002216static PyMethodDef bufferedrwpair_methods[] = {
2217 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2218 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2219 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2220 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2223 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002225 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2226 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002228 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2229 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230
Antoine Pitrou243757e2010-11-05 21:15:39 +00002231 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2232
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233 {NULL, NULL}
2234};
2235
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002236static PyGetSetDef bufferedrwpair_getset[] = {
2237 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002238 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002239};
2240
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002241PyTypeObject PyBufferedRWPair_Type = {
2242 PyVarObject_HEAD_INIT(NULL, 0)
2243 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002244 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002246 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002247 0, /*tp_print*/
2248 0, /*tp_getattr*/
2249 0, /*tp_setattr*/
2250 0, /*tp_compare */
2251 0, /*tp_repr*/
2252 0, /*tp_as_number*/
2253 0, /*tp_as_sequence*/
2254 0, /*tp_as_mapping*/
2255 0, /*tp_hash */
2256 0, /*tp_call*/
2257 0, /*tp_str*/
2258 0, /*tp_getattro*/
2259 0, /*tp_setattro*/
2260 0, /*tp_as_buffer*/
2261 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2262 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002263 bufferedrwpair_doc, /* tp_doc */
2264 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2265 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002267 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002268 0, /* tp_iter */
2269 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002270 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002272 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273 0, /* tp_base */
2274 0, /* tp_dict */
2275 0, /* tp_descr_get */
2276 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002277 offsetof(rwpair, dict), /* tp_dictoffset */
2278 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002279 0, /* tp_alloc */
2280 PyType_GenericNew, /* tp_new */
2281};
2282
2283
2284
2285/*
2286 * BufferedRandom
2287 */
2288
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290 "A buffered interface to random access streams.\n"
2291 "\n"
2292 "The constructor creates a reader and writer for a seekable stream,\n"
2293 "raw, given in the first argument. If the buffer_size is omitted it\n"
2294 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2295 );
2296
2297static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002298bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299{
2300 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2301 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002302 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303 PyObject *raw;
2304
2305 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002306 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307
2308 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2309 &raw, &buffer_size, &max_buffer_size)) {
2310 return -1;
2311 }
2312
Benjamin Peterson59406a92009-03-26 17:10:29 +00002313 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2314 return -1;
2315
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002316 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002318 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002320 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002321 return -1;
2322
2323 Py_CLEAR(self->raw);
2324 Py_INCREF(raw);
2325 self->raw = raw;
2326 self->buffer_size = buffer_size;
2327 self->readable = 1;
2328 self->writable = 1;
2329
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002330 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002332 _bufferedreader_reset_buf(self);
2333 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334 self->pos = 0;
2335
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002336 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2337 Py_TYPE(raw) == &PyFileIO_Type);
2338
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339 self->ok = 1;
2340 return 0;
2341}
2342
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002343static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002344 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002345 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2346 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2347 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2348 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2349 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2350 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2351 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002352 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002353 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002354
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002355 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002356
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002357 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2358 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2359 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2360 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2361 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2362 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2363 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2364 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2365 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002366 {NULL, NULL}
2367};
2368
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002369static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002370 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371 {NULL}
2372};
2373
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002374static PyGetSetDef bufferedrandom_getset[] = {
2375 {"closed", (getter)buffered_closed_get, NULL, NULL},
2376 {"name", (getter)buffered_name_get, NULL, NULL},
2377 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002378 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002379};
2380
2381
2382PyTypeObject PyBufferedRandom_Type = {
2383 PyVarObject_HEAD_INIT(NULL, 0)
2384 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002385 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002386 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002387 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388 0, /*tp_print*/
2389 0, /*tp_getattr*/
2390 0, /*tp_setattr*/
2391 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002392 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002393 0, /*tp_as_number*/
2394 0, /*tp_as_sequence*/
2395 0, /*tp_as_mapping*/
2396 0, /*tp_hash */
2397 0, /*tp_call*/
2398 0, /*tp_str*/
2399 0, /*tp_getattro*/
2400 0, /*tp_setattro*/
2401 0, /*tp_as_buffer*/
2402 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2403 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002404 bufferedrandom_doc, /* tp_doc */
2405 (traverseproc)buffered_traverse, /* tp_traverse */
2406 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002407 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002408 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002409 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002410 (iternextfunc)buffered_iternext, /* tp_iternext */
2411 bufferedrandom_methods, /* tp_methods */
2412 bufferedrandom_members, /* tp_members */
2413 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002414 0, /* tp_base */
2415 0, /*tp_dict*/
2416 0, /* tp_descr_get */
2417 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002418 offsetof(buffered, dict), /*tp_dictoffset*/
2419 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 0, /* tp_alloc */
2421 PyType_GenericNew, /* tp_new */
2422};