blob: 504e2cbd14091cc6c59b16150c74bd15d4c5d84a [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;
Georg Brandldfd73442009-04-05 11:47:34 +0000228#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000229
230 Py_ssize_t buffer_size;
231 Py_ssize_t buffer_mask;
232
233 PyObject *dict;
234 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000235} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000236
237/*
238 Implementation notes:
239
240 * BufferedReader, BufferedWriter and BufferedRandom try to share most
241 methods (this is helped by the members `readable` and `writable`, which
242 are initialized in the respective constructors)
243 * They also share a single buffer for reading and writing. This enables
244 interleaved reads and writes without flushing. It also makes the logic
245 a bit trickier to get right.
246 * The absolute position of the raw stream is cached, if possible, in the
247 `abs_pos` member. It must be updated every time an operation is done
248 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000249 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000251 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
252 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000253
254 NOTE: we should try to maintain block alignment of reads and writes to the
255 raw stream (according to the buffer size), but for now it is only done
256 in read() and friends.
257
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000258*/
259
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000260/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000261
Georg Brandldfd73442009-04-05 11:47:34 +0000262#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000263#define ENTER_BUFFERED(self) \
Antoine Pitrou5800b272009-11-01 12:05:48 +0000264 if (!PyThread_acquire_lock(self->lock, 0)) { \
265 Py_BEGIN_ALLOW_THREADS \
266 PyThread_acquire_lock(self->lock, 1); \
267 Py_END_ALLOW_THREADS \
268 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000269
270#define LEAVE_BUFFERED(self) \
271 PyThread_release_lock(self->lock);
Georg Brandldfd73442009-04-05 11:47:34 +0000272#else
273#define ENTER_BUFFERED(self)
274#define LEAVE_BUFFERED(self)
275#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000276
277#define CHECK_INITIALIZED(self) \
278 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000279 if (self->detached) { \
280 PyErr_SetString(PyExc_ValueError, \
281 "raw stream has been detached"); \
282 } else { \
283 PyErr_SetString(PyExc_ValueError, \
284 "I/O operation on uninitialized object"); \
285 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000286 return NULL; \
287 }
288
289#define CHECK_INITIALIZED_INT(self) \
290 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000291 if (self->detached) { \
292 PyErr_SetString(PyExc_ValueError, \
293 "raw stream has been detached"); \
294 } else { \
295 PyErr_SetString(PyExc_ValueError, \
296 "I/O operation on uninitialized object"); \
297 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000298 return -1; \
299 }
300
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000301#define IS_CLOSED(self) \
302 (self->fast_closed_checks \
303 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000304 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000305
306#define CHECK_CLOSED(self, error_msg) \
307 if (IS_CLOSED(self)) { \
308 PyErr_SetString(PyExc_ValueError, error_msg); \
309 return NULL; \
310 }
311
312
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000313#define VALID_READ_BUFFER(self) \
314 (self->readable && self->read_end != -1)
315
316#define VALID_WRITE_BUFFER(self) \
317 (self->writable && self->write_end != -1)
318
319#define ADJUST_POSITION(self, _new_pos) \
320 do { \
321 self->pos = _new_pos; \
322 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
323 self->read_end = self->pos; \
324 } while(0)
325
326#define READAHEAD(self) \
327 ((self->readable && VALID_READ_BUFFER(self)) \
328 ? (self->read_end - self->pos) : 0)
329
330#define RAW_OFFSET(self) \
331 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
332 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
333
334#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000335 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336
337#define MINUS_LAST_BLOCK(self, size) \
338 (self->buffer_mask ? \
339 (size & ~self->buffer_mask) : \
340 (self->buffer_size * (size / self->buffer_size)))
341
342
343static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000344buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000345{
Antoine Pitroue033e062010-10-29 10:38:18 +0000346 self->deallocating = 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000347 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
348 return;
349 _PyObject_GC_UNTRACK(self);
350 self->ok = 0;
351 if (self->weakreflist != NULL)
352 PyObject_ClearWeakRefs((PyObject *)self);
353 Py_CLEAR(self->raw);
354 if (self->buffer) {
355 PyMem_Free(self->buffer);
356 self->buffer = NULL;
357 }
Georg Brandldfd73442009-04-05 11:47:34 +0000358#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000359 if (self->lock) {
360 PyThread_free_lock(self->lock);
361 self->lock = NULL;
362 }
Georg Brandldfd73442009-04-05 11:47:34 +0000363#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000364 Py_CLEAR(self->dict);
365 Py_TYPE(self)->tp_free((PyObject *)self);
366}
367
368static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000369buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000370{
371 Py_VISIT(self->raw);
372 Py_VISIT(self->dict);
373 return 0;
374}
375
376static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000377buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000378{
379 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
380 return -1;
381 self->ok = 0;
382 Py_CLEAR(self->raw);
383 Py_CLEAR(self->dict);
384 return 0;
385}
386
Antoine Pitroue033e062010-10-29 10:38:18 +0000387/* Because this can call arbitrary code, it shouldn't be called when
388 the refcount is 0 (that is, not directly from tp_dealloc unless
389 the refcount has been temporarily re-incremented). */
390PyObject *
391buffered_dealloc_warn(buffered *self, PyObject *source)
392{
393 if (self->ok && self->raw) {
394 PyObject *r;
395 r = PyObject_CallMethod(self->raw, "_dealloc_warn", "O", source);
396 if (r)
397 Py_DECREF(r);
398 else
399 PyErr_Clear();
400 }
401 Py_RETURN_NONE;
402}
403
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000404/*
405 * _BufferedIOMixin methods
406 * This is not a class, just a collection of methods that will be reused
407 * by BufferedReader and BufferedWriter
408 */
409
410/* Flush and close */
411
412static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000413buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000414{
415 CHECK_INITIALIZED(self)
416 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
417}
418
419static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000420buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000421{
422 int closed;
423 PyObject *res;
424 CHECK_INITIALIZED_INT(self)
425 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
426 if (res == NULL)
427 return -1;
428 closed = PyObject_IsTrue(res);
429 Py_DECREF(res);
430 return closed;
431}
432
433static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000434buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435{
436 CHECK_INITIALIZED(self)
437 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
438}
439
440static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000441buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000442{
443 PyObject *res = NULL;
444 int r;
445
446 CHECK_INITIALIZED(self)
447 ENTER_BUFFERED(self)
448
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000449 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000450 if (r < 0)
451 goto end;
452 if (r > 0) {
453 res = Py_None;
454 Py_INCREF(res);
455 goto end;
456 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000457
458 if (self->deallocating) {
459 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
460 if (r)
461 Py_DECREF(r);
462 else
463 PyErr_Clear();
464 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000465 /* flush() will most probably re-take the lock, so drop it first */
466 LEAVE_BUFFERED(self)
467 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
468 ENTER_BUFFERED(self)
469 if (res == NULL) {
Antoine Pitrou6be88762010-05-03 16:48:20 +0000470 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000471 }
472 Py_XDECREF(res);
473
474 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
475
476end:
477 LEAVE_BUFFERED(self)
478 return res;
479}
480
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000481/* detach */
482
483static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000484buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000485{
486 PyObject *raw, *res;
487 CHECK_INITIALIZED(self)
488 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
489 if (res == NULL)
490 return NULL;
491 Py_DECREF(res);
492 raw = self->raw;
493 self->raw = NULL;
494 self->detached = 1;
495 self->ok = 0;
496 return raw;
497}
498
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000499/* Inquiries */
500
501static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503{
504 CHECK_INITIALIZED(self)
505 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
506}
507
508static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000509buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510{
511 CHECK_INITIALIZED(self)
512 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
513}
514
515static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000516buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000517{
518 CHECK_INITIALIZED(self)
519 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
520}
521
522static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000523buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000524{
525 CHECK_INITIALIZED(self)
526 return PyObject_GetAttrString(self->raw, "name");
527}
528
529static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000530buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000531{
532 CHECK_INITIALIZED(self)
533 return PyObject_GetAttrString(self->raw, "mode");
534}
535
536/* Lower-level APIs */
537
538static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000539buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000540{
541 CHECK_INITIALIZED(self)
542 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
543}
544
545static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000546buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000547{
548 CHECK_INITIALIZED(self)
549 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
550}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000551
Antoine Pitrou243757e2010-11-05 21:15:39 +0000552/* Serialization */
553
554static PyObject *
555buffered_getstate(buffered *self, PyObject *args)
556{
557 PyErr_Format(PyExc_TypeError,
558 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
559 return NULL;
560}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000561
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562/* Forward decls */
563static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000564_bufferedwriter_flush_unlocked(buffered *, int);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000566_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000567static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000568_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000570_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000571static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000572_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000574_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000575static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000576_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000577static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000578_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579
580
581/*
582 * Helpers
583 */
584
585/* Returns the address of the `written` member if a BlockingIOError was
586 raised, NULL otherwise. The error is always re-raised. */
587static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589{
590 PyObject *t, *v, *tb;
591 PyBlockingIOErrorObject *err;
592
593 PyErr_Fetch(&t, &v, &tb);
594 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
595 PyErr_Restore(t, v, tb);
596 return NULL;
597 }
598 err = (PyBlockingIOErrorObject *) v;
599 /* TODO: sanity check (err->written >= 0) */
600 PyErr_Restore(t, v, tb);
601 return &err->written;
602}
603
604static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000608 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
610 if (res == NULL)
611 return -1;
612 n = PyNumber_AsOff_t(res, PyExc_ValueError);
613 Py_DECREF(res);
614 if (n < 0) {
615 if (!PyErr_Occurred())
616 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000617 "Raw stream returned invalid position %" PY_PRIdOFF,
618 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619 return -1;
620 }
621 self->abs_pos = n;
622 return n;
623}
624
625static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000626_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627{
628 PyObject *res, *posobj, *whenceobj;
629 Py_off_t n;
630
631 posobj = PyLong_FromOff_t(target);
632 if (posobj == NULL)
633 return -1;
634 whenceobj = PyLong_FromLong(whence);
635 if (whenceobj == NULL) {
636 Py_DECREF(posobj);
637 return -1;
638 }
639 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
640 posobj, whenceobj, NULL);
641 Py_DECREF(posobj);
642 Py_DECREF(whenceobj);
643 if (res == NULL)
644 return -1;
645 n = PyNumber_AsOff_t(res, PyExc_ValueError);
646 Py_DECREF(res);
647 if (n < 0) {
648 if (!PyErr_Occurred())
649 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000650 "Raw stream returned invalid position %" PY_PRIdOFF,
651 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652 return -1;
653 }
654 self->abs_pos = n;
655 return n;
656}
657
658static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000659_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660{
661 Py_ssize_t n;
662 if (self->buffer_size <= 0) {
663 PyErr_SetString(PyExc_ValueError,
664 "buffer size must be strictly positive");
665 return -1;
666 }
667 if (self->buffer)
668 PyMem_Free(self->buffer);
669 self->buffer = PyMem_Malloc(self->buffer_size);
670 if (self->buffer == NULL) {
671 PyErr_NoMemory();
672 return -1;
673 }
Georg Brandldfd73442009-04-05 11:47:34 +0000674#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000675 if (self->lock)
676 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677 self->lock = PyThread_allocate_lock();
678 if (self->lock == NULL) {
679 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
680 return -1;
681 }
Georg Brandldfd73442009-04-05 11:47:34 +0000682#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000683 /* Find out whether buffer_size is a power of 2 */
684 /* XXX is this optimization useful? */
685 for (n = self->buffer_size - 1; n & 1; n >>= 1)
686 ;
687 if (n == 0)
688 self->buffer_mask = self->buffer_size - 1;
689 else
690 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000691 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 PyErr_Clear();
693 return 0;
694}
695
696/*
697 * Shared methods and wrappers
698 */
699
700static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000701buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702{
703 PyObject *res;
704
705 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000706 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707
708 ENTER_BUFFERED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000709 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710 if (res != NULL && self->readable) {
711 /* Rewind the raw stream so that its position corresponds to
712 the current logical position. */
713 Py_off_t n;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000714 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715 if (n == -1)
716 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000717 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000718 }
719 LEAVE_BUFFERED(self)
720
721 return res;
722}
723
724static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000725buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000726{
727 Py_ssize_t n = 0;
728 PyObject *res = NULL;
729
730 CHECK_INITIALIZED(self)
731 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
732 return NULL;
733 }
734
735 ENTER_BUFFERED(self)
736
737 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000738 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000739 if (res == NULL)
740 goto end;
741 Py_CLEAR(res);
742 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000743 res = _bufferedreader_peek_unlocked(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000744
745end:
746 LEAVE_BUFFERED(self)
747 return res;
748}
749
750static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000751buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000752{
753 Py_ssize_t n = -1;
754 PyObject *res;
755
756 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000757 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000758 return NULL;
759 }
760 if (n < -1) {
761 PyErr_SetString(PyExc_ValueError,
762 "read length must be positive or -1");
763 return NULL;
764 }
765
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000766 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000767
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000768 if (n == -1) {
769 /* The number of bytes is unspecified, read until the end of stream */
770 ENTER_BUFFERED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000771 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000772 LEAVE_BUFFERED(self)
773 }
774 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000775 res = _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000776 if (res == Py_None) {
777 Py_DECREF(res);
778 ENTER_BUFFERED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000779 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000780 LEAVE_BUFFERED(self)
781 }
782 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000783
784 return res;
785}
786
787static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000788buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000789{
790 Py_ssize_t n, have, r;
791 PyObject *res = NULL;
792
793 CHECK_INITIALIZED(self)
794 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
795 return NULL;
796 }
797
798 if (n < 0) {
799 PyErr_SetString(PyExc_ValueError,
800 "read length must be positive");
801 return NULL;
802 }
803 if (n == 0)
804 return PyBytes_FromStringAndSize(NULL, 0);
805
806 ENTER_BUFFERED(self)
807
808 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000809 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000810 if (res == NULL)
811 goto end;
812 Py_CLEAR(res);
813 }
814
815 /* Return up to n bytes. If at least one byte is buffered, we
816 only return buffered bytes. Otherwise, we do one raw read. */
817
818 /* XXX: this mimicks the io.py implementation but is probably wrong.
819 If we need to read from the raw stream, then we could actually read
820 all `n` bytes asked by the caller (and possibly more, so as to fill
821 our buffer for the next reads). */
822
823 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
824 if (have > 0) {
825 if (n > have)
826 n = have;
827 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
828 if (res == NULL)
829 goto end;
830 self->pos += n;
831 goto end;
832 }
833
834 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000835 _bufferedreader_reset_buf(self);
836 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000837 if (r == -1)
838 goto end;
839 if (r == -2)
840 r = 0;
841 if (n > r)
842 n = r;
843 res = PyBytes_FromStringAndSize(self->buffer, n);
844 if (res == NULL)
845 goto end;
846 self->pos = n;
847
848end:
849 LEAVE_BUFFERED(self)
850 return res;
851}
852
853static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000854buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855{
856 PyObject *res = NULL;
857
858 CHECK_INITIALIZED(self)
859
860 /* TODO: use raw.readinto() instead! */
861 if (self->writable) {
862 ENTER_BUFFERED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000863 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864 LEAVE_BUFFERED(self)
865 if (res == NULL)
866 goto end;
867 Py_DECREF(res);
868 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000869 res = bufferediobase_readinto((PyObject *)self, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000870
871end:
872 return res;
873}
874
875static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000876_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000877{
878 PyObject *res = NULL;
879 PyObject *chunks = NULL;
880 Py_ssize_t n, written = 0;
881 const char *start, *s, *end;
882
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000883 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000884
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000885 /* First, try to find a line in the buffer. This can run unlocked because
886 the calls to the C API are simple enough that they can't trigger
887 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000888 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
889 if (limit >= 0 && n > limit)
890 n = limit;
891 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000892 s = memchr(start, '\n', n);
893 if (s != NULL) {
894 res = PyBytes_FromStringAndSize(start, s - start + 1);
895 if (res != NULL)
896 self->pos += s - start + 1;
897 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000898 }
899 if (n == limit) {
900 res = PyBytes_FromStringAndSize(start, n);
901 if (res != NULL)
902 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000903 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000904 }
905
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000906 ENTER_BUFFERED(self)
907
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000908 /* Now we try to get some more from the raw stream */
909 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000910 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000911 if (res == NULL)
912 goto end;
913 Py_CLEAR(res);
914 }
915 chunks = PyList_New(0);
916 if (chunks == NULL)
917 goto end;
918 if (n > 0) {
919 res = PyBytes_FromStringAndSize(start, n);
920 if (res == NULL)
921 goto end;
922 if (PyList_Append(chunks, res) < 0) {
923 Py_CLEAR(res);
924 goto end;
925 }
926 Py_CLEAR(res);
927 written += n;
928 if (limit >= 0)
929 limit -= n;
930 }
931
932 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000933 _bufferedreader_reset_buf(self);
934 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000935 if (n == -1)
936 goto end;
937 if (n <= 0)
938 break;
939 if (limit >= 0 && n > limit)
940 n = limit;
941 start = self->buffer;
942 end = start + n;
943 s = start;
944 while (s < end) {
945 if (*s++ == '\n') {
946 res = PyBytes_FromStringAndSize(start, s - start);
947 if (res == NULL)
948 goto end;
949 self->pos = s - start;
950 goto found;
951 }
952 }
953 res = PyBytes_FromStringAndSize(start, n);
954 if (res == NULL)
955 goto end;
956 if (n == limit) {
957 self->pos = n;
958 break;
959 }
960 if (PyList_Append(chunks, res) < 0) {
961 Py_CLEAR(res);
962 goto end;
963 }
964 Py_CLEAR(res);
965 written += n;
966 if (limit >= 0)
967 limit -= n;
968 }
969found:
970 if (res != NULL && PyList_Append(chunks, res) < 0) {
971 Py_CLEAR(res);
972 goto end;
973 }
974 Py_CLEAR(res);
975 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
976
977end:
978 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000979end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 Py_XDECREF(chunks);
981 return res;
982}
983
984static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000985buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986{
987 Py_ssize_t limit = -1;
988
989 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000990 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000991 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000992 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993}
994
995
996static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000997buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000998{
999 Py_off_t pos;
1000
1001 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001002 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003 if (pos == -1)
1004 return NULL;
1005 pos -= RAW_OFFSET(self);
1006 /* TODO: sanity check (pos >= 0) */
1007 return PyLong_FromOff_t(pos);
1008}
1009
1010static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001011buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012{
1013 Py_off_t target, n;
1014 int whence = 0;
1015 PyObject *targetobj, *res = NULL;
1016
1017 CHECK_INITIALIZED(self)
1018 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1019 return NULL;
1020 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021 if (whence < 0 || whence > 2) {
1022 PyErr_Format(PyExc_ValueError,
1023 "whence must be between 0 and 2, not %d", whence);
1024 return NULL;
1025 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001026
1027 CHECK_CLOSED(self, "seek of closed file")
1028
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001029 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1030 if (target == -1 && PyErr_Occurred())
1031 return NULL;
1032
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001033 if (whence != 2 && self->readable) {
1034 Py_off_t current, avail;
1035 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001036 so as to return quickly if possible. Also, we needn't take the
1037 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001038 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001039 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1040 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 current = RAW_TELL(self);
1042 avail = READAHEAD(self);
1043 if (avail > 0) {
1044 Py_off_t offset;
1045 if (whence == 0)
1046 offset = target - (current - RAW_OFFSET(self));
1047 else
1048 offset = target;
1049 if (offset >= -self->pos && offset <= avail) {
1050 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001051 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001052 }
1053 }
1054 }
1055
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001056 ENTER_BUFFERED(self)
1057
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058 /* Fallback: invoke raw seek() method and clear buffer */
1059 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001060 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001061 if (res == NULL)
1062 goto end;
1063 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001064 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065 }
1066
1067 /* TODO: align on block boundary and read buffer if needed? */
1068 if (whence == 1)
1069 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001070 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001071 if (n == -1)
1072 goto end;
1073 self->raw_pos = -1;
1074 res = PyLong_FromOff_t(n);
1075 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001076 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001077
1078end:
1079 LEAVE_BUFFERED(self)
1080 return res;
1081}
1082
1083static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001084buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001085{
1086 PyObject *pos = Py_None;
1087 PyObject *res = NULL;
1088
1089 CHECK_INITIALIZED(self)
1090 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1091 return NULL;
1092 }
1093
1094 ENTER_BUFFERED(self)
1095
1096 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001097 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001098 if (res == NULL)
1099 goto end;
1100 Py_CLEAR(res);
1101 }
1102 if (self->readable) {
1103 if (pos == Py_None) {
1104 /* Rewind the raw stream so that its position corresponds to
1105 the current logical position. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001106 if (_buffered_raw_seek(self, -RAW_OFFSET(self), 1) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001107 goto end;
1108 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001109 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001110 }
1111 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1112 if (res == NULL)
1113 goto end;
1114 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001115 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001116 PyErr_Clear();
1117
1118end:
1119 LEAVE_BUFFERED(self)
1120 return res;
1121}
1122
1123static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001124buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001125{
1126 PyObject *line;
1127 PyTypeObject *tp;
1128
1129 CHECK_INITIALIZED(self);
1130
1131 tp = Py_TYPE(self);
1132 if (tp == &PyBufferedReader_Type ||
1133 tp == &PyBufferedRandom_Type) {
1134 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001135 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001136 }
1137 else {
1138 line = PyObject_CallMethodObjArgs((PyObject *)self,
1139 _PyIO_str_readline, NULL);
1140 if (line && !PyBytes_Check(line)) {
1141 PyErr_Format(PyExc_IOError,
1142 "readline() should have returned a bytes object, "
1143 "not '%.200s'", Py_TYPE(line)->tp_name);
1144 Py_DECREF(line);
1145 return NULL;
1146 }
1147 }
1148
1149 if (line == NULL)
1150 return NULL;
1151
1152 if (PyBytes_GET_SIZE(line) == 0) {
1153 /* Reached EOF or would have blocked */
1154 Py_DECREF(line);
1155 return NULL;
1156 }
1157
1158 return line;
1159}
1160
Antoine Pitrou716c4442009-05-23 19:04:03 +00001161static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001162buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001163{
1164 PyObject *nameobj, *res;
1165
1166 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1167 if (nameobj == NULL) {
1168 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1169 PyErr_Clear();
1170 else
1171 return NULL;
1172 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1173 }
1174 else {
1175 res = PyUnicode_FromFormat("<%s name=%R>",
1176 Py_TYPE(self)->tp_name, nameobj);
1177 Py_DECREF(nameobj);
1178 }
1179 return res;
1180}
1181
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001182/*
1183 * class BufferedReader
1184 */
1185
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001186PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001187 "Create a new buffered reader using the given readable raw IO object.");
1188
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001189static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190{
1191 self->read_end = -1;
1192}
1193
1194static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001195bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001196{
1197 char *kwlist[] = {"raw", "buffer_size", NULL};
1198 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1199 PyObject *raw;
1200
1201 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001202 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001203
1204 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1205 &raw, &buffer_size)) {
1206 return -1;
1207 }
1208
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001209 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001210 return -1;
1211
1212 Py_CLEAR(self->raw);
1213 Py_INCREF(raw);
1214 self->raw = raw;
1215 self->buffer_size = buffer_size;
1216 self->readable = 1;
1217 self->writable = 0;
1218
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001219 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001221 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001223 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1224 Py_TYPE(raw) == &PyFileIO_Type);
1225
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226 self->ok = 1;
1227 return 0;
1228}
1229
1230static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001231_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001232{
1233 Py_buffer buf;
1234 PyObject *memobj, *res;
1235 Py_ssize_t n;
1236 /* NOTE: the buffer needn't be released as its object is NULL. */
1237 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1238 return -1;
1239 memobj = PyMemoryView_FromBuffer(&buf);
1240 if (memobj == NULL)
1241 return -1;
1242 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1243 Py_DECREF(memobj);
1244 if (res == NULL)
1245 return -1;
1246 if (res == Py_None) {
1247 /* Non-blocking stream would have blocked. Special return code! */
1248 Py_DECREF(res);
1249 return -2;
1250 }
1251 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1252 Py_DECREF(res);
1253 if (n < 0 || n > len) {
1254 PyErr_Format(PyExc_IOError,
1255 "raw readinto() returned invalid length %zd "
1256 "(should have been between 0 and %zd)", n, len);
1257 return -1;
1258 }
1259 if (n > 0 && self->abs_pos != -1)
1260 self->abs_pos += n;
1261 return n;
1262}
1263
1264static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001265_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266{
1267 Py_ssize_t start, len, n;
1268 if (VALID_READ_BUFFER(self))
1269 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1270 else
1271 start = 0;
1272 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001273 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 if (n <= 0)
1275 return n;
1276 self->read_end = start + n;
1277 self->raw_pos = start + n;
1278 return n;
1279}
1280
1281static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001282_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001284 Py_ssize_t current_size;
1285 PyObject *res, *data = NULL;
1286 PyObject *chunks = PyList_New(0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001287
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001288 if (chunks == NULL)
1289 return NULL;
1290
1291 /* First copy what we have in the current buffer. */
1292 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1293 if (current_size) {
1294 data = PyBytes_FromStringAndSize(
1295 self->buffer + self->pos, current_size);
1296 if (data == NULL) {
1297 Py_DECREF(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001299 }
1300 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001301 _bufferedreader_reset_buf(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001302 /* We're going past the buffer's bounds, flush it */
1303 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001304 res = _bufferedwriter_flush_unlocked(self, 1);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001305 if (res == NULL) {
1306 Py_DECREF(chunks);
1307 return NULL;
1308 }
1309 Py_CLEAR(res);
1310 }
1311 while (1) {
1312 if (data) {
1313 if (PyList_Append(chunks, data) < 0) {
1314 Py_DECREF(data);
1315 Py_DECREF(chunks);
1316 return NULL;
1317 }
1318 Py_DECREF(data);
1319 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001321 /* Read until EOF or until read() would block. */
1322 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1323 if (data == NULL) {
1324 Py_DECREF(chunks);
1325 return NULL;
1326 }
1327 if (data != Py_None && !PyBytes_Check(data)) {
1328 Py_DECREF(data);
1329 Py_DECREF(chunks);
1330 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1331 return NULL;
1332 }
1333 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1334 if (current_size == 0) {
1335 Py_DECREF(chunks);
1336 return data;
1337 }
1338 else {
1339 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1340 Py_DECREF(data);
1341 Py_DECREF(chunks);
1342 return res;
1343 }
1344 }
1345 current_size += PyBytes_GET_SIZE(data);
1346 if (self->abs_pos != -1)
1347 self->abs_pos += PyBytes_GET_SIZE(data);
1348 }
1349}
1350
1351/* Read n bytes from the buffer if it can, otherwise return None.
1352 This function is simple enough that it can run unlocked. */
1353static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001354_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001355{
1356 Py_ssize_t current_size;
1357
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001358 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1359 if (n <= current_size) {
1360 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001361 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1362 if (res != NULL)
1363 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001364 return res;
1365 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001366 Py_RETURN_NONE;
1367}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001368
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001369/* Generic read function: read from the stream until enough bytes are read,
1370 * or until an EOF occurs or until read() would block.
1371 */
1372static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001373_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001374{
1375 PyObject *res = NULL;
1376 Py_ssize_t current_size, remaining, written;
1377 char *out;
1378
1379 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1380 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001381 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001382
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001383 res = PyBytes_FromStringAndSize(NULL, n);
1384 if (res == NULL)
1385 goto error;
1386 out = PyBytes_AS_STRING(res);
1387 remaining = n;
1388 written = 0;
1389 if (current_size > 0) {
1390 memcpy(out, self->buffer + self->pos, current_size);
1391 remaining -= current_size;
1392 written += current_size;
1393 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001394 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001395 while (remaining > 0) {
1396 /* We want to read a whole block at the end into buffer.
1397 If we had readv() we could do this in one pass. */
1398 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1399 if (r == 0)
1400 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001401 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001402 if (r == -1)
1403 goto error;
1404 if (r == 0 || r == -2) {
1405 /* EOF occurred or read() would block. */
1406 if (r == 0 || written > 0) {
1407 if (_PyBytes_Resize(&res, written))
1408 goto error;
1409 return res;
1410 }
1411 Py_DECREF(res);
1412 Py_INCREF(Py_None);
1413 return Py_None;
1414 }
1415 remaining -= r;
1416 written += r;
1417 }
1418 assert(remaining <= self->buffer_size);
1419 self->pos = 0;
1420 self->raw_pos = 0;
1421 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001422 /* NOTE: when the read is satisfied, we avoid issuing any additional
1423 reads, which could block indefinitely (e.g. on a socket).
1424 See issue #9550. */
1425 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001426 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001427 if (r == -1)
1428 goto error;
1429 if (r == 0 || r == -2) {
1430 /* EOF occurred or read() would block. */
1431 if (r == 0 || written > 0) {
1432 if (_PyBytes_Resize(&res, written))
1433 goto error;
1434 return res;
1435 }
1436 Py_DECREF(res);
1437 Py_INCREF(Py_None);
1438 return Py_None;
1439 }
1440 if (remaining > r) {
1441 memcpy(out + written, self->buffer + self->pos, r);
1442 written += r;
1443 self->pos += r;
1444 remaining -= r;
1445 }
1446 else if (remaining > 0) {
1447 memcpy(out + written, self->buffer + self->pos, remaining);
1448 written += remaining;
1449 self->pos += remaining;
1450 remaining = 0;
1451 }
1452 if (remaining == 0)
1453 break;
1454 }
1455
1456 return res;
1457
1458error:
1459 Py_XDECREF(res);
1460 return NULL;
1461}
1462
1463static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001464_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465{
1466 Py_ssize_t have, r;
1467
1468 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1469 /* Constraints:
1470 1. we don't want to advance the file position.
1471 2. we don't want to lose block alignment, so we can't shift the buffer
1472 to make some place.
1473 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1474 */
1475 if (have > 0) {
1476 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1477 }
1478
1479 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001480 _bufferedreader_reset_buf(self);
1481 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001482 if (r == -1)
1483 return NULL;
1484 if (r == -2)
1485 r = 0;
1486 self->pos = 0;
1487 return PyBytes_FromStringAndSize(self->buffer, r);
1488}
1489
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001490static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001491 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001492 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1493 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1494 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1495 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1496 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1497 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1498 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1499 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001500 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001501 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001502
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001503 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1504 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1505 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
1506 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1507 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1508 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1509 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001510 {NULL, NULL}
1511};
1512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001513static PyMemberDef bufferedreader_members[] = {
1514 {"raw", T_OBJECT, offsetof(buffered, raw), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001515 {NULL}
1516};
1517
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001518static PyGetSetDef bufferedreader_getset[] = {
1519 {"closed", (getter)buffered_closed_get, NULL, NULL},
1520 {"name", (getter)buffered_name_get, NULL, NULL},
1521 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001522 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001523};
1524
1525
1526PyTypeObject PyBufferedReader_Type = {
1527 PyVarObject_HEAD_INIT(NULL, 0)
1528 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001529 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001530 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001531 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532 0, /*tp_print*/
1533 0, /*tp_getattr*/
1534 0, /*tp_setattr*/
1535 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001536 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 0, /*tp_as_number*/
1538 0, /*tp_as_sequence*/
1539 0, /*tp_as_mapping*/
1540 0, /*tp_hash */
1541 0, /*tp_call*/
1542 0, /*tp_str*/
1543 0, /*tp_getattro*/
1544 0, /*tp_setattro*/
1545 0, /*tp_as_buffer*/
1546 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1547 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001548 bufferedreader_doc, /* tp_doc */
1549 (traverseproc)buffered_traverse, /* tp_traverse */
1550 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001551 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001552 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001554 (iternextfunc)buffered_iternext, /* tp_iternext */
1555 bufferedreader_methods, /* tp_methods */
1556 bufferedreader_members, /* tp_members */
1557 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001558 0, /* tp_base */
1559 0, /* tp_dict */
1560 0, /* tp_descr_get */
1561 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001562 offsetof(buffered, dict), /* tp_dictoffset */
1563 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001564 0, /* tp_alloc */
1565 PyType_GenericNew, /* tp_new */
1566};
1567
1568
Benjamin Peterson59406a92009-03-26 17:10:29 +00001569
1570static int
1571complain_about_max_buffer_size(void)
1572{
1573 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1574 "max_buffer_size is deprecated", 1) < 0)
1575 return 0;
1576 return 1;
1577}
1578
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001579/*
1580 * class BufferedWriter
1581 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001582PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001583 "A buffer for a writeable sequential RawIO object.\n"
1584 "\n"
1585 "The constructor creates a BufferedWriter for the given writeable raw\n"
1586 "stream. If the buffer_size is not given, it defaults to\n"
1587 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1588 );
1589
1590static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001591_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001592{
1593 self->write_pos = 0;
1594 self->write_end = -1;
1595}
1596
1597static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001598bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001599{
1600 /* TODO: properly deprecate max_buffer_size */
1601 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1602 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001603 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001604 PyObject *raw;
1605
1606 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001607 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001608
1609 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1610 &raw, &buffer_size, &max_buffer_size)) {
1611 return -1;
1612 }
1613
Benjamin Peterson59406a92009-03-26 17:10:29 +00001614 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1615 return -1;
1616
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001617 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001618 return -1;
1619
1620 Py_CLEAR(self->raw);
1621 Py_INCREF(raw);
1622 self->raw = raw;
1623 self->readable = 0;
1624 self->writable = 1;
1625
1626 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001627 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001628 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630 self->pos = 0;
1631
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001632 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1633 Py_TYPE(raw) == &PyFileIO_Type);
1634
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001635 self->ok = 1;
1636 return 0;
1637}
1638
1639static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001640_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001641{
1642 Py_buffer buf;
1643 PyObject *memobj, *res;
1644 Py_ssize_t n;
1645 /* NOTE: the buffer needn't be released as its object is NULL. */
1646 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1647 return -1;
1648 memobj = PyMemoryView_FromBuffer(&buf);
1649 if (memobj == NULL)
1650 return -1;
1651 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1652 Py_DECREF(memobj);
1653 if (res == NULL)
1654 return -1;
1655 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1656 Py_DECREF(res);
1657 if (n < 0 || n > len) {
1658 PyErr_Format(PyExc_IOError,
1659 "raw write() returned invalid length %zd "
1660 "(should have been between 0 and %zd)", n, len);
1661 return -1;
1662 }
1663 if (n > 0 && self->abs_pos != -1)
1664 self->abs_pos += n;
1665 return n;
1666}
1667
1668/* `restore_pos` is 1 if we need to restore the raw stream position at
1669 the end, 0 otherwise. */
1670static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001671_bufferedwriter_flush_unlocked(buffered *self, int restore_pos)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001672{
1673 Py_ssize_t written = 0;
1674 Py_off_t n, rewind;
1675
1676 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1677 goto end;
1678 /* First, rewind */
1679 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1680 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001681 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001682 if (n < 0) {
1683 goto error;
1684 }
1685 self->raw_pos -= rewind;
1686 }
1687 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001688 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001689 self->buffer + self->write_pos,
1690 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1691 Py_off_t, Py_ssize_t));
1692 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001693 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001694 if (w == NULL)
1695 goto error;
1696 self->write_pos += *w;
1697 self->raw_pos = self->write_pos;
1698 written += *w;
1699 *w = written;
1700 /* Already re-raised */
1701 goto error;
1702 }
1703 self->write_pos += n;
1704 self->raw_pos = self->write_pos;
1705 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001706 /* Partial writes can return successfully when interrupted by a
1707 signal (see write(2)). We must run signal handlers before
1708 blocking another time, possibly indefinitely. */
1709 if (PyErr_CheckSignals() < 0)
1710 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001711 }
1712
1713 if (restore_pos) {
1714 Py_off_t forward = rewind - written;
1715 if (forward != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001716 n = _buffered_raw_seek(self, forward, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001717 if (n < 0) {
1718 goto error;
1719 }
1720 self->raw_pos += forward;
1721 }
1722 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001723 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001724
1725end:
1726 Py_RETURN_NONE;
1727
1728error:
1729 return NULL;
1730}
1731
1732static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001733bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001734{
1735 PyObject *res = NULL;
1736 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001737 Py_ssize_t written, avail, remaining;
1738 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001739
1740 CHECK_INITIALIZED(self)
1741 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1742 return NULL;
1743 }
1744
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001745 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746 PyErr_SetString(PyExc_ValueError, "write to closed file");
1747 PyBuffer_Release(&buf);
1748 return NULL;
1749 }
1750
1751 ENTER_BUFFERED(self)
1752
1753 /* Fast path: the data to write can be fully buffered. */
1754 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1755 self->pos = 0;
1756 self->raw_pos = 0;
1757 }
1758 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1759 if (buf.len <= avail) {
1760 memcpy(self->buffer + self->pos, buf.buf, buf.len);
1761 if (!VALID_WRITE_BUFFER(self)) {
1762 self->write_pos = self->pos;
1763 }
1764 ADJUST_POSITION(self, self->pos + buf.len);
1765 if (self->pos > self->write_end)
1766 self->write_end = self->pos;
1767 written = buf.len;
1768 goto end;
1769 }
1770
1771 /* First write the current buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001772 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001774 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775 if (w == NULL)
1776 goto error;
1777 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001778 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779 /* Make some place by shifting the buffer. */
1780 assert(VALID_WRITE_BUFFER(self));
1781 memmove(self->buffer, self->buffer + self->write_pos,
1782 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1783 Py_off_t, Py_ssize_t));
1784 self->write_end -= self->write_pos;
1785 self->raw_pos -= self->write_pos;
1786 self->pos -= self->write_pos;
1787 self->write_pos = 0;
1788 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1789 Py_off_t, Py_ssize_t);
1790 if (buf.len <= avail) {
1791 /* Everything can be buffered */
1792 PyErr_Clear();
1793 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1794 self->write_end += buf.len;
1795 written = buf.len;
1796 goto end;
1797 }
1798 /* Buffer as much as possible. */
1799 memcpy(self->buffer + self->write_end, buf.buf, avail);
1800 self->write_end += avail;
1801 /* Already re-raised */
1802 *w = avail;
1803 goto error;
1804 }
1805 Py_CLEAR(res);
1806
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001807 /* Adjust the raw stream position if it is away from the logical stream
1808 position. This happens if the read buffer has been filled but not
1809 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1810 the raw stream by itself).
1811 Fixes issue #6629.
1812 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001813 offset = RAW_OFFSET(self);
1814 if (offset != 0) {
1815 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001816 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001817 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001818 }
1819
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 /* Then write buf itself. At this point the buffer has been emptied. */
1821 remaining = buf.len;
1822 written = 0;
1823 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001824 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 self, (char *) buf.buf + written, buf.len - written);
1826 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001827 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828 if (w == NULL)
1829 goto error;
1830 written += *w;
1831 remaining -= *w;
1832 if (remaining > self->buffer_size) {
1833 /* Can't buffer everything, still buffer as much as possible */
1834 memcpy(self->buffer,
1835 (char *) buf.buf + written, self->buffer_size);
1836 self->raw_pos = 0;
1837 ADJUST_POSITION(self, self->buffer_size);
1838 self->write_end = self->buffer_size;
1839 *w = written + self->buffer_size;
1840 /* Already re-raised */
1841 goto error;
1842 }
1843 PyErr_Clear();
1844 break;
1845 }
1846 written += n;
1847 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001848 /* Partial writes can return successfully when interrupted by a
1849 signal (see write(2)). We must run signal handlers before
1850 blocking another time, possibly indefinitely. */
1851 if (PyErr_CheckSignals() < 0)
1852 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853 }
1854 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001855 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856 if (remaining > 0) {
1857 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1858 written += remaining;
1859 }
1860 self->write_pos = 0;
1861 /* TODO: sanity check (remaining >= 0) */
1862 self->write_end = remaining;
1863 ADJUST_POSITION(self, remaining);
1864 self->raw_pos = 0;
1865
1866end:
1867 res = PyLong_FromSsize_t(written);
1868
1869error:
1870 LEAVE_BUFFERED(self)
1871 PyBuffer_Release(&buf);
1872 return res;
1873}
1874
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001875static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001876 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001877 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1878 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1879 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1880 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1881 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1882 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1883 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001884 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001885 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001886
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001887 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
1888 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1889 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
1890 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1891 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001892 {NULL, NULL}
1893};
1894
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001895static PyMemberDef bufferedwriter_members[] = {
1896 {"raw", T_OBJECT, offsetof(buffered, raw), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001897 {NULL}
1898};
1899
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001900static PyGetSetDef bufferedwriter_getset[] = {
1901 {"closed", (getter)buffered_closed_get, NULL, NULL},
1902 {"name", (getter)buffered_name_get, NULL, NULL},
1903 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001904 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001905};
1906
1907
1908PyTypeObject PyBufferedWriter_Type = {
1909 PyVarObject_HEAD_INIT(NULL, 0)
1910 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001911 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001913 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001914 0, /*tp_print*/
1915 0, /*tp_getattr*/
1916 0, /*tp_setattr*/
1917 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001918 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001919 0, /*tp_as_number*/
1920 0, /*tp_as_sequence*/
1921 0, /*tp_as_mapping*/
1922 0, /*tp_hash */
1923 0, /*tp_call*/
1924 0, /*tp_str*/
1925 0, /*tp_getattro*/
1926 0, /*tp_setattro*/
1927 0, /*tp_as_buffer*/
1928 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1929 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001930 bufferedwriter_doc, /* tp_doc */
1931 (traverseproc)buffered_traverse, /* tp_traverse */
1932 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001934 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935 0, /* tp_iter */
1936 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001937 bufferedwriter_methods, /* tp_methods */
1938 bufferedwriter_members, /* tp_members */
1939 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001940 0, /* tp_base */
1941 0, /* tp_dict */
1942 0, /* tp_descr_get */
1943 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001944 offsetof(buffered, dict), /* tp_dictoffset */
1945 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001946 0, /* tp_alloc */
1947 PyType_GenericNew, /* tp_new */
1948};
1949
1950
1951
1952/*
1953 * BufferedRWPair
1954 */
1955
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001956PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957 "A buffered reader and writer object together.\n"
1958 "\n"
1959 "A buffered reader object and buffered writer object put together to\n"
1960 "form a sequential IO object that can read and write. This is typically\n"
1961 "used with a socket or two-way pipe.\n"
1962 "\n"
1963 "reader and writer are RawIOBase objects that are readable and\n"
1964 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00001965 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966 );
1967
1968/* XXX The usefulness of this (compared to having two separate IO objects) is
1969 * questionable.
1970 */
1971
1972typedef struct {
1973 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001974 buffered *reader;
1975 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976 PyObject *dict;
1977 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001978} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001979
1980static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001981bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982{
1983 PyObject *reader, *writer;
1984 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001985 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001986
1987 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
1988 &buffer_size, &max_buffer_size)) {
1989 return -1;
1990 }
1991
Benjamin Peterson59406a92009-03-26 17:10:29 +00001992 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1993 return -1;
1994
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001995 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001997 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998 return -1;
1999
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002000 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002001 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002002 if (self->reader == NULL)
2003 return -1;
2004
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002005 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002006 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 if (self->writer == NULL) {
2008 Py_CLEAR(self->reader);
2009 return -1;
2010 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002011
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 return 0;
2013}
2014
2015static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002016bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017{
2018 Py_VISIT(self->dict);
2019 return 0;
2020}
2021
2022static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002023bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024{
2025 Py_CLEAR(self->reader);
2026 Py_CLEAR(self->writer);
2027 Py_CLEAR(self->dict);
2028 return 0;
2029}
2030
2031static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002032bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033{
2034 _PyObject_GC_UNTRACK(self);
2035 Py_CLEAR(self->reader);
2036 Py_CLEAR(self->writer);
2037 Py_CLEAR(self->dict);
2038 Py_TYPE(self)->tp_free((PyObject *) self);
2039}
2040
2041static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002042_forward_call(buffered *self, const char *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002043{
2044 PyObject *func = PyObject_GetAttrString((PyObject *)self, name);
2045 PyObject *ret;
2046
2047 if (func == NULL) {
2048 PyErr_SetString(PyExc_AttributeError, name);
2049 return NULL;
2050 }
2051
2052 ret = PyObject_CallObject(func, args);
2053 Py_DECREF(func);
2054 return ret;
2055}
2056
2057static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002058bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059{
2060 return _forward_call(self->reader, "read", args);
2061}
2062
2063static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002064bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002065{
2066 return _forward_call(self->reader, "peek", args);
2067}
2068
2069static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002070bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071{
2072 return _forward_call(self->reader, "read1", args);
2073}
2074
2075static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002076bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002077{
2078 return _forward_call(self->reader, "readinto", args);
2079}
2080
2081static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002082bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083{
2084 return _forward_call(self->writer, "write", args);
2085}
2086
2087static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002088bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002089{
2090 return _forward_call(self->writer, "flush", args);
2091}
2092
2093static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002094bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095{
2096 return _forward_call(self->reader, "readable", args);
2097}
2098
2099static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101{
2102 return _forward_call(self->writer, "writable", args);
2103}
2104
2105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002106bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107{
2108 PyObject *ret = _forward_call(self->writer, "close", args);
2109 if (ret == NULL)
2110 return NULL;
2111 Py_DECREF(ret);
2112
2113 return _forward_call(self->reader, "close", args);
2114}
2115
2116static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002117bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118{
2119 PyObject *ret = _forward_call(self->writer, "isatty", args);
2120
2121 if (ret != Py_False) {
2122 /* either True or exception */
2123 return ret;
2124 }
2125 Py_DECREF(ret);
2126
2127 return _forward_call(self->reader, "isatty", args);
2128}
2129
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002130static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002132{
2133 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2134}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002135
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002136static PyMethodDef bufferedrwpair_methods[] = {
2137 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2138 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2139 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2140 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002142 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2143 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002144
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002145 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2146 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002148 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2149 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150
Antoine Pitrou243757e2010-11-05 21:15:39 +00002151 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2152
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 {NULL, NULL}
2154};
2155
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002156static PyGetSetDef bufferedrwpair_getset[] = {
2157 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002158 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002159};
2160
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161PyTypeObject PyBufferedRWPair_Type = {
2162 PyVarObject_HEAD_INIT(NULL, 0)
2163 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002164 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002166 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167 0, /*tp_print*/
2168 0, /*tp_getattr*/
2169 0, /*tp_setattr*/
2170 0, /*tp_compare */
2171 0, /*tp_repr*/
2172 0, /*tp_as_number*/
2173 0, /*tp_as_sequence*/
2174 0, /*tp_as_mapping*/
2175 0, /*tp_hash */
2176 0, /*tp_call*/
2177 0, /*tp_str*/
2178 0, /*tp_getattro*/
2179 0, /*tp_setattro*/
2180 0, /*tp_as_buffer*/
2181 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2182 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002183 bufferedrwpair_doc, /* tp_doc */
2184 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2185 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188 0, /* tp_iter */
2189 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193 0, /* tp_base */
2194 0, /* tp_dict */
2195 0, /* tp_descr_get */
2196 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002197 offsetof(rwpair, dict), /* tp_dictoffset */
2198 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199 0, /* tp_alloc */
2200 PyType_GenericNew, /* tp_new */
2201};
2202
2203
2204
2205/*
2206 * BufferedRandom
2207 */
2208
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002209PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210 "A buffered interface to random access streams.\n"
2211 "\n"
2212 "The constructor creates a reader and writer for a seekable stream,\n"
2213 "raw, given in the first argument. If the buffer_size is omitted it\n"
2214 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2215 );
2216
2217static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002218bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219{
2220 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2221 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002222 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223 PyObject *raw;
2224
2225 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002226 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227
2228 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2229 &raw, &buffer_size, &max_buffer_size)) {
2230 return -1;
2231 }
2232
Benjamin Peterson59406a92009-03-26 17:10:29 +00002233 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2234 return -1;
2235
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002236 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002238 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002240 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002241 return -1;
2242
2243 Py_CLEAR(self->raw);
2244 Py_INCREF(raw);
2245 self->raw = raw;
2246 self->buffer_size = buffer_size;
2247 self->readable = 1;
2248 self->writable = 1;
2249
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002252 _bufferedreader_reset_buf(self);
2253 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254 self->pos = 0;
2255
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002256 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2257 Py_TYPE(raw) == &PyFileIO_Type);
2258
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259 self->ok = 1;
2260 return 0;
2261}
2262
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002263static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002264 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2266 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2267 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2268 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2269 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2270 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2271 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002272 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002273 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002274
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002275 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002277 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2278 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2279 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2280 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2281 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2282 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2283 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2284 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2285 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286 {NULL, NULL}
2287};
2288
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289static PyMemberDef bufferedrandom_members[] = {
2290 {"raw", T_OBJECT, offsetof(buffered, raw), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291 {NULL}
2292};
2293
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002294static PyGetSetDef bufferedrandom_getset[] = {
2295 {"closed", (getter)buffered_closed_get, NULL, NULL},
2296 {"name", (getter)buffered_name_get, NULL, NULL},
2297 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002298 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299};
2300
2301
2302PyTypeObject PyBufferedRandom_Type = {
2303 PyVarObject_HEAD_INIT(NULL, 0)
2304 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002305 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002306 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002307 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308 0, /*tp_print*/
2309 0, /*tp_getattr*/
2310 0, /*tp_setattr*/
2311 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002312 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313 0, /*tp_as_number*/
2314 0, /*tp_as_sequence*/
2315 0, /*tp_as_mapping*/
2316 0, /*tp_hash */
2317 0, /*tp_call*/
2318 0, /*tp_str*/
2319 0, /*tp_getattro*/
2320 0, /*tp_setattro*/
2321 0, /*tp_as_buffer*/
2322 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2323 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002324 bufferedrandom_doc, /* tp_doc */
2325 (traverseproc)buffered_traverse, /* tp_traverse */
2326 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002327 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002328 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002330 (iternextfunc)buffered_iternext, /* tp_iternext */
2331 bufferedrandom_methods, /* tp_methods */
2332 bufferedrandom_members, /* tp_members */
2333 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334 0, /* tp_base */
2335 0, /*tp_dict*/
2336 0, /* tp_descr_get */
2337 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002338 offsetof(buffered, dict), /*tp_dictoffset*/
2339 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002340 0, /* tp_alloc */
2341 PyType_GenericNew, /* tp_new */
2342};