blob: 71c4052f29c03c32e3c130f0ece4c9b0bdbadb55 [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 Pitrou711af3a2009-04-11 15:39:24 +0000200
201 /* True if this is a vanilla Buffered object (rather than a user derived
202 class) *and* the raw stream is a vanilla FileIO object. */
203 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000204
205 /* Absolute position inside the raw stream (-1 if unknown). */
206 Py_off_t abs_pos;
207
208 /* A static buffer of size `buffer_size` */
209 char *buffer;
210 /* Current logical position in the buffer. */
211 Py_off_t pos;
212 /* Position of the raw stream in the buffer. */
213 Py_off_t raw_pos;
214
215 /* Just after the last buffered byte in the buffer, or -1 if the buffer
216 isn't ready for reading. */
217 Py_off_t read_end;
218
219 /* Just after the last byte actually written */
220 Py_off_t write_pos;
221 /* Just after the last byte waiting to be written, or -1 if the buffer
222 isn't ready for writing. */
223 Py_off_t write_end;
224
Georg Brandldfd73442009-04-05 11:47:34 +0000225#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000226 PyThread_type_lock lock;
Antoine Pitrou976157f2010-12-03 19:21:49 +0000227 volatile long owner;
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
Antoine Pitrou976157f2010-12-03 19:21:49 +0000263static int
264_enter_buffered_busy(buffered *self)
265{
266 if (self->owner == PyThread_get_thread_ident()) {
267 PyErr_Format(PyExc_RuntimeError,
268 "reentrant call inside %R", self);
269 return 0;
270 }
271 Py_BEGIN_ALLOW_THREADS
272 PyThread_acquire_lock(self->lock, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000273 Py_END_ALLOW_THREADS
Antoine Pitrou976157f2010-12-03 19:21:49 +0000274 return 1;
275}
276
277#define ENTER_BUFFERED(self) \
278 ( (PyThread_acquire_lock(self->lock, 0) ? \
279 1 : _enter_buffered_busy(self)) \
280 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000281
282#define LEAVE_BUFFERED(self) \
Antoine Pitrou976157f2010-12-03 19:21:49 +0000283 do { \
284 self->owner = 0; \
285 PyThread_release_lock(self->lock); \
286 } while(0);
287
Georg Brandldfd73442009-04-05 11:47:34 +0000288#else
Antoine Pitrou976157f2010-12-03 19:21:49 +0000289#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000290#define LEAVE_BUFFERED(self)
291#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000292
293#define CHECK_INITIALIZED(self) \
294 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000295 if (self->detached) { \
296 PyErr_SetString(PyExc_ValueError, \
297 "raw stream has been detached"); \
298 } else { \
299 PyErr_SetString(PyExc_ValueError, \
300 "I/O operation on uninitialized object"); \
301 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000302 return NULL; \
303 }
304
305#define CHECK_INITIALIZED_INT(self) \
306 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000307 if (self->detached) { \
308 PyErr_SetString(PyExc_ValueError, \
309 "raw stream has been detached"); \
310 } else { \
311 PyErr_SetString(PyExc_ValueError, \
312 "I/O operation on uninitialized object"); \
313 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000314 return -1; \
315 }
316
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000317#define IS_CLOSED(self) \
318 (self->fast_closed_checks \
319 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000320 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000321
322#define CHECK_CLOSED(self, error_msg) \
323 if (IS_CLOSED(self)) { \
324 PyErr_SetString(PyExc_ValueError, error_msg); \
325 return NULL; \
326 }
327
328
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000329#define VALID_READ_BUFFER(self) \
330 (self->readable && self->read_end != -1)
331
332#define VALID_WRITE_BUFFER(self) \
333 (self->writable && self->write_end != -1)
334
335#define ADJUST_POSITION(self, _new_pos) \
336 do { \
337 self->pos = _new_pos; \
338 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
339 self->read_end = self->pos; \
340 } while(0)
341
342#define READAHEAD(self) \
343 ((self->readable && VALID_READ_BUFFER(self)) \
344 ? (self->read_end - self->pos) : 0)
345
346#define RAW_OFFSET(self) \
347 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
348 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
349
350#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000351 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000352
353#define MINUS_LAST_BLOCK(self, size) \
354 (self->buffer_mask ? \
355 (size & ~self->buffer_mask) : \
356 (self->buffer_size * (size / self->buffer_size)))
357
358
359static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000360buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000361{
362 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
363 return;
364 _PyObject_GC_UNTRACK(self);
365 self->ok = 0;
366 if (self->weakreflist != NULL)
367 PyObject_ClearWeakRefs((PyObject *)self);
368 Py_CLEAR(self->raw);
369 if (self->buffer) {
370 PyMem_Free(self->buffer);
371 self->buffer = NULL;
372 }
Georg Brandldfd73442009-04-05 11:47:34 +0000373#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000374 if (self->lock) {
375 PyThread_free_lock(self->lock);
376 self->lock = NULL;
377 }
Georg Brandldfd73442009-04-05 11:47:34 +0000378#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000379 Py_CLEAR(self->dict);
380 Py_TYPE(self)->tp_free((PyObject *)self);
381}
382
383static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000384buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385{
386 Py_VISIT(self->raw);
387 Py_VISIT(self->dict);
388 return 0;
389}
390
391static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000392buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000393{
394 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
395 return -1;
396 self->ok = 0;
397 Py_CLEAR(self->raw);
398 Py_CLEAR(self->dict);
399 return 0;
400}
401
402/*
403 * _BufferedIOMixin methods
404 * This is not a class, just a collection of methods that will be reused
405 * by BufferedReader and BufferedWriter
406 */
407
408/* Flush and close */
409
410static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000411buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000412{
413 CHECK_INITIALIZED(self)
414 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
415}
416
417static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000418buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000419{
420 int closed;
421 PyObject *res;
422 CHECK_INITIALIZED_INT(self)
423 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
424 if (res == NULL)
425 return -1;
426 closed = PyObject_IsTrue(res);
427 Py_DECREF(res);
428 return closed;
429}
430
431static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000432buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000433{
434 CHECK_INITIALIZED(self)
435 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
436}
437
438static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000439buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000440{
441 PyObject *res = NULL;
442 int r;
443
444 CHECK_INITIALIZED(self)
Antoine Pitrou976157f2010-12-03 19:21:49 +0000445 if (!ENTER_BUFFERED(self))
446 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000447
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000448 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000449 if (r < 0)
450 goto end;
451 if (r > 0) {
452 res = Py_None;
453 Py_INCREF(res);
454 goto end;
455 }
456 /* flush() will most probably re-take the lock, so drop it first */
457 LEAVE_BUFFERED(self)
458 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrou976157f2010-12-03 19:21:49 +0000459 if (!ENTER_BUFFERED(self))
460 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461 if (res == NULL) {
Antoine Pitroufaf90072010-05-03 16:58:19 +0000462 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000463 }
464 Py_XDECREF(res);
465
466 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
467
468end:
469 LEAVE_BUFFERED(self)
470 return res;
471}
472
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000473/* detach */
474
475static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000476buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000477{
478 PyObject *raw, *res;
479 CHECK_INITIALIZED(self)
480 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
481 if (res == NULL)
482 return NULL;
483 Py_DECREF(res);
484 raw = self->raw;
485 self->raw = NULL;
486 self->detached = 1;
487 self->ok = 0;
488 return raw;
489}
490
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491/* Inquiries */
492
493static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000494buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000495{
496 CHECK_INITIALIZED(self)
497 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
498}
499
500static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000501buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000502{
503 CHECK_INITIALIZED(self)
504 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
505}
506
507static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000508buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509{
510 CHECK_INITIALIZED(self)
511 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
512}
513
514static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000515buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000516{
517 CHECK_INITIALIZED(self)
518 return PyObject_GetAttrString(self->raw, "name");
519}
520
521static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000522buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000523{
524 CHECK_INITIALIZED(self)
525 return PyObject_GetAttrString(self->raw, "mode");
526}
527
528/* Lower-level APIs */
529
530static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000531buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000532{
533 CHECK_INITIALIZED(self)
534 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
535}
536
537static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000538buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000539{
540 CHECK_INITIALIZED(self)
541 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
542}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000543
544
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000545/* Forward decls */
546static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000547_bufferedwriter_flush_unlocked(buffered *, int);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000548static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000549_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000550static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000551_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000552static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000553_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000554static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000555_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000556static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000557_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000560static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000561_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562
563
564/*
565 * Helpers
566 */
567
568/* Returns the address of the `written` member if a BlockingIOError was
569 raised, NULL otherwise. The error is always re-raised. */
570static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000571_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572{
573 PyObject *t, *v, *tb;
574 PyBlockingIOErrorObject *err;
575
576 PyErr_Fetch(&t, &v, &tb);
577 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
578 PyErr_Restore(t, v, tb);
579 return NULL;
580 }
581 err = (PyBlockingIOErrorObject *) v;
582 /* TODO: sanity check (err->written >= 0) */
583 PyErr_Restore(t, v, tb);
584 return &err->written;
585}
586
587static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000591 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
593 if (res == NULL)
594 return -1;
595 n = PyNumber_AsOff_t(res, PyExc_ValueError);
596 Py_DECREF(res);
597 if (n < 0) {
598 if (!PyErr_Occurred())
599 PyErr_Format(PyExc_IOError,
Mark Dickinson00de1bd2009-10-29 10:01:23 +0000600 "Raw stream returned invalid position %zd", n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601 return -1;
602 }
603 self->abs_pos = n;
604 return n;
605}
606
607static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000608_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609{
610 PyObject *res, *posobj, *whenceobj;
611 Py_off_t n;
612
613 posobj = PyLong_FromOff_t(target);
614 if (posobj == NULL)
615 return -1;
616 whenceobj = PyLong_FromLong(whence);
617 if (whenceobj == NULL) {
618 Py_DECREF(posobj);
619 return -1;
620 }
621 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
622 posobj, whenceobj, NULL);
623 Py_DECREF(posobj);
624 Py_DECREF(whenceobj);
625 if (res == NULL)
626 return -1;
627 n = PyNumber_AsOff_t(res, PyExc_ValueError);
628 Py_DECREF(res);
629 if (n < 0) {
630 if (!PyErr_Occurred())
631 PyErr_Format(PyExc_IOError,
Mark Dickinson00de1bd2009-10-29 10:01:23 +0000632 "Raw stream returned invalid position %zd", n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633 return -1;
634 }
635 self->abs_pos = n;
636 return n;
637}
638
639static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641{
642 Py_ssize_t n;
643 if (self->buffer_size <= 0) {
644 PyErr_SetString(PyExc_ValueError,
645 "buffer size must be strictly positive");
646 return -1;
647 }
648 if (self->buffer)
649 PyMem_Free(self->buffer);
650 self->buffer = PyMem_Malloc(self->buffer_size);
651 if (self->buffer == NULL) {
652 PyErr_NoMemory();
653 return -1;
654 }
Georg Brandldfd73442009-04-05 11:47:34 +0000655#ifdef WITH_THREAD
Antoine Pitrouf6df1ee2010-08-01 16:57:42 +0000656 if (self->lock)
657 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658 self->lock = PyThread_allocate_lock();
659 if (self->lock == NULL) {
660 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
661 return -1;
662 }
Antoine Pitrou976157f2010-12-03 19:21:49 +0000663 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000664#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665 /* Find out whether buffer_size is a power of 2 */
666 /* XXX is this optimization useful? */
667 for (n = self->buffer_size - 1; n & 1; n >>= 1)
668 ;
669 if (n == 0)
670 self->buffer_mask = self->buffer_size - 1;
671 else
672 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000673 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674 PyErr_Clear();
675 return 0;
676}
677
678/*
679 * Shared methods and wrappers
680 */
681
682static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000683buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684{
685 PyObject *res;
686
687 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000688 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689
Antoine Pitrou976157f2010-12-03 19:21:49 +0000690 if (!ENTER_BUFFERED(self))
691 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000692 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000693 if (res != NULL && self->readable) {
694 /* Rewind the raw stream so that its position corresponds to
695 the current logical position. */
696 Py_off_t n;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000697 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698 if (n == -1)
699 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000700 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000701 }
702 LEAVE_BUFFERED(self)
703
704 return res;
705}
706
707static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000708buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709{
710 Py_ssize_t n = 0;
711 PyObject *res = NULL;
712
713 CHECK_INITIALIZED(self)
714 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
715 return NULL;
716 }
717
Antoine Pitrou976157f2010-12-03 19:21:49 +0000718 if (!ENTER_BUFFERED(self))
719 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000720
721 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000722 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723 if (res == NULL)
724 goto end;
725 Py_CLEAR(res);
726 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000727 res = _bufferedreader_peek_unlocked(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000728
729end:
730 LEAVE_BUFFERED(self)
731 return res;
732}
733
734static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000735buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000736{
737 Py_ssize_t n = -1;
738 PyObject *res;
739
740 CHECK_INITIALIZED(self)
Benjamin Peterson6b59f772009-12-13 19:30:15 +0000741 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000742 return NULL;
743 }
744 if (n < -1) {
745 PyErr_SetString(PyExc_ValueError,
746 "read length must be positive or -1");
747 return NULL;
748 }
749
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000750 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000751
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000752 if (n == -1) {
753 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrou976157f2010-12-03 19:21:49 +0000754 if (!ENTER_BUFFERED(self))
755 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000756 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000757 LEAVE_BUFFERED(self)
758 }
759 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000760 res = _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000761 if (res == Py_None) {
762 Py_DECREF(res);
Antoine Pitrou976157f2010-12-03 19:21:49 +0000763 if (!ENTER_BUFFERED(self))
764 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000765 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000766 LEAVE_BUFFERED(self)
767 }
768 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000769
770 return res;
771}
772
773static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000774buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000775{
776 Py_ssize_t n, have, r;
777 PyObject *res = NULL;
778
779 CHECK_INITIALIZED(self)
780 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
781 return NULL;
782 }
783
784 if (n < 0) {
785 PyErr_SetString(PyExc_ValueError,
786 "read length must be positive");
787 return NULL;
788 }
789 if (n == 0)
790 return PyBytes_FromStringAndSize(NULL, 0);
791
Antoine Pitrou976157f2010-12-03 19:21:49 +0000792 if (!ENTER_BUFFERED(self))
793 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000794
795 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000796 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000797 if (res == NULL)
798 goto end;
799 Py_CLEAR(res);
800 }
801
802 /* Return up to n bytes. If at least one byte is buffered, we
803 only return buffered bytes. Otherwise, we do one raw read. */
804
805 /* XXX: this mimicks the io.py implementation but is probably wrong.
806 If we need to read from the raw stream, then we could actually read
807 all `n` bytes asked by the caller (and possibly more, so as to fill
808 our buffer for the next reads). */
809
810 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
811 if (have > 0) {
812 if (n > have)
813 n = have;
814 res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
815 if (res == NULL)
816 goto end;
817 self->pos += n;
818 goto end;
819 }
820
821 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000822 _bufferedreader_reset_buf(self);
823 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000824 if (r == -1)
825 goto end;
826 if (r == -2)
827 r = 0;
828 if (n > r)
829 n = r;
830 res = PyBytes_FromStringAndSize(self->buffer, n);
831 if (res == NULL)
832 goto end;
833 self->pos = n;
834
835end:
836 LEAVE_BUFFERED(self)
837 return res;
838}
839
840static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000841buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000842{
843 PyObject *res = NULL;
844
845 CHECK_INITIALIZED(self)
846
847 /* TODO: use raw.readinto() instead! */
848 if (self->writable) {
Antoine Pitrou976157f2010-12-03 19:21:49 +0000849 if (!ENTER_BUFFERED(self))
850 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000851 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852 LEAVE_BUFFERED(self)
853 if (res == NULL)
854 goto end;
855 Py_DECREF(res);
856 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000857 res = bufferediobase_readinto((PyObject *)self, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000858
859end:
860 return res;
861}
862
863static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000864_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000865{
866 PyObject *res = NULL;
867 PyObject *chunks = NULL;
868 Py_ssize_t n, written = 0;
869 const char *start, *s, *end;
870
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000871 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000872
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000873 /* First, try to find a line in the buffer. This can run unlocked because
874 the calls to the C API are simple enough that they can't trigger
875 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
877 if (limit >= 0 && n > limit)
878 n = limit;
879 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000880 s = memchr(start, '\n', n);
881 if (s != NULL) {
882 res = PyBytes_FromStringAndSize(start, s - start + 1);
883 if (res != NULL)
884 self->pos += s - start + 1;
885 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886 }
887 if (n == limit) {
888 res = PyBytes_FromStringAndSize(start, n);
889 if (res != NULL)
890 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000891 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000892 }
893
Antoine Pitrou976157f2010-12-03 19:21:49 +0000894 if (!ENTER_BUFFERED(self))
895 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000896
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000897 /* Now we try to get some more from the raw stream */
898 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000899 res = _bufferedwriter_flush_unlocked(self, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000900 if (res == NULL)
901 goto end;
902 Py_CLEAR(res);
903 }
904 chunks = PyList_New(0);
905 if (chunks == NULL)
906 goto end;
907 if (n > 0) {
908 res = PyBytes_FromStringAndSize(start, n);
909 if (res == NULL)
910 goto end;
911 if (PyList_Append(chunks, res) < 0) {
912 Py_CLEAR(res);
913 goto end;
914 }
915 Py_CLEAR(res);
916 written += n;
917 if (limit >= 0)
918 limit -= n;
919 }
920
921 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000922 _bufferedreader_reset_buf(self);
923 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 if (n == -1)
925 goto end;
926 if (n <= 0)
927 break;
928 if (limit >= 0 && n > limit)
929 n = limit;
930 start = self->buffer;
931 end = start + n;
932 s = start;
933 while (s < end) {
934 if (*s++ == '\n') {
935 res = PyBytes_FromStringAndSize(start, s - start);
936 if (res == NULL)
937 goto end;
938 self->pos = s - start;
939 goto found;
940 }
941 }
942 res = PyBytes_FromStringAndSize(start, n);
943 if (res == NULL)
944 goto end;
945 if (n == limit) {
946 self->pos = n;
947 break;
948 }
949 if (PyList_Append(chunks, res) < 0) {
950 Py_CLEAR(res);
951 goto end;
952 }
953 Py_CLEAR(res);
954 written += n;
955 if (limit >= 0)
956 limit -= n;
957 }
958found:
959 if (res != NULL && PyList_Append(chunks, res) < 0) {
960 Py_CLEAR(res);
961 goto end;
962 }
963 Py_CLEAR(res);
964 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
965
966end:
967 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000968end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969 Py_XDECREF(chunks);
970 return res;
971}
972
973static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000974buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000975{
976 Py_ssize_t limit = -1;
977
978 CHECK_INITIALIZED(self)
Benjamin Peterson6b59f772009-12-13 19:30:15 +0000979 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000981 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982}
983
984
985static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000986buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987{
988 Py_off_t pos;
989
990 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000991 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 if (pos == -1)
993 return NULL;
994 pos -= RAW_OFFSET(self);
995 /* TODO: sanity check (pos >= 0) */
996 return PyLong_FromOff_t(pos);
997}
998
999static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001000buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001001{
1002 Py_off_t target, n;
1003 int whence = 0;
1004 PyObject *targetobj, *res = NULL;
1005
1006 CHECK_INITIALIZED(self)
1007 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1008 return NULL;
1009 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001010 if (whence < 0 || whence > 2) {
1011 PyErr_Format(PyExc_ValueError,
1012 "whence must be between 0 and 2, not %d", whence);
1013 return NULL;
1014 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001015
1016 CHECK_CLOSED(self, "seek of closed file")
1017
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1019 if (target == -1 && PyErr_Occurred())
1020 return NULL;
1021
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001022 if (whence != 2 && self->readable) {
1023 Py_off_t current, avail;
1024 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001025 so as to return quickly if possible. Also, we needn't take the
1026 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001027 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001028 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1029 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001030 current = RAW_TELL(self);
1031 avail = READAHEAD(self);
1032 if (avail > 0) {
1033 Py_off_t offset;
1034 if (whence == 0)
1035 offset = target - (current - RAW_OFFSET(self));
1036 else
1037 offset = target;
1038 if (offset >= -self->pos && offset <= avail) {
1039 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001040 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 }
1042 }
1043 }
1044
Antoine Pitrou976157f2010-12-03 19:21:49 +00001045 if (!ENTER_BUFFERED(self))
1046 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001047
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001048 /* Fallback: invoke raw seek() method and clear buffer */
1049 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001050 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001051 if (res == NULL)
1052 goto end;
1053 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001054 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001055 }
1056
1057 /* TODO: align on block boundary and read buffer if needed? */
1058 if (whence == 1)
1059 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001060 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001061 if (n == -1)
1062 goto end;
1063 self->raw_pos = -1;
1064 res = PyLong_FromOff_t(n);
1065 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001066 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067
1068end:
1069 LEAVE_BUFFERED(self)
1070 return res;
1071}
1072
1073static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001074buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075{
1076 PyObject *pos = Py_None;
1077 PyObject *res = NULL;
1078
1079 CHECK_INITIALIZED(self)
1080 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1081 return NULL;
1082 }
1083
Antoine Pitrou976157f2010-12-03 19:21:49 +00001084 if (!ENTER_BUFFERED(self))
1085 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001086
1087 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001088 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001089 if (res == NULL)
1090 goto end;
1091 Py_CLEAR(res);
1092 }
1093 if (self->readable) {
1094 if (pos == Py_None) {
1095 /* Rewind the raw stream so that its position corresponds to
1096 the current logical position. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001097 if (_buffered_raw_seek(self, -RAW_OFFSET(self), 1) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001098 goto end;
1099 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001100 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 }
1102 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1103 if (res == NULL)
1104 goto end;
1105 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001106 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001107 PyErr_Clear();
1108
1109end:
1110 LEAVE_BUFFERED(self)
1111 return res;
1112}
1113
1114static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001115buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001116{
1117 PyObject *line;
1118 PyTypeObject *tp;
1119
1120 CHECK_INITIALIZED(self);
1121
1122 tp = Py_TYPE(self);
1123 if (tp == &PyBufferedReader_Type ||
1124 tp == &PyBufferedRandom_Type) {
1125 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001126 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127 }
1128 else {
1129 line = PyObject_CallMethodObjArgs((PyObject *)self,
1130 _PyIO_str_readline, NULL);
1131 if (line && !PyBytes_Check(line)) {
1132 PyErr_Format(PyExc_IOError,
1133 "readline() should have returned a bytes object, "
1134 "not '%.200s'", Py_TYPE(line)->tp_name);
1135 Py_DECREF(line);
1136 return NULL;
1137 }
1138 }
1139
1140 if (line == NULL)
1141 return NULL;
1142
1143 if (PyBytes_GET_SIZE(line) == 0) {
1144 /* Reached EOF or would have blocked */
1145 Py_DECREF(line);
1146 return NULL;
1147 }
1148
1149 return line;
1150}
1151
Antoine Pitrou716c4442009-05-23 19:04:03 +00001152static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001153buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001154{
1155 PyObject *nameobj, *res;
1156
1157 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
1158 if (nameobj == NULL) {
1159 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1160 PyErr_Clear();
1161 else
1162 return NULL;
1163 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1164 }
1165 else {
1166 res = PyUnicode_FromFormat("<%s name=%R>",
1167 Py_TYPE(self)->tp_name, nameobj);
1168 Py_DECREF(nameobj);
1169 }
1170 return res;
1171}
1172
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001173/*
1174 * class BufferedReader
1175 */
1176
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001177PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001178 "Create a new buffered reader using the given readable raw IO object.");
1179
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001180static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001181{
1182 self->read_end = -1;
1183}
1184
1185static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001186bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001187{
1188 char *kwlist[] = {"raw", "buffer_size", NULL};
1189 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1190 PyObject *raw;
1191
1192 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001193 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001194
1195 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1196 &raw, &buffer_size)) {
1197 return -1;
1198 }
1199
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001200 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201 return -1;
1202
1203 Py_CLEAR(self->raw);
1204 Py_INCREF(raw);
1205 self->raw = raw;
1206 self->buffer_size = buffer_size;
1207 self->readable = 1;
1208 self->writable = 0;
1209
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001210 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001211 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001212 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001213
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001214 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1215 Py_TYPE(raw) == &PyFileIO_Type);
1216
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 self->ok = 1;
1218 return 0;
1219}
1220
1221static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001222_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001223{
1224 Py_buffer buf;
1225 PyObject *memobj, *res;
1226 Py_ssize_t n;
1227 /* NOTE: the buffer needn't be released as its object is NULL. */
1228 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1229 return -1;
1230 memobj = PyMemoryView_FromBuffer(&buf);
1231 if (memobj == NULL)
1232 return -1;
1233 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1234 Py_DECREF(memobj);
1235 if (res == NULL)
1236 return -1;
1237 if (res == Py_None) {
1238 /* Non-blocking stream would have blocked. Special return code! */
1239 Py_DECREF(res);
1240 return -2;
1241 }
1242 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1243 Py_DECREF(res);
1244 if (n < 0 || n > len) {
1245 PyErr_Format(PyExc_IOError,
1246 "raw readinto() returned invalid length %zd "
1247 "(should have been between 0 and %zd)", n, len);
1248 return -1;
1249 }
1250 if (n > 0 && self->abs_pos != -1)
1251 self->abs_pos += n;
1252 return n;
1253}
1254
1255static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001256_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001257{
1258 Py_ssize_t start, len, n;
1259 if (VALID_READ_BUFFER(self))
1260 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1261 else
1262 start = 0;
1263 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001264 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265 if (n <= 0)
1266 return n;
1267 self->read_end = start + n;
1268 self->raw_pos = start + n;
1269 return n;
1270}
1271
1272static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001273_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001275 Py_ssize_t current_size;
1276 PyObject *res, *data = NULL;
1277 PyObject *chunks = PyList_New(0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001279 if (chunks == NULL)
1280 return NULL;
1281
1282 /* First copy what we have in the current buffer. */
1283 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1284 if (current_size) {
1285 data = PyBytes_FromStringAndSize(
1286 self->buffer + self->pos, current_size);
1287 if (data == NULL) {
1288 Py_DECREF(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290 }
1291 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001292 _bufferedreader_reset_buf(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001293 /* We're going past the buffer's bounds, flush it */
1294 if (self->writable) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001295 res = _bufferedwriter_flush_unlocked(self, 1);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001296 if (res == NULL) {
1297 Py_DECREF(chunks);
1298 return NULL;
1299 }
1300 Py_CLEAR(res);
1301 }
1302 while (1) {
1303 if (data) {
1304 if (PyList_Append(chunks, data) < 0) {
1305 Py_DECREF(data);
1306 Py_DECREF(chunks);
1307 return NULL;
1308 }
1309 Py_DECREF(data);
1310 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001312 /* Read until EOF or until read() would block. */
1313 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1314 if (data == NULL) {
1315 Py_DECREF(chunks);
1316 return NULL;
1317 }
1318 if (data != Py_None && !PyBytes_Check(data)) {
1319 Py_DECREF(data);
1320 Py_DECREF(chunks);
1321 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1322 return NULL;
1323 }
1324 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1325 if (current_size == 0) {
1326 Py_DECREF(chunks);
1327 return data;
1328 }
1329 else {
1330 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1331 Py_DECREF(data);
1332 Py_DECREF(chunks);
1333 return res;
1334 }
1335 }
1336 current_size += PyBytes_GET_SIZE(data);
1337 if (self->abs_pos != -1)
1338 self->abs_pos += PyBytes_GET_SIZE(data);
1339 }
1340}
1341
1342/* Read n bytes from the buffer if it can, otherwise return None.
1343 This function is simple enough that it can run unlocked. */
1344static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001345_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001346{
1347 Py_ssize_t current_size;
1348
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1350 if (n <= current_size) {
1351 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001352 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1353 if (res != NULL)
1354 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355 return res;
1356 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001357 Py_RETURN_NONE;
1358}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001360/* Generic read function: read from the stream until enough bytes are read,
1361 * or until an EOF occurs or until read() would block.
1362 */
1363static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001364_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001365{
1366 PyObject *res = NULL;
1367 Py_ssize_t current_size, remaining, written;
1368 char *out;
1369
1370 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1371 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001372 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001373
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001374 res = PyBytes_FromStringAndSize(NULL, n);
1375 if (res == NULL)
1376 goto error;
1377 out = PyBytes_AS_STRING(res);
1378 remaining = n;
1379 written = 0;
1380 if (current_size > 0) {
1381 memcpy(out, self->buffer + self->pos, current_size);
1382 remaining -= current_size;
1383 written += current_size;
1384 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001385 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001386 while (remaining > 0) {
1387 /* We want to read a whole block at the end into buffer.
1388 If we had readv() we could do this in one pass. */
1389 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1390 if (r == 0)
1391 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001392 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393 if (r == -1)
1394 goto error;
1395 if (r == 0 || r == -2) {
1396 /* EOF occurred or read() would block. */
1397 if (r == 0 || written > 0) {
1398 if (_PyBytes_Resize(&res, written))
1399 goto error;
1400 return res;
1401 }
1402 Py_DECREF(res);
1403 Py_INCREF(Py_None);
1404 return Py_None;
1405 }
1406 remaining -= r;
1407 written += r;
1408 }
1409 assert(remaining <= self->buffer_size);
1410 self->pos = 0;
1411 self->raw_pos = 0;
1412 self->read_end = 0;
Antoine Pitrou00091ca2010-08-11 13:38:10 +00001413 /* NOTE: when the read is satisfied, we avoid issuing any additional
1414 reads, which could block indefinitely (e.g. on a socket).
1415 See issue #9550. */
1416 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001417 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001418 if (r == -1)
1419 goto error;
1420 if (r == 0 || r == -2) {
1421 /* EOF occurred or read() would block. */
1422 if (r == 0 || written > 0) {
1423 if (_PyBytes_Resize(&res, written))
1424 goto error;
1425 return res;
1426 }
1427 Py_DECREF(res);
1428 Py_INCREF(Py_None);
1429 return Py_None;
1430 }
1431 if (remaining > r) {
1432 memcpy(out + written, self->buffer + self->pos, r);
1433 written += r;
1434 self->pos += r;
1435 remaining -= r;
1436 }
1437 else if (remaining > 0) {
1438 memcpy(out + written, self->buffer + self->pos, remaining);
1439 written += remaining;
1440 self->pos += remaining;
1441 remaining = 0;
1442 }
1443 if (remaining == 0)
1444 break;
1445 }
1446
1447 return res;
1448
1449error:
1450 Py_XDECREF(res);
1451 return NULL;
1452}
1453
1454static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001455_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001456{
1457 Py_ssize_t have, r;
1458
1459 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1460 /* Constraints:
1461 1. we don't want to advance the file position.
1462 2. we don't want to lose block alignment, so we can't shift the buffer
1463 to make some place.
1464 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1465 */
1466 if (have > 0) {
1467 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1468 }
1469
1470 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001471 _bufferedreader_reset_buf(self);
1472 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001473 if (r == -1)
1474 return NULL;
1475 if (r == -2)
1476 r = 0;
1477 self->pos = 0;
1478 return PyBytes_FromStringAndSize(self->buffer, r);
1479}
1480
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001481static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001482 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001483 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1484 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1485 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1486 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1487 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1488 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1489 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1490 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001491
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001492 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1493 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1494 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
1495 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1496 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1497 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1498 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001499 {NULL, NULL}
1500};
1501
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001502static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou6cfc5122010-12-21 21:26:09 +00001503 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001504 {NULL}
1505};
1506
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001507static PyGetSetDef bufferedreader_getset[] = {
1508 {"closed", (getter)buffered_closed_get, NULL, NULL},
1509 {"name", (getter)buffered_name_get, NULL, NULL},
1510 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001511 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001512};
1513
1514
1515PyTypeObject PyBufferedReader_Type = {
1516 PyVarObject_HEAD_INIT(NULL, 0)
1517 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001518 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001519 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001520 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001521 0, /*tp_print*/
1522 0, /*tp_getattr*/
1523 0, /*tp_setattr*/
1524 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001525 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001526 0, /*tp_as_number*/
1527 0, /*tp_as_sequence*/
1528 0, /*tp_as_mapping*/
1529 0, /*tp_hash */
1530 0, /*tp_call*/
1531 0, /*tp_str*/
1532 0, /*tp_getattro*/
1533 0, /*tp_setattro*/
1534 0, /*tp_as_buffer*/
1535 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1536 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001537 bufferedreader_doc, /* tp_doc */
1538 (traverseproc)buffered_traverse, /* tp_traverse */
1539 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001540 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001541 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001542 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001543 (iternextfunc)buffered_iternext, /* tp_iternext */
1544 bufferedreader_methods, /* tp_methods */
1545 bufferedreader_members, /* tp_members */
1546 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001547 0, /* tp_base */
1548 0, /* tp_dict */
1549 0, /* tp_descr_get */
1550 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001551 offsetof(buffered, dict), /* tp_dictoffset */
1552 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553 0, /* tp_alloc */
1554 PyType_GenericNew, /* tp_new */
1555};
1556
1557
Benjamin Peterson59406a92009-03-26 17:10:29 +00001558
1559static int
1560complain_about_max_buffer_size(void)
1561{
1562 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1563 "max_buffer_size is deprecated", 1) < 0)
1564 return 0;
1565 return 1;
1566}
1567
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001568/*
1569 * class BufferedWriter
1570 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001571PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001572 "A buffer for a writeable sequential RawIO object.\n"
1573 "\n"
1574 "The constructor creates a BufferedWriter for the given writeable raw\n"
1575 "stream. If the buffer_size is not given, it defaults to\n"
1576 "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
1577 );
1578
1579static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001580_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001581{
1582 self->write_pos = 0;
1583 self->write_end = -1;
1584}
1585
1586static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001587bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001588{
1589 /* TODO: properly deprecate max_buffer_size */
1590 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
1591 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001592 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001593 PyObject *raw;
1594
1595 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001596 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001597
1598 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
1599 &raw, &buffer_size, &max_buffer_size)) {
1600 return -1;
1601 }
1602
Benjamin Peterson59406a92009-03-26 17:10:29 +00001603 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1604 return -1;
1605
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001606 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001607 return -1;
1608
1609 Py_CLEAR(self->raw);
1610 Py_INCREF(raw);
1611 self->raw = raw;
1612 self->readable = 0;
1613 self->writable = 1;
1614
1615 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001616 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001617 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001618 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001619 self->pos = 0;
1620
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001621 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1622 Py_TYPE(raw) == &PyFileIO_Type);
1623
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001624 self->ok = 1;
1625 return 0;
1626}
1627
1628static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630{
1631 Py_buffer buf;
1632 PyObject *memobj, *res;
1633 Py_ssize_t n;
1634 /* NOTE: the buffer needn't be released as its object is NULL. */
1635 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1636 return -1;
1637 memobj = PyMemoryView_FromBuffer(&buf);
1638 if (memobj == NULL)
1639 return -1;
1640 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1641 Py_DECREF(memobj);
1642 if (res == NULL)
1643 return -1;
1644 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1645 Py_DECREF(res);
1646 if (n < 0 || n > len) {
1647 PyErr_Format(PyExc_IOError,
1648 "raw write() returned invalid length %zd "
1649 "(should have been between 0 and %zd)", n, len);
1650 return -1;
1651 }
1652 if (n > 0 && self->abs_pos != -1)
1653 self->abs_pos += n;
1654 return n;
1655}
1656
1657/* `restore_pos` is 1 if we need to restore the raw stream position at
1658 the end, 0 otherwise. */
1659static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001660_bufferedwriter_flush_unlocked(buffered *self, int restore_pos)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001661{
1662 Py_ssize_t written = 0;
1663 Py_off_t n, rewind;
1664
1665 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1666 goto end;
1667 /* First, rewind */
1668 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1669 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001670 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001671 if (n < 0) {
1672 goto error;
1673 }
1674 self->raw_pos -= rewind;
1675 }
1676 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001677 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001678 self->buffer + self->write_pos,
1679 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1680 Py_off_t, Py_ssize_t));
1681 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001682 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683 if (w == NULL)
1684 goto error;
1685 self->write_pos += *w;
1686 self->raw_pos = self->write_pos;
1687 written += *w;
1688 *w = written;
1689 /* Already re-raised */
1690 goto error;
1691 }
1692 self->write_pos += n;
1693 self->raw_pos = self->write_pos;
1694 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitrou16b11de2010-08-21 19:17:57 +00001695 /* Partial writes can return successfully when interrupted by a
1696 signal (see write(2)). We must run signal handlers before
1697 blocking another time, possibly indefinitely. */
1698 if (PyErr_CheckSignals() < 0)
1699 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700 }
1701
1702 if (restore_pos) {
1703 Py_off_t forward = rewind - written;
1704 if (forward != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 n = _buffered_raw_seek(self, forward, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 if (n < 0) {
1707 goto error;
1708 }
1709 self->raw_pos += forward;
1710 }
1711 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001712 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001713
1714end:
1715 Py_RETURN_NONE;
1716
1717error:
1718 return NULL;
1719}
1720
1721static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001722bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001723{
1724 PyObject *res = NULL;
1725 Py_buffer buf;
1726 Py_ssize_t written, avail, remaining, n;
1727
1728 CHECK_INITIALIZED(self)
1729 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1730 return NULL;
1731 }
1732
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001733 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001734 PyErr_SetString(PyExc_ValueError, "write to closed file");
1735 PyBuffer_Release(&buf);
1736 return NULL;
1737 }
1738
Antoine Pitrou976157f2010-12-03 19:21:49 +00001739 if (!ENTER_BUFFERED(self)) {
1740 PyBuffer_Release(&buf);
1741 return NULL;
1742 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743
1744 /* Fast path: the data to write can be fully buffered. */
1745 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1746 self->pos = 0;
1747 self->raw_pos = 0;
1748 }
1749 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1750 if (buf.len <= avail) {
1751 memcpy(self->buffer + self->pos, buf.buf, buf.len);
1752 if (!VALID_WRITE_BUFFER(self)) {
1753 self->write_pos = self->pos;
1754 }
1755 ADJUST_POSITION(self, self->pos + buf.len);
1756 if (self->pos > self->write_end)
1757 self->write_end = self->pos;
1758 written = buf.len;
1759 goto end;
1760 }
1761
1762 /* First write the current buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001763 res = _bufferedwriter_flush_unlocked(self, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001765 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001766 if (w == NULL)
1767 goto error;
1768 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001769 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770 /* Make some place by shifting the buffer. */
1771 assert(VALID_WRITE_BUFFER(self));
1772 memmove(self->buffer, self->buffer + self->write_pos,
1773 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1774 Py_off_t, Py_ssize_t));
1775 self->write_end -= self->write_pos;
1776 self->raw_pos -= self->write_pos;
1777 self->pos -= self->write_pos;
1778 self->write_pos = 0;
1779 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1780 Py_off_t, Py_ssize_t);
1781 if (buf.len <= avail) {
1782 /* Everything can be buffered */
1783 PyErr_Clear();
1784 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
1785 self->write_end += buf.len;
1786 written = buf.len;
1787 goto end;
1788 }
1789 /* Buffer as much as possible. */
1790 memcpy(self->buffer + self->write_end, buf.buf, avail);
1791 self->write_end += avail;
1792 /* Already re-raised */
1793 *w = avail;
1794 goto error;
1795 }
1796 Py_CLEAR(res);
1797
Antoine Pitrou0473e562009-08-06 20:52:43 +00001798 /* Adjust the raw stream position if it is away from the logical stream
1799 position. This happens if the read buffer has been filled but not
1800 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1801 the raw stream by itself).
1802 Fixes issue #6629.
1803 */
1804 n = RAW_OFFSET(self);
1805 if (n != 0) {
1806 if (_buffered_raw_seek(self, -n, 1) < 0)
1807 goto error;
1808 self->raw_pos -= n;
1809 }
1810
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 /* Then write buf itself. At this point the buffer has been emptied. */
1812 remaining = buf.len;
1813 written = 0;
1814 while (remaining > self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001815 n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816 self, (char *) buf.buf + written, buf.len - written);
1817 if (n == -1) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001818 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001819 if (w == NULL)
1820 goto error;
1821 written += *w;
1822 remaining -= *w;
1823 if (remaining > self->buffer_size) {
1824 /* Can't buffer everything, still buffer as much as possible */
1825 memcpy(self->buffer,
1826 (char *) buf.buf + written, self->buffer_size);
1827 self->raw_pos = 0;
1828 ADJUST_POSITION(self, self->buffer_size);
1829 self->write_end = self->buffer_size;
1830 *w = written + self->buffer_size;
1831 /* Already re-raised */
1832 goto error;
1833 }
1834 PyErr_Clear();
1835 break;
1836 }
1837 written += n;
1838 remaining -= n;
Antoine Pitrou16b11de2010-08-21 19:17:57 +00001839 /* Partial writes can return successfully when interrupted by a
1840 signal (see write(2)). We must run signal handlers before
1841 blocking another time, possibly indefinitely. */
1842 if (PyErr_CheckSignals() < 0)
1843 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844 }
1845 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001846 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847 if (remaining > 0) {
1848 memcpy(self->buffer, (char *) buf.buf + written, remaining);
1849 written += remaining;
1850 }
1851 self->write_pos = 0;
1852 /* TODO: sanity check (remaining >= 0) */
1853 self->write_end = remaining;
1854 ADJUST_POSITION(self, remaining);
1855 self->raw_pos = 0;
1856
1857end:
1858 res = PyLong_FromSsize_t(written);
1859
1860error:
1861 LEAVE_BUFFERED(self)
1862 PyBuffer_Release(&buf);
1863 return res;
1864}
1865
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001866static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001867 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001868 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1869 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1870 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1871 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1872 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1873 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1874 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001876 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
1877 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
1878 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
1879 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1880 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001881 {NULL, NULL}
1882};
1883
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001884static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou6cfc5122010-12-21 21:26:09 +00001885 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001886 {NULL}
1887};
1888
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001889static PyGetSetDef bufferedwriter_getset[] = {
1890 {"closed", (getter)buffered_closed_get, NULL, NULL},
1891 {"name", (getter)buffered_name_get, NULL, NULL},
1892 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001893 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001894};
1895
1896
1897PyTypeObject PyBufferedWriter_Type = {
1898 PyVarObject_HEAD_INIT(NULL, 0)
1899 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001900 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001901 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001902 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001903 0, /*tp_print*/
1904 0, /*tp_getattr*/
1905 0, /*tp_setattr*/
1906 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001907 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908 0, /*tp_as_number*/
1909 0, /*tp_as_sequence*/
1910 0, /*tp_as_mapping*/
1911 0, /*tp_hash */
1912 0, /*tp_call*/
1913 0, /*tp_str*/
1914 0, /*tp_getattro*/
1915 0, /*tp_setattro*/
1916 0, /*tp_as_buffer*/
1917 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1918 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001919 bufferedwriter_doc, /* tp_doc */
1920 (traverseproc)buffered_traverse, /* tp_traverse */
1921 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001922 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001923 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924 0, /* tp_iter */
1925 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001926 bufferedwriter_methods, /* tp_methods */
1927 bufferedwriter_members, /* tp_members */
1928 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929 0, /* tp_base */
1930 0, /* tp_dict */
1931 0, /* tp_descr_get */
1932 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001933 offsetof(buffered, dict), /* tp_dictoffset */
1934 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935 0, /* tp_alloc */
1936 PyType_GenericNew, /* tp_new */
1937};
1938
1939
1940
1941/*
1942 * BufferedRWPair
1943 */
1944
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001945PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001946 "A buffered reader and writer object together.\n"
1947 "\n"
1948 "A buffered reader object and buffered writer object put together to\n"
1949 "form a sequential IO object that can read and write. This is typically\n"
1950 "used with a socket or two-way pipe.\n"
1951 "\n"
1952 "reader and writer are RawIOBase objects that are readable and\n"
1953 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00001954 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955 );
1956
1957/* XXX The usefulness of this (compared to having two separate IO objects) is
1958 * questionable.
1959 */
1960
1961typedef struct {
1962 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001963 buffered *reader;
1964 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965 PyObject *dict;
1966 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001967} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001968
1969static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001970bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001971{
1972 PyObject *reader, *writer;
1973 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00001974 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001975
1976 if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer,
1977 &buffer_size, &max_buffer_size)) {
1978 return -1;
1979 }
1980
Benjamin Peterson59406a92009-03-26 17:10:29 +00001981 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
1982 return -1;
1983
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001984 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001985 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001986 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001987 return -1;
1988
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001989 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00001990 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 if (self->reader == NULL)
1992 return -1;
1993
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001994 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00001995 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 if (self->writer == NULL) {
1997 Py_CLEAR(self->reader);
1998 return -1;
1999 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002000
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 return 0;
2002}
2003
2004static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002005bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002006{
2007 Py_VISIT(self->dict);
2008 return 0;
2009}
2010
2011static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002012bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002013{
2014 Py_CLEAR(self->reader);
2015 Py_CLEAR(self->writer);
2016 Py_CLEAR(self->dict);
2017 return 0;
2018}
2019
2020static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002021bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022{
2023 _PyObject_GC_UNTRACK(self);
2024 Py_CLEAR(self->reader);
2025 Py_CLEAR(self->writer);
2026 Py_CLEAR(self->dict);
2027 Py_TYPE(self)->tp_free((PyObject *) self);
2028}
2029
2030static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002031_forward_call(buffered *self, const char *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002032{
2033 PyObject *func = PyObject_GetAttrString((PyObject *)self, name);
2034 PyObject *ret;
2035
2036 if (func == NULL) {
2037 PyErr_SetString(PyExc_AttributeError, name);
2038 return NULL;
2039 }
2040
2041 ret = PyObject_CallObject(func, args);
2042 Py_DECREF(func);
2043 return ret;
2044}
2045
2046static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002047bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048{
2049 return _forward_call(self->reader, "read", args);
2050}
2051
2052static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002053bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054{
2055 return _forward_call(self->reader, "peek", args);
2056}
2057
2058static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002059bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060{
2061 return _forward_call(self->reader, "read1", args);
2062}
2063
2064static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002065bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002066{
2067 return _forward_call(self->reader, "readinto", args);
2068}
2069
2070static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002071bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002072{
2073 return _forward_call(self->writer, "write", args);
2074}
2075
2076static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002077bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078{
2079 return _forward_call(self->writer, "flush", args);
2080}
2081
2082static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002083bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002084{
2085 return _forward_call(self->reader, "readable", args);
2086}
2087
2088static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002089bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002090{
2091 return _forward_call(self->writer, "writable", args);
2092}
2093
2094static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002095bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096{
2097 PyObject *ret = _forward_call(self->writer, "close", args);
2098 if (ret == NULL)
2099 return NULL;
2100 Py_DECREF(ret);
2101
2102 return _forward_call(self->reader, "close", args);
2103}
2104
2105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002106bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107{
2108 PyObject *ret = _forward_call(self->writer, "isatty", args);
2109
2110 if (ret != Py_False) {
2111 /* either True or exception */
2112 return ret;
2113 }
2114 Py_DECREF(ret);
2115
2116 return _forward_call(self->reader, "isatty", args);
2117}
2118
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002119static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002121{
2122 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2123}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002125static PyMethodDef bufferedrwpair_methods[] = {
2126 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2127 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2128 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2129 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2132 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002134 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2135 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002136
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002137 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2138 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139
2140 {NULL, NULL}
2141};
2142
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002143static PyGetSetDef bufferedrwpair_getset[] = {
2144 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002145 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002146};
2147
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148PyTypeObject PyBufferedRWPair_Type = {
2149 PyVarObject_HEAD_INIT(NULL, 0)
2150 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002151 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002153 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154 0, /*tp_print*/
2155 0, /*tp_getattr*/
2156 0, /*tp_setattr*/
2157 0, /*tp_compare */
2158 0, /*tp_repr*/
2159 0, /*tp_as_number*/
2160 0, /*tp_as_sequence*/
2161 0, /*tp_as_mapping*/
2162 0, /*tp_hash */
2163 0, /*tp_call*/
2164 0, /*tp_str*/
2165 0, /*tp_getattro*/
2166 0, /*tp_setattro*/
2167 0, /*tp_as_buffer*/
2168 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2169 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 bufferedrwpair_doc, /* tp_doc */
2171 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2172 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002174 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175 0, /* tp_iter */
2176 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002177 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002179 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180 0, /* tp_base */
2181 0, /* tp_dict */
2182 0, /* tp_descr_get */
2183 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184 offsetof(rwpair, dict), /* tp_dictoffset */
2185 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186 0, /* tp_alloc */
2187 PyType_GenericNew, /* tp_new */
2188};
2189
2190
2191
2192/*
2193 * BufferedRandom
2194 */
2195
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002196PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 "A buffered interface to random access streams.\n"
2198 "\n"
2199 "The constructor creates a reader and writer for a seekable stream,\n"
2200 "raw, given in the first argument. If the buffer_size is omitted it\n"
2201 "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n"
2202 );
2203
2204static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002205bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002206{
2207 char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL};
2208 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson59406a92009-03-26 17:10:29 +00002209 Py_ssize_t max_buffer_size = -234;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210 PyObject *raw;
2211
2212 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002213 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214
2215 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist,
2216 &raw, &buffer_size, &max_buffer_size)) {
2217 return -1;
2218 }
2219
Benjamin Peterson59406a92009-03-26 17:10:29 +00002220 if (max_buffer_size != -234 && !complain_about_max_buffer_size())
2221 return -1;
2222
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002225 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002228 return -1;
2229
2230 Py_CLEAR(self->raw);
2231 Py_INCREF(raw);
2232 self->raw = raw;
2233 self->buffer_size = buffer_size;
2234 self->readable = 1;
2235 self->writable = 1;
2236
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002237 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002239 _bufferedreader_reset_buf(self);
2240 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002241 self->pos = 0;
2242
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002243 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2244 Py_TYPE(raw) == &PyFileIO_Type);
2245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246 self->ok = 1;
2247 return 0;
2248}
2249
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002252 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2253 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2254 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2255 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2256 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2257 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2258 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002260 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2263 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2264 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2265 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2266 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2267 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2268 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2269 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2270 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271 {NULL, NULL}
2272};
2273
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002274static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou6cfc5122010-12-21 21:26:09 +00002275 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276 {NULL}
2277};
2278
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002279static PyGetSetDef bufferedrandom_getset[] = {
2280 {"closed", (getter)buffered_closed_get, NULL, NULL},
2281 {"name", (getter)buffered_name_get, NULL, NULL},
2282 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002283 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002284};
2285
2286
2287PyTypeObject PyBufferedRandom_Type = {
2288 PyVarObject_HEAD_INIT(NULL, 0)
2289 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002290 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002292 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293 0, /*tp_print*/
2294 0, /*tp_getattr*/
2295 0, /*tp_setattr*/
2296 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002297 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298 0, /*tp_as_number*/
2299 0, /*tp_as_sequence*/
2300 0, /*tp_as_mapping*/
2301 0, /*tp_hash */
2302 0, /*tp_call*/
2303 0, /*tp_str*/
2304 0, /*tp_getattro*/
2305 0, /*tp_setattro*/
2306 0, /*tp_as_buffer*/
2307 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2308 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002309 bufferedrandom_doc, /* tp_doc */
2310 (traverseproc)buffered_traverse, /* tp_traverse */
2311 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002313 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002314 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002315 (iternextfunc)buffered_iternext, /* tp_iternext */
2316 bufferedrandom_methods, /* tp_methods */
2317 bufferedrandom_members, /* tp_members */
2318 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319 0, /* tp_base */
2320 0, /*tp_dict*/
2321 0, /* tp_descr_get */
2322 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002323 offsetof(buffered, dict), /*tp_dictoffset*/
2324 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002325 0, /* tp_alloc */
2326 PyType_GenericNew, /* tp_new */
2327};
2328