blob: 6fe5d586a9c01f7f6a0c2b1845f2c8038cc0e436 [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020016_Py_IDENTIFIER(close);
17_Py_IDENTIFIER(_dealloc_warn);
18_Py_IDENTIFIER(flush);
19_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020020_Py_IDENTIFIER(mode);
21_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020022_Py_IDENTIFIER(peek);
23_Py_IDENTIFIER(read);
24_Py_IDENTIFIER(read1);
25_Py_IDENTIFIER(readable);
26_Py_IDENTIFIER(readinto);
27_Py_IDENTIFIER(writable);
28_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020029
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000030/*
31 * BufferedIOBase class, inherits from IOBase.
32 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000033PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034 "Base class for buffered IO objects.\n"
35 "\n"
36 "The main difference with RawIOBase is that the read() method\n"
37 "supports omitting the size argument, and does not have a default\n"
38 "implementation that defers to readinto().\n"
39 "\n"
40 "In addition, read(), readinto() and write() may raise\n"
41 "BlockingIOError if the underlying raw stream is in non-blocking\n"
42 "mode and not ready; unlike their raw counterparts, they will never\n"
43 "return None.\n"
44 "\n"
45 "A typical implementation should not inherit from a RawIOBase\n"
46 "implementation, but wrap one.\n"
47 );
48
49static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000050bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000051{
52 Py_buffer buf;
53 Py_ssize_t len;
54 PyObject *data;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020055 _Py_IDENTIFIER(read);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000056
57 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
58 return NULL;
59 }
60
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020061 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000062 if (data == NULL)
63 goto error;
64
65 if (!PyBytes_Check(data)) {
66 Py_DECREF(data);
67 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
68 goto error;
69 }
70
71 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030072 if (len > buf.len) {
73 PyErr_Format(PyExc_ValueError,
74 "read() returned too much data: "
75 "%zd bytes requested, %zd returned",
76 buf.len, len);
77 Py_DECREF(data);
78 goto error;
79 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
81
82 PyBuffer_Release(&buf);
83 Py_DECREF(data);
84
85 return PyLong_FromSsize_t(len);
86
87 error:
88 PyBuffer_Release(&buf);
89 return NULL;
90}
91
92static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000093bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094{
95 PyErr_SetString(IO_STATE->unsupported_operation, message);
96 return NULL;
97}
98
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000100 "Disconnect this buffer from its underlying raw stream and return it.\n"
101 "\n"
102 "After the raw stream has been detached, the buffer is in an unusable\n"
103 "state.\n");
104
105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000106bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000107{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000108 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000109}
110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000111PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000112 "Read and return up to n bytes.\n"
113 "\n"
114 "If the argument is omitted, None, or negative, reads and\n"
115 "returns all data until EOF.\n"
116 "\n"
117 "If the argument is positive, and the underlying raw stream is\n"
118 "not 'interactive', multiple raw reads may be issued to satisfy\n"
119 "the byte count (unless EOF is reached first). But for\n"
120 "interactive raw streams (as well as sockets and pipes), at most\n"
121 "one raw read will be issued, and a short result does not imply\n"
122 "that EOF is imminent.\n"
123 "\n"
124 "Returns an empty bytes object on EOF.\n"
125 "\n"
126 "Returns None if the underlying raw stream was open in non-blocking\n"
127 "mode and no data is available at the moment.\n");
128
129static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000130bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000131{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000132 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133}
134
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000135PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000136 "Read and return up to n bytes, with at most one read() call\n"
137 "to the underlying raw stream. A short result does not imply\n"
138 "that EOF is imminent.\n"
139 "\n"
140 "Returns an empty bytes object on EOF.\n");
141
142static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000144{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000145 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000146}
147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149 "Write the given buffer to the IO stream.\n"
150 "\n"
151 "Returns the number of bytes written, which is never less than\n"
152 "len(b).\n"
153 "\n"
154 "Raises BlockingIOError if the buffer is full and the\n"
155 "underlying raw stream cannot accept more data at the moment.\n");
156
157static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000159{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000160 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000161}
162
163
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000164static PyMethodDef bufferediobase_methods[] = {
165 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
166 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
167 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
168 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
169 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000170 {NULL, NULL}
171};
172
173PyTypeObject PyBufferedIOBase_Type = {
174 PyVarObject_HEAD_INIT(NULL, 0)
175 "_io._BufferedIOBase", /*tp_name*/
176 0, /*tp_basicsize*/
177 0, /*tp_itemsize*/
178 0, /*tp_dealloc*/
179 0, /*tp_print*/
180 0, /*tp_getattr*/
181 0, /*tp_setattr*/
182 0, /*tp_compare */
183 0, /*tp_repr*/
184 0, /*tp_as_number*/
185 0, /*tp_as_sequence*/
186 0, /*tp_as_mapping*/
187 0, /*tp_hash */
188 0, /*tp_call*/
189 0, /*tp_str*/
190 0, /*tp_getattro*/
191 0, /*tp_setattro*/
192 0, /*tp_as_buffer*/
Antoine Pitrou796564c2013-07-30 19:59:21 +0200193 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
194 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000195 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196 0, /* tp_traverse */
197 0, /* tp_clear */
198 0, /* tp_richcompare */
199 0, /* tp_weaklistoffset */
200 0, /* tp_iter */
201 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000202 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000203 0, /* tp_members */
204 0, /* tp_getset */
205 &PyIOBase_Type, /* tp_base */
206 0, /* tp_dict */
207 0, /* tp_descr_get */
208 0, /* tp_descr_set */
209 0, /* tp_dictoffset */
210 0, /* tp_init */
211 0, /* tp_alloc */
212 0, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200213 0, /* tp_free */
214 0, /* tp_is_gc */
215 0, /* tp_bases */
216 0, /* tp_mro */
217 0, /* tp_cache */
218 0, /* tp_subclasses */
219 0, /* tp_weaklist */
220 0, /* tp_del */
221 0, /* tp_version_tag */
222 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000223};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000224
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000225
226typedef struct {
227 PyObject_HEAD
228
229 PyObject *raw;
230 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000231 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000232 int readable;
233 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200234 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200235
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000236 /* True if this is a vanilla Buffered object (rather than a user derived
237 class) *and* the raw stream is a vanilla FileIO object. */
238 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000239
240 /* Absolute position inside the raw stream (-1 if unknown). */
241 Py_off_t abs_pos;
242
243 /* A static buffer of size `buffer_size` */
244 char *buffer;
245 /* Current logical position in the buffer. */
246 Py_off_t pos;
247 /* Position of the raw stream in the buffer. */
248 Py_off_t raw_pos;
249
250 /* Just after the last buffered byte in the buffer, or -1 if the buffer
251 isn't ready for reading. */
252 Py_off_t read_end;
253
254 /* Just after the last byte actually written */
255 Py_off_t write_pos;
256 /* Just after the last byte waiting to be written, or -1 if the buffer
257 isn't ready for writing. */
258 Py_off_t write_end;
259
Georg Brandldfd73442009-04-05 11:47:34 +0000260#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000261 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000262 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000263#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264
265 Py_ssize_t buffer_size;
266 Py_ssize_t buffer_mask;
267
268 PyObject *dict;
269 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000270} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000271
272/*
273 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200274
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000275 * BufferedReader, BufferedWriter and BufferedRandom try to share most
276 methods (this is helped by the members `readable` and `writable`, which
277 are initialized in the respective constructors)
278 * They also share a single buffer for reading and writing. This enables
279 interleaved reads and writes without flushing. It also makes the logic
280 a bit trickier to get right.
281 * The absolute position of the raw stream is cached, if possible, in the
282 `abs_pos` member. It must be updated every time an operation is done
283 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000284 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000285 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000286 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
287 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000288
289 NOTE: we should try to maintain block alignment of reads and writes to the
290 raw stream (according to the buffer size), but for now it is only done
291 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200292
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000293*/
294
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000295/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000296
Georg Brandldfd73442009-04-05 11:47:34 +0000297#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000298
299static int
300_enter_buffered_busy(buffered *self)
301{
302 if (self->owner == PyThread_get_thread_ident()) {
303 PyErr_Format(PyExc_RuntimeError,
304 "reentrant call inside %R", self);
305 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000306 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000307 Py_BEGIN_ALLOW_THREADS
308 PyThread_acquire_lock(self->lock, 1);
309 Py_END_ALLOW_THREADS
310 return 1;
311}
312
313#define ENTER_BUFFERED(self) \
314 ( (PyThread_acquire_lock(self->lock, 0) ? \
315 1 : _enter_buffered_busy(self)) \
316 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000317
318#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000319 do { \
320 self->owner = 0; \
321 PyThread_release_lock(self->lock); \
322 } while(0);
323
Georg Brandldfd73442009-04-05 11:47:34 +0000324#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000325#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000326#define LEAVE_BUFFERED(self)
327#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000328
329#define CHECK_INITIALIZED(self) \
330 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000331 if (self->detached) { \
332 PyErr_SetString(PyExc_ValueError, \
333 "raw stream has been detached"); \
334 } else { \
335 PyErr_SetString(PyExc_ValueError, \
336 "I/O operation on uninitialized object"); \
337 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000338 return NULL; \
339 }
340
341#define CHECK_INITIALIZED_INT(self) \
342 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000343 if (self->detached) { \
344 PyErr_SetString(PyExc_ValueError, \
345 "raw stream has been detached"); \
346 } else { \
347 PyErr_SetString(PyExc_ValueError, \
348 "I/O operation on uninitialized object"); \
349 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000350 return -1; \
351 }
352
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000353#define IS_CLOSED(self) \
354 (self->fast_closed_checks \
355 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000356 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000357
358#define CHECK_CLOSED(self, error_msg) \
359 if (IS_CLOSED(self)) { \
360 PyErr_SetString(PyExc_ValueError, error_msg); \
361 return NULL; \
362 }
363
364
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000365#define VALID_READ_BUFFER(self) \
366 (self->readable && self->read_end != -1)
367
368#define VALID_WRITE_BUFFER(self) \
369 (self->writable && self->write_end != -1)
370
371#define ADJUST_POSITION(self, _new_pos) \
372 do { \
373 self->pos = _new_pos; \
374 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
375 self->read_end = self->pos; \
376 } while(0)
377
378#define READAHEAD(self) \
379 ((self->readable && VALID_READ_BUFFER(self)) \
380 ? (self->read_end - self->pos) : 0)
381
382#define RAW_OFFSET(self) \
383 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
384 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
385
386#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000387 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388
389#define MINUS_LAST_BLOCK(self, size) \
390 (self->buffer_mask ? \
391 (size & ~self->buffer_mask) : \
392 (self->buffer_size * (size / self->buffer_size)))
393
394
395static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000396buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000397{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200398 self->finalizing = 1;
399 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000400 return;
401 _PyObject_GC_UNTRACK(self);
402 self->ok = 0;
403 if (self->weakreflist != NULL)
404 PyObject_ClearWeakRefs((PyObject *)self);
405 Py_CLEAR(self->raw);
406 if (self->buffer) {
407 PyMem_Free(self->buffer);
408 self->buffer = NULL;
409 }
Georg Brandldfd73442009-04-05 11:47:34 +0000410#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000411 if (self->lock) {
412 PyThread_free_lock(self->lock);
413 self->lock = NULL;
414 }
Georg Brandldfd73442009-04-05 11:47:34 +0000415#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416 Py_CLEAR(self->dict);
417 Py_TYPE(self)->tp_free((PyObject *)self);
418}
419
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200420static PyObject *
421buffered_sizeof(buffered *self, void *unused)
422{
423 Py_ssize_t res;
424
425 res = sizeof(buffered);
426 if (self->buffer)
427 res += self->buffer_size;
428 return PyLong_FromSsize_t(res);
429}
430
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000431static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000432buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000433{
434 Py_VISIT(self->raw);
435 Py_VISIT(self->dict);
436 return 0;
437}
438
439static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000440buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000441{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000442 self->ok = 0;
443 Py_CLEAR(self->raw);
444 Py_CLEAR(self->dict);
445 return 0;
446}
447
Antoine Pitroue033e062010-10-29 10:38:18 +0000448/* Because this can call arbitrary code, it shouldn't be called when
449 the refcount is 0 (that is, not directly from tp_dealloc unless
450 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000451static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000452buffered_dealloc_warn(buffered *self, PyObject *source)
453{
454 if (self->ok && self->raw) {
455 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200456 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000457 if (r)
458 Py_DECREF(r);
459 else
460 PyErr_Clear();
461 }
462 Py_RETURN_NONE;
463}
464
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000465/*
466 * _BufferedIOMixin methods
467 * This is not a class, just a collection of methods that will be reused
468 * by BufferedReader and BufferedWriter
469 */
470
471/* Flush and close */
472
473static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000474buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000475{
476 CHECK_INITIALIZED(self)
477 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
478}
479
480static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000481buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482{
483 int closed;
484 PyObject *res;
485 CHECK_INITIALIZED_INT(self)
486 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
487 if (res == NULL)
488 return -1;
489 closed = PyObject_IsTrue(res);
490 Py_DECREF(res);
491 return closed;
492}
493
494static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000495buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496{
497 CHECK_INITIALIZED(self)
498 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
499}
500
501static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503{
Benjamin Peterson68623612012-12-20 11:53:11 -0600504 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505 int r;
506
507 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000508 if (!ENTER_BUFFERED(self))
509 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000511 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512 if (r < 0)
513 goto end;
514 if (r > 0) {
515 res = Py_None;
516 Py_INCREF(res);
517 goto end;
518 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000519
Antoine Pitrou796564c2013-07-30 19:59:21 +0200520 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000521 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
522 if (r)
523 Py_DECREF(r);
524 else
525 PyErr_Clear();
526 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000527 /* flush() will most probably re-take the lock, so drop it first */
528 LEAVE_BUFFERED(self)
529 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000530 if (!ENTER_BUFFERED(self))
531 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600532 if (res == NULL)
533 PyErr_Fetch(&exc, &val, &tb);
534 else
535 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000536
537 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
538
Jesus Ceadc469452012-10-04 12:37:56 +0200539 if (self->buffer) {
540 PyMem_Free(self->buffer);
541 self->buffer = NULL;
542 }
543
Benjamin Peterson68623612012-12-20 11:53:11 -0600544 if (exc != NULL) {
545 if (res != NULL) {
546 Py_CLEAR(res);
547 PyErr_Restore(exc, val, tb);
548 }
549 else {
550 PyObject *val2;
551 Py_DECREF(exc);
552 Py_XDECREF(tb);
553 PyErr_Fetch(&exc, &val2, &tb);
554 PyErr_NormalizeException(&exc, &val2, &tb);
555 PyException_SetContext(val2, val);
556 PyErr_Restore(exc, val2, tb);
557 }
558 }
559
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000560end:
561 LEAVE_BUFFERED(self)
562 return res;
563}
564
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000565/* detach */
566
567static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000568buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000569{
570 PyObject *raw, *res;
571 CHECK_INITIALIZED(self)
572 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
573 if (res == NULL)
574 return NULL;
575 Py_DECREF(res);
576 raw = self->raw;
577 self->raw = NULL;
578 self->detached = 1;
579 self->ok = 0;
580 return raw;
581}
582
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583/* Inquiries */
584
585static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000586buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000587{
588 CHECK_INITIALIZED(self)
589 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
590}
591
592static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000593buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594{
595 CHECK_INITIALIZED(self)
596 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
597}
598
599static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000600buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601{
602 CHECK_INITIALIZED(self)
603 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
604}
605
606static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000607buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608{
609 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200610 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611}
612
613static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615{
616 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200617 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618}
619
620/* Lower-level APIs */
621
622static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000623buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000624{
625 CHECK_INITIALIZED(self)
626 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
627}
628
629static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000630buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000631{
632 CHECK_INITIALIZED(self)
633 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
634}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000635
Antoine Pitrou243757e2010-11-05 21:15:39 +0000636/* Serialization */
637
638static PyObject *
639buffered_getstate(buffered *self, PyObject *args)
640{
641 PyErr_Format(PyExc_TypeError,
642 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
643 return NULL;
644}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000645
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646/* Forward decls */
647static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100648_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000650_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000654_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200656_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000658_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000659static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000660_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000661static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000662_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200663static Py_ssize_t
664_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665
666/*
667 * Helpers
668 */
669
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100670/* Sets the current error to BlockingIOError */
671static void
672_set_BlockingIOError(char *msg, Py_ssize_t written)
673{
674 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200675#ifdef Py_DEBUG
676 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
677 if an exception is set when it is called */
678 PyErr_Clear();
679#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100680 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
681 errno, msg, written);
682 if (err)
683 PyErr_SetObject(PyExc_BlockingIOError, err);
684 Py_XDECREF(err);
685}
686
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000687/* Returns the address of the `written` member if a BlockingIOError was
688 raised, NULL otherwise. The error is always re-raised. */
689static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000690_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691{
692 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200693 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000694
695 PyErr_Fetch(&t, &v, &tb);
696 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
697 PyErr_Restore(t, v, tb);
698 return NULL;
699 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200700 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000701 /* TODO: sanity check (err->written >= 0) */
702 PyErr_Restore(t, v, tb);
703 return &err->written;
704}
705
706static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000707_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000710 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
712 if (res == NULL)
713 return -1;
714 n = PyNumber_AsOff_t(res, PyExc_ValueError);
715 Py_DECREF(res);
716 if (n < 0) {
717 if (!PyErr_Occurred())
718 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000719 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200720 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000721 return -1;
722 }
723 self->abs_pos = n;
724 return n;
725}
726
727static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000728_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000729{
730 PyObject *res, *posobj, *whenceobj;
731 Py_off_t n;
732
733 posobj = PyLong_FromOff_t(target);
734 if (posobj == NULL)
735 return -1;
736 whenceobj = PyLong_FromLong(whence);
737 if (whenceobj == NULL) {
738 Py_DECREF(posobj);
739 return -1;
740 }
741 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
742 posobj, whenceobj, NULL);
743 Py_DECREF(posobj);
744 Py_DECREF(whenceobj);
745 if (res == NULL)
746 return -1;
747 n = PyNumber_AsOff_t(res, PyExc_ValueError);
748 Py_DECREF(res);
749 if (n < 0) {
750 if (!PyErr_Occurred())
751 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000752 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200753 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 return -1;
755 }
756 self->abs_pos = n;
757 return n;
758}
759
760static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000761_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000762{
763 Py_ssize_t n;
764 if (self->buffer_size <= 0) {
765 PyErr_SetString(PyExc_ValueError,
766 "buffer size must be strictly positive");
767 return -1;
768 }
769 if (self->buffer)
770 PyMem_Free(self->buffer);
771 self->buffer = PyMem_Malloc(self->buffer_size);
772 if (self->buffer == NULL) {
773 PyErr_NoMemory();
774 return -1;
775 }
Georg Brandldfd73442009-04-05 11:47:34 +0000776#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000777 if (self->lock)
778 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000779 self->lock = PyThread_allocate_lock();
780 if (self->lock == NULL) {
781 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
782 return -1;
783 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000784 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000785#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000786 /* Find out whether buffer_size is a power of 2 */
787 /* XXX is this optimization useful? */
788 for (n = self->buffer_size - 1; n & 1; n >>= 1)
789 ;
790 if (n == 0)
791 self->buffer_mask = self->buffer_size - 1;
792 else
793 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000794 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000795 PyErr_Clear();
796 return 0;
797}
798
Antoine Pitrou707ce822011-02-25 21:24:11 +0000799/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
800 clears the error indicator), 0 otherwise.
801 Should only be called when PyErr_Occurred() is true.
802*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700803int
804_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000805{
806 static PyObject *eintr_int = NULL;
807 PyObject *typ, *val, *tb;
808 PyEnvironmentErrorObject *env_err;
809
810 if (eintr_int == NULL) {
811 eintr_int = PyLong_FromLong(EINTR);
812 assert(eintr_int != NULL);
813 }
814 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
815 return 0;
816 PyErr_Fetch(&typ, &val, &tb);
817 PyErr_NormalizeException(&typ, &val, &tb);
818 env_err = (PyEnvironmentErrorObject *) val;
819 assert(env_err != NULL);
820 if (env_err->myerrno != NULL &&
821 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
822 Py_DECREF(typ);
823 Py_DECREF(val);
824 Py_XDECREF(tb);
825 return 1;
826 }
827 /* This silences any error set by PyObject_RichCompareBool() */
828 PyErr_Restore(typ, val, tb);
829 return 0;
830}
831
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000832/*
833 * Shared methods and wrappers
834 */
835
836static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200837buffered_flush_and_rewind_unlocked(buffered *self)
838{
839 PyObject *res;
840
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100841 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200842 if (res == NULL)
843 return NULL;
844 Py_DECREF(res);
845
846 if (self->readable) {
847 /* Rewind the raw stream so that its position corresponds to
848 the current logical position. */
849 Py_off_t n;
850 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
851 _bufferedreader_reset_buf(self);
852 if (n == -1)
853 return NULL;
854 }
855 Py_RETURN_NONE;
856}
857
858static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000859buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860{
861 PyObject *res;
862
863 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000864 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000865
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000866 if (!ENTER_BUFFERED(self))
867 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200868 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000869 LEAVE_BUFFERED(self)
870
871 return res;
872}
873
874static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000875buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876{
877 Py_ssize_t n = 0;
878 PyObject *res = NULL;
879
880 CHECK_INITIALIZED(self)
881 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
882 return NULL;
883 }
884
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000885 if (!ENTER_BUFFERED(self))
886 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887
888 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200889 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890 if (res == NULL)
891 goto end;
892 Py_CLEAR(res);
893 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200894 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000895
896end:
897 LEAVE_BUFFERED(self)
898 return res;
899}
900
901static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000902buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903{
904 Py_ssize_t n = -1;
905 PyObject *res;
906
907 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000908 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909 return NULL;
910 }
911 if (n < -1) {
912 PyErr_SetString(PyExc_ValueError,
913 "read length must be positive or -1");
914 return NULL;
915 }
916
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000917 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000918
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000919 if (n == -1) {
920 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000921 if (!ENTER_BUFFERED(self))
922 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000923 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000924 }
925 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000926 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200927 if (res != Py_None)
928 return res;
929 Py_DECREF(res);
930 if (!ENTER_BUFFERED(self))
931 return NULL;
932 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000933 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000934
Antoine Pitroue05565e2011-08-20 14:39:23 +0200935 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936 return res;
937}
938
939static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000940buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000941{
942 Py_ssize_t n, have, r;
943 PyObject *res = NULL;
944
945 CHECK_INITIALIZED(self)
946 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
947 return NULL;
948 }
949
950 if (n < 0) {
951 PyErr_SetString(PyExc_ValueError,
952 "read length must be positive");
953 return NULL;
954 }
955 if (n == 0)
956 return PyBytes_FromStringAndSize(NULL, 0);
957
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 /* Return up to n bytes. If at least one byte is buffered, we
959 only return buffered bytes. Otherwise, we do one raw read. */
960
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
962 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100963 n = Py_MIN(have, n);
964 res = _bufferedreader_read_fast(self, n);
965 assert(res != Py_None);
966 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100968 res = PyBytes_FromStringAndSize(NULL, n);
969 if (res == NULL)
970 return NULL;
971 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200972 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100973 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200974 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000975 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100976 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
977 LEAVE_BUFFERED(self)
978 if (r == -1) {
979 Py_DECREF(res);
980 return NULL;
981 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982 if (r == -2)
983 r = 0;
984 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100985 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986 return res;
987}
988
989static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000990buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000991{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200992 Py_buffer buf;
993 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000994 PyObject *res = NULL;
995
996 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997
998 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
999 return NULL;
1000
1001 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1002 if (n > 0) {
1003 if (n >= buf.len) {
1004 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1005 self->pos += buf.len;
1006 res = PyLong_FromSsize_t(buf.len);
1007 goto end_unlocked;
1008 }
1009 memcpy(buf.buf, self->buffer + self->pos, n);
1010 self->pos += n;
1011 written = n;
1012 }
1013
1014 if (!ENTER_BUFFERED(self))
1015 goto end_unlocked;
1016
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001017 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001018 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001019 if (res == NULL)
1020 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001022 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001023
1024 _bufferedreader_reset_buf(self);
1025 self->pos = 0;
1026
1027 for (remaining = buf.len - written;
1028 remaining > 0;
1029 written += n, remaining -= n) {
1030 /* If remaining bytes is larger than internal buffer size, copy
1031 * directly into caller's buffer. */
1032 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001033 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1034 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001035 }
1036 else {
1037 n = _bufferedreader_fill_buffer(self);
1038 if (n > 0) {
1039 if (n > remaining)
1040 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001041 memcpy((char *) buf.buf + written,
1042 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001043 self->pos += n;
1044 continue; /* short circuit */
1045 }
1046 }
1047 if (n == 0 || (n == -2 && written > 0))
1048 break;
1049 if (n < 0) {
1050 if (n == -2) {
1051 Py_INCREF(Py_None);
1052 res = Py_None;
1053 }
1054 goto end;
1055 }
1056 }
1057 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058
1059end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001060 LEAVE_BUFFERED(self);
1061end_unlocked:
1062 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001063 return res;
1064}
1065
1066static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001067_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001068{
1069 PyObject *res = NULL;
1070 PyObject *chunks = NULL;
1071 Py_ssize_t n, written = 0;
1072 const char *start, *s, *end;
1073
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001074 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001076 /* First, try to find a line in the buffer. This can run unlocked because
1077 the calls to the C API are simple enough that they can't trigger
1078 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1080 if (limit >= 0 && n > limit)
1081 n = limit;
1082 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001083 s = memchr(start, '\n', n);
1084 if (s != NULL) {
1085 res = PyBytes_FromStringAndSize(start, s - start + 1);
1086 if (res != NULL)
1087 self->pos += s - start + 1;
1088 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001089 }
1090 if (n == limit) {
1091 res = PyBytes_FromStringAndSize(start, n);
1092 if (res != NULL)
1093 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001094 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001095 }
1096
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001097 if (!ENTER_BUFFERED(self))
1098 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001099
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 chunks = PyList_New(0);
1102 if (chunks == NULL)
1103 goto end;
1104 if (n > 0) {
1105 res = PyBytes_FromStringAndSize(start, n);
1106 if (res == NULL)
1107 goto end;
1108 if (PyList_Append(chunks, res) < 0) {
1109 Py_CLEAR(res);
1110 goto end;
1111 }
1112 Py_CLEAR(res);
1113 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001114 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001115 if (limit >= 0)
1116 limit -= n;
1117 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001118 if (self->writable) {
1119 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1120 if (r == NULL)
1121 goto end;
1122 Py_DECREF(r);
1123 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001124
1125 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001126 _bufferedreader_reset_buf(self);
1127 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128 if (n == -1)
1129 goto end;
1130 if (n <= 0)
1131 break;
1132 if (limit >= 0 && n > limit)
1133 n = limit;
1134 start = self->buffer;
1135 end = start + n;
1136 s = start;
1137 while (s < end) {
1138 if (*s++ == '\n') {
1139 res = PyBytes_FromStringAndSize(start, s - start);
1140 if (res == NULL)
1141 goto end;
1142 self->pos = s - start;
1143 goto found;
1144 }
1145 }
1146 res = PyBytes_FromStringAndSize(start, n);
1147 if (res == NULL)
1148 goto end;
1149 if (n == limit) {
1150 self->pos = n;
1151 break;
1152 }
1153 if (PyList_Append(chunks, res) < 0) {
1154 Py_CLEAR(res);
1155 goto end;
1156 }
1157 Py_CLEAR(res);
1158 written += n;
1159 if (limit >= 0)
1160 limit -= n;
1161 }
1162found:
1163 if (res != NULL && PyList_Append(chunks, res) < 0) {
1164 Py_CLEAR(res);
1165 goto end;
1166 }
1167 Py_CLEAR(res);
1168 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1169
1170end:
1171 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001172end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001173 Py_XDECREF(chunks);
1174 return res;
1175}
1176
1177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001178buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001179{
1180 Py_ssize_t limit = -1;
1181
1182 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001183 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001184 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001185 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186}
1187
1188
1189static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001190buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001191{
1192 Py_off_t pos;
1193
1194 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001195 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001196 if (pos == -1)
1197 return NULL;
1198 pos -= RAW_OFFSET(self);
1199 /* TODO: sanity check (pos >= 0) */
1200 return PyLong_FromOff_t(pos);
1201}
1202
1203static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001204buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001205{
1206 Py_off_t target, n;
1207 int whence = 0;
1208 PyObject *targetobj, *res = NULL;
1209
1210 CHECK_INITIALIZED(self)
1211 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1212 return NULL;
1213 }
Jesus Cea94363612012-06-22 18:32:07 +02001214
1215 /* Do some error checking instead of trusting OS 'seek()'
1216 ** error detection, just in case.
1217 */
1218 if ((whence < 0 || whence >2)
1219#ifdef SEEK_HOLE
1220 && (whence != SEEK_HOLE)
1221#endif
1222#ifdef SEEK_DATA
1223 && (whence != SEEK_DATA)
1224#endif
1225 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001227 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001228 return NULL;
1229 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001230
1231 CHECK_CLOSED(self, "seek of closed file")
1232
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001233 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1234 return NULL;
1235
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1237 if (target == -1 && PyErr_Occurred())
1238 return NULL;
1239
Jesus Cea94363612012-06-22 18:32:07 +02001240 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1241 buffer. Other whence values must be managed without this optimization.
1242 Some Operating Systems can provide additional values, like
1243 SEEK_HOLE/SEEK_DATA. */
1244 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245 Py_off_t current, avail;
1246 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001247 so as to return quickly if possible. Also, we needn't take the
1248 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001250 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1251 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001252 current = RAW_TELL(self);
1253 avail = READAHEAD(self);
1254 if (avail > 0) {
1255 Py_off_t offset;
1256 if (whence == 0)
1257 offset = target - (current - RAW_OFFSET(self));
1258 else
1259 offset = target;
1260 if (offset >= -self->pos && offset <= avail) {
1261 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001262 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 }
1264 }
1265 }
1266
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001267 if (!ENTER_BUFFERED(self))
1268 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001269
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270 /* Fallback: invoke raw seek() method and clear buffer */
1271 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001272 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 if (res == NULL)
1274 goto end;
1275 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001276 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001277 }
1278
1279 /* TODO: align on block boundary and read buffer if needed? */
1280 if (whence == 1)
1281 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001282 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 if (n == -1)
1284 goto end;
1285 self->raw_pos = -1;
1286 res = PyLong_FromOff_t(n);
1287 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001288 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289
1290end:
1291 LEAVE_BUFFERED(self)
1292 return res;
1293}
1294
1295static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001296buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001297{
1298 PyObject *pos = Py_None;
1299 PyObject *res = NULL;
1300
1301 CHECK_INITIALIZED(self)
1302 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1303 return NULL;
1304 }
1305
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001306 if (!ENTER_BUFFERED(self))
1307 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308
1309 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001310 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311 if (res == NULL)
1312 goto end;
1313 Py_CLEAR(res);
1314 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001315 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1316 if (res == NULL)
1317 goto end;
1318 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001319 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320 PyErr_Clear();
1321
1322end:
1323 LEAVE_BUFFERED(self)
1324 return res;
1325}
1326
1327static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001328buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001329{
1330 PyObject *line;
1331 PyTypeObject *tp;
1332
1333 CHECK_INITIALIZED(self);
1334
1335 tp = Py_TYPE(self);
1336 if (tp == &PyBufferedReader_Type ||
1337 tp == &PyBufferedRandom_Type) {
1338 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001339 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340 }
1341 else {
1342 line = PyObject_CallMethodObjArgs((PyObject *)self,
1343 _PyIO_str_readline, NULL);
1344 if (line && !PyBytes_Check(line)) {
1345 PyErr_Format(PyExc_IOError,
1346 "readline() should have returned a bytes object, "
1347 "not '%.200s'", Py_TYPE(line)->tp_name);
1348 Py_DECREF(line);
1349 return NULL;
1350 }
1351 }
1352
1353 if (line == NULL)
1354 return NULL;
1355
1356 if (PyBytes_GET_SIZE(line) == 0) {
1357 /* Reached EOF or would have blocked */
1358 Py_DECREF(line);
1359 return NULL;
1360 }
1361
1362 return line;
1363}
1364
Antoine Pitrou716c4442009-05-23 19:04:03 +00001365static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001366buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001367{
1368 PyObject *nameobj, *res;
1369
Martin v. Löwis767046a2011-10-14 15:35:36 +02001370 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001371 if (nameobj == NULL) {
1372 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1373 PyErr_Clear();
1374 else
1375 return NULL;
1376 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1377 }
1378 else {
1379 res = PyUnicode_FromFormat("<%s name=%R>",
1380 Py_TYPE(self)->tp_name, nameobj);
1381 Py_DECREF(nameobj);
1382 }
1383 return res;
1384}
1385
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001386/*
1387 * class BufferedReader
1388 */
1389
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001390PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001391 "Create a new buffered reader using the given readable raw IO object.");
1392
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001393static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001394{
1395 self->read_end = -1;
1396}
1397
1398static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001399bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001400{
1401 char *kwlist[] = {"raw", "buffer_size", NULL};
1402 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1403 PyObject *raw;
1404
1405 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001406 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001407
1408 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1409 &raw, &buffer_size)) {
1410 return -1;
1411 }
1412
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001413 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001414 return -1;
1415
1416 Py_CLEAR(self->raw);
1417 Py_INCREF(raw);
1418 self->raw = raw;
1419 self->buffer_size = buffer_size;
1420 self->readable = 1;
1421 self->writable = 0;
1422
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001423 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001424 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001425 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001426
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001427 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1428 Py_TYPE(raw) == &PyFileIO_Type);
1429
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001430 self->ok = 1;
1431 return 0;
1432}
1433
1434static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001435_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001436{
1437 Py_buffer buf;
1438 PyObject *memobj, *res;
1439 Py_ssize_t n;
1440 /* NOTE: the buffer needn't be released as its object is NULL. */
1441 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1442 return -1;
1443 memobj = PyMemoryView_FromBuffer(&buf);
1444 if (memobj == NULL)
1445 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001446 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1447 occurs so we needn't do it ourselves.
1448 We then retry reading, ignoring the signal if no handler has
1449 raised (see issue #10956).
1450 */
1451 do {
1452 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001453 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454 Py_DECREF(memobj);
1455 if (res == NULL)
1456 return -1;
1457 if (res == Py_None) {
1458 /* Non-blocking stream would have blocked. Special return code! */
1459 Py_DECREF(res);
1460 return -2;
1461 }
1462 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1463 Py_DECREF(res);
1464 if (n < 0 || n > len) {
1465 PyErr_Format(PyExc_IOError,
1466 "raw readinto() returned invalid length %zd "
1467 "(should have been between 0 and %zd)", n, len);
1468 return -1;
1469 }
1470 if (n > 0 && self->abs_pos != -1)
1471 self->abs_pos += n;
1472 return n;
1473}
1474
1475static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001476_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001477{
1478 Py_ssize_t start, len, n;
1479 if (VALID_READ_BUFFER(self))
1480 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1481 else
1482 start = 0;
1483 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001484 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001485 if (n <= 0)
1486 return n;
1487 self->read_end = start + n;
1488 self->raw_pos = start + n;
1489 return n;
1490}
1491
1492static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001493_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001494{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001495 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001496 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001497
1498 /* First copy what we have in the current buffer. */
1499 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1500 if (current_size) {
1501 data = PyBytes_FromStringAndSize(
1502 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001503 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001504 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001505 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001506 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001507 /* We're going past the buffer's bounds, flush it */
1508 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001509 tmp = buffered_flush_and_rewind_unlocked(self);
1510 if (tmp == NULL)
1511 goto cleanup;
1512 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001513 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001514 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001515
1516 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001517 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1518 if (tmp == NULL)
1519 goto cleanup;
1520 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001521 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001522 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001523 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001524 if (tmp == Py_None) {
1525 if (current_size == 0) {
1526 res = Py_None;
1527 goto cleanup;
1528 } else {
1529 res = data;
1530 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001531 }
1532 }
1533 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001534 PyBytes_Concat(&data, tmp);
1535 res = data;
1536 goto cleanup;
1537 }
1538 else {
1539 res = tmp;
1540 goto cleanup;
1541 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001542 }
1543
1544 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001545 if (chunks == NULL)
1546 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001547
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001548 while (1) {
1549 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001550 if (PyList_Append(chunks, data) < 0)
1551 goto cleanup;
1552 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001553 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001554
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001555 /* Read until EOF or until read() would block. */
1556 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 if (data == NULL)
1558 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001559 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001560 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001561 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001562 }
1563 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1564 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001565 res = data;
1566 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567 }
1568 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1570 res = tmp;
1571 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572 }
1573 }
1574 current_size += PyBytes_GET_SIZE(data);
1575 if (self->abs_pos != -1)
1576 self->abs_pos += PyBytes_GET_SIZE(data);
1577 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001578cleanup:
1579 /* res is either NULL or a borrowed ref */
1580 Py_XINCREF(res);
1581 Py_XDECREF(data);
1582 Py_XDECREF(tmp);
1583 Py_XDECREF(chunks);
1584 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001585}
1586
1587/* Read n bytes from the buffer if it can, otherwise return None.
1588 This function is simple enough that it can run unlocked. */
1589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001590_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591{
1592 Py_ssize_t current_size;
1593
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001594 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1595 if (n <= current_size) {
1596 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001597 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1598 if (res != NULL)
1599 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001600 return res;
1601 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602 Py_RETURN_NONE;
1603}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001604
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001605/* Generic read function: read from the stream until enough bytes are read,
1606 * or until an EOF occurs or until read() would block.
1607 */
1608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001609_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001610{
1611 PyObject *res = NULL;
1612 Py_ssize_t current_size, remaining, written;
1613 char *out;
1614
1615 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1616 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001617 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001618
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001619 res = PyBytes_FromStringAndSize(NULL, n);
1620 if (res == NULL)
1621 goto error;
1622 out = PyBytes_AS_STRING(res);
1623 remaining = n;
1624 written = 0;
1625 if (current_size > 0) {
1626 memcpy(out, self->buffer + self->pos, current_size);
1627 remaining -= current_size;
1628 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001629 self->pos += current_size;
1630 }
1631 /* Flush the write buffer if necessary */
1632 if (self->writable) {
1633 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1634 if (r == NULL)
1635 goto error;
1636 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001637 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001638 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001639 while (remaining > 0) {
1640 /* We want to read a whole block at the end into buffer.
1641 If we had readv() we could do this in one pass. */
1642 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1643 if (r == 0)
1644 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001645 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001646 if (r == -1)
1647 goto error;
1648 if (r == 0 || r == -2) {
1649 /* EOF occurred or read() would block. */
1650 if (r == 0 || written > 0) {
1651 if (_PyBytes_Resize(&res, written))
1652 goto error;
1653 return res;
1654 }
1655 Py_DECREF(res);
1656 Py_INCREF(Py_None);
1657 return Py_None;
1658 }
1659 remaining -= r;
1660 written += r;
1661 }
1662 assert(remaining <= self->buffer_size);
1663 self->pos = 0;
1664 self->raw_pos = 0;
1665 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001666 /* NOTE: when the read is satisfied, we avoid issuing any additional
1667 reads, which could block indefinitely (e.g. on a socket).
1668 See issue #9550. */
1669 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001670 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001671 if (r == -1)
1672 goto error;
1673 if (r == 0 || r == -2) {
1674 /* EOF occurred or read() would block. */
1675 if (r == 0 || written > 0) {
1676 if (_PyBytes_Resize(&res, written))
1677 goto error;
1678 return res;
1679 }
1680 Py_DECREF(res);
1681 Py_INCREF(Py_None);
1682 return Py_None;
1683 }
1684 if (remaining > r) {
1685 memcpy(out + written, self->buffer + self->pos, r);
1686 written += r;
1687 self->pos += r;
1688 remaining -= r;
1689 }
1690 else if (remaining > 0) {
1691 memcpy(out + written, self->buffer + self->pos, remaining);
1692 written += remaining;
1693 self->pos += remaining;
1694 remaining = 0;
1695 }
1696 if (remaining == 0)
1697 break;
1698 }
1699
1700 return res;
1701
1702error:
1703 Py_XDECREF(res);
1704 return NULL;
1705}
1706
1707static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001708_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001709{
1710 Py_ssize_t have, r;
1711
1712 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1713 /* Constraints:
1714 1. we don't want to advance the file position.
1715 2. we don't want to lose block alignment, so we can't shift the buffer
1716 to make some place.
1717 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1718 */
1719 if (have > 0) {
1720 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1721 }
1722
1723 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001724 _bufferedreader_reset_buf(self);
1725 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001726 if (r == -1)
1727 return NULL;
1728 if (r == -2)
1729 r = 0;
1730 self->pos = 0;
1731 return PyBytes_FromStringAndSize(self->buffer, r);
1732}
1733
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001734static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001735 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001736 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1737 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1738 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1739 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1740 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1741 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1742 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1743 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001744 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001745 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001747 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1748 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1749 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001750 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001751 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1752 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1753 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1754 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001755 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001756 {NULL, NULL}
1757};
1758
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001759static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001760 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001761 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762 {NULL}
1763};
1764
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001765static PyGetSetDef bufferedreader_getset[] = {
1766 {"closed", (getter)buffered_closed_get, NULL, NULL},
1767 {"name", (getter)buffered_name_get, NULL, NULL},
1768 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001769 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770};
1771
1772
1773PyTypeObject PyBufferedReader_Type = {
1774 PyVarObject_HEAD_INIT(NULL, 0)
1775 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001777 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001778 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779 0, /*tp_print*/
1780 0, /*tp_getattr*/
1781 0, /*tp_setattr*/
1782 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001783 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 0, /*tp_as_number*/
1785 0, /*tp_as_sequence*/
1786 0, /*tp_as_mapping*/
1787 0, /*tp_hash */
1788 0, /*tp_call*/
1789 0, /*tp_str*/
1790 0, /*tp_getattro*/
1791 0, /*tp_setattro*/
1792 0, /*tp_as_buffer*/
1793 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001794 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001795 bufferedreader_doc, /* tp_doc */
1796 (traverseproc)buffered_traverse, /* tp_traverse */
1797 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001798 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001801 (iternextfunc)buffered_iternext, /* tp_iternext */
1802 bufferedreader_methods, /* tp_methods */
1803 bufferedreader_members, /* tp_members */
1804 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 0, /* tp_base */
1806 0, /* tp_dict */
1807 0, /* tp_descr_get */
1808 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809 offsetof(buffered, dict), /* tp_dictoffset */
1810 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 0, /* tp_alloc */
1812 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001813 0, /* tp_free */
1814 0, /* tp_is_gc */
1815 0, /* tp_bases */
1816 0, /* tp_mro */
1817 0, /* tp_cache */
1818 0, /* tp_subclasses */
1819 0, /* tp_weaklist */
1820 0, /* tp_del */
1821 0, /* tp_version_tag */
1822 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823};
1824
1825
Benjamin Peterson59406a92009-03-26 17:10:29 +00001826
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827/*
1828 * class BufferedWriter
1829 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001830PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 "A buffer for a writeable sequential RawIO object.\n"
1832 "\n"
1833 "The constructor creates a BufferedWriter for the given writeable raw\n"
1834 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001835 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 );
1837
1838static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001839_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001840{
1841 self->write_pos = 0;
1842 self->write_end = -1;
1843}
1844
1845static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001846bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847{
Florent Xicluna109d5732012-07-07 17:03:22 +02001848 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001850 PyObject *raw;
1851
1852 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001853 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854
R David Murray9f10f562013-02-23 22:07:55 -05001855 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001856 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001857 return -1;
1858 }
1859
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001860 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001861 return -1;
1862
1863 Py_CLEAR(self->raw);
1864 Py_INCREF(raw);
1865 self->raw = raw;
1866 self->readable = 0;
1867 self->writable = 1;
1868
1869 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001870 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001871 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001872 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001873 self->pos = 0;
1874
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001875 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1876 Py_TYPE(raw) == &PyFileIO_Type);
1877
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001878 self->ok = 1;
1879 return 0;
1880}
1881
1882static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001883_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884{
1885 Py_buffer buf;
1886 PyObject *memobj, *res;
1887 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001888 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 /* NOTE: the buffer needn't be released as its object is NULL. */
1890 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1891 return -1;
1892 memobj = PyMemoryView_FromBuffer(&buf);
1893 if (memobj == NULL)
1894 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001895 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1896 occurs so we needn't do it ourselves.
1897 We then retry writing, ignoring the signal if no handler has
1898 raised (see issue #10956).
1899 */
1900 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001901 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001902 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001903 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001904 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001905 Py_DECREF(memobj);
1906 if (res == NULL)
1907 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001908 if (res == Py_None) {
1909 /* Non-blocking stream would have blocked. Special return code!
1910 Being paranoid we reset errno in case it is changed by code
1911 triggered by a decref. errno is used by _set_BlockingIOError(). */
1912 Py_DECREF(res);
1913 errno = errnum;
1914 return -2;
1915 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1917 Py_DECREF(res);
1918 if (n < 0 || n > len) {
1919 PyErr_Format(PyExc_IOError,
1920 "raw write() returned invalid length %zd "
1921 "(should have been between 0 and %zd)", n, len);
1922 return -1;
1923 }
1924 if (n > 0 && self->abs_pos != -1)
1925 self->abs_pos += n;
1926 return n;
1927}
1928
1929/* `restore_pos` is 1 if we need to restore the raw stream position at
1930 the end, 0 otherwise. */
1931static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001932_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933{
1934 Py_ssize_t written = 0;
1935 Py_off_t n, rewind;
1936
1937 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1938 goto end;
1939 /* First, rewind */
1940 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1941 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001942 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001943 if (n < 0) {
1944 goto error;
1945 }
1946 self->raw_pos -= rewind;
1947 }
1948 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001949 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001950 self->buffer + self->write_pos,
1951 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1952 Py_off_t, Py_ssize_t));
1953 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001954 goto error;
1955 }
1956 else if (n == -2) {
1957 _set_BlockingIOError("write could not complete without blocking",
1958 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001959 goto error;
1960 }
1961 self->write_pos += n;
1962 self->raw_pos = self->write_pos;
1963 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001964 /* Partial writes can return successfully when interrupted by a
1965 signal (see write(2)). We must run signal handlers before
1966 blocking another time, possibly indefinitely. */
1967 if (PyErr_CheckSignals() < 0)
1968 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969 }
1970
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001971 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972
1973end:
1974 Py_RETURN_NONE;
1975
1976error:
1977 return NULL;
1978}
1979
1980static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001981bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982{
1983 PyObject *res = NULL;
1984 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001985 Py_ssize_t written, avail, remaining;
1986 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001987
1988 CHECK_INITIALIZED(self)
1989 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1990 return NULL;
1991 }
1992
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001993 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001994 PyErr_SetString(PyExc_ValueError, "write to closed file");
1995 PyBuffer_Release(&buf);
1996 return NULL;
1997 }
1998
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001999 if (!ENTER_BUFFERED(self)) {
2000 PyBuffer_Release(&buf);
2001 return NULL;
2002 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003
2004 /* Fast path: the data to write can be fully buffered. */
2005 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2006 self->pos = 0;
2007 self->raw_pos = 0;
2008 }
2009 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2010 if (buf.len <= avail) {
2011 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002012 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002013 self->write_pos = self->pos;
2014 }
2015 ADJUST_POSITION(self, self->pos + buf.len);
2016 if (self->pos > self->write_end)
2017 self->write_end = self->pos;
2018 written = buf.len;
2019 goto end;
2020 }
2021
2022 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002023 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002025 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 if (w == NULL)
2027 goto error;
2028 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002029 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 /* Make some place by shifting the buffer. */
2031 assert(VALID_WRITE_BUFFER(self));
2032 memmove(self->buffer, self->buffer + self->write_pos,
2033 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2034 Py_off_t, Py_ssize_t));
2035 self->write_end -= self->write_pos;
2036 self->raw_pos -= self->write_pos;
2037 self->pos -= self->write_pos;
2038 self->write_pos = 0;
2039 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2040 Py_off_t, Py_ssize_t);
2041 if (buf.len <= avail) {
2042 /* Everything can be buffered */
2043 PyErr_Clear();
2044 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2045 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002046 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002047 written = buf.len;
2048 goto end;
2049 }
2050 /* Buffer as much as possible. */
2051 memcpy(self->buffer + self->write_end, buf.buf, avail);
2052 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002053 self->pos += avail;
2054 /* XXX Modifying the existing exception e using the pointer w
2055 will change e.characters_written but not e.args[2].
2056 Therefore we just replace with a new error. */
2057 _set_BlockingIOError("write could not complete without blocking",
2058 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059 goto error;
2060 }
2061 Py_CLEAR(res);
2062
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002063 /* Adjust the raw stream position if it is away from the logical stream
2064 position. This happens if the read buffer has been filled but not
2065 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2066 the raw stream by itself).
2067 Fixes issue #6629.
2068 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002069 offset = RAW_OFFSET(self);
2070 if (offset != 0) {
2071 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002072 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002073 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002074 }
2075
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076 /* Then write buf itself. At this point the buffer has been emptied. */
2077 remaining = buf.len;
2078 written = 0;
2079 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002080 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 self, (char *) buf.buf + written, buf.len - written);
2082 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002083 goto error;
2084 } else if (n == -2) {
2085 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086 if (remaining > self->buffer_size) {
2087 /* Can't buffer everything, still buffer as much as possible */
2088 memcpy(self->buffer,
2089 (char *) buf.buf + written, self->buffer_size);
2090 self->raw_pos = 0;
2091 ADJUST_POSITION(self, self->buffer_size);
2092 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002093 written += self->buffer_size;
2094 _set_BlockingIOError("write could not complete without "
2095 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096 goto error;
2097 }
2098 PyErr_Clear();
2099 break;
2100 }
2101 written += n;
2102 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002103 /* Partial writes can return successfully when interrupted by a
2104 signal (see write(2)). We must run signal handlers before
2105 blocking another time, possibly indefinitely. */
2106 if (PyErr_CheckSignals() < 0)
2107 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108 }
2109 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 if (remaining > 0) {
2112 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2113 written += remaining;
2114 }
2115 self->write_pos = 0;
2116 /* TODO: sanity check (remaining >= 0) */
2117 self->write_end = remaining;
2118 ADJUST_POSITION(self, remaining);
2119 self->raw_pos = 0;
2120
2121end:
2122 res = PyLong_FromSsize_t(written);
2123
2124error:
2125 LEAVE_BUFFERED(self)
2126 PyBuffer_Release(&buf);
2127 return res;
2128}
2129
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002130static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002132 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2133 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2134 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2135 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2136 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2137 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2138 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002139 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002140 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002142 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2143 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2144 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2145 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2146 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002147 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148 {NULL, NULL}
2149};
2150
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002151static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002152 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002153 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154 {NULL}
2155};
2156
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002157static PyGetSetDef bufferedwriter_getset[] = {
2158 {"closed", (getter)buffered_closed_get, NULL, NULL},
2159 {"name", (getter)buffered_name_get, NULL, NULL},
2160 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002161 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002162};
2163
2164
2165PyTypeObject PyBufferedWriter_Type = {
2166 PyVarObject_HEAD_INIT(NULL, 0)
2167 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 0, /*tp_print*/
2172 0, /*tp_getattr*/
2173 0, /*tp_setattr*/
2174 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002175 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002176 0, /*tp_as_number*/
2177 0, /*tp_as_sequence*/
2178 0, /*tp_as_mapping*/
2179 0, /*tp_hash */
2180 0, /*tp_call*/
2181 0, /*tp_str*/
2182 0, /*tp_getattro*/
2183 0, /*tp_setattro*/
2184 0, /*tp_as_buffer*/
2185 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002186 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187 bufferedwriter_doc, /* tp_doc */
2188 (traverseproc)buffered_traverse, /* tp_traverse */
2189 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002190 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002191 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 0, /* tp_iter */
2193 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002194 bufferedwriter_methods, /* tp_methods */
2195 bufferedwriter_members, /* tp_members */
2196 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 0, /* tp_base */
2198 0, /* tp_dict */
2199 0, /* tp_descr_get */
2200 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002201 offsetof(buffered, dict), /* tp_dictoffset */
2202 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203 0, /* tp_alloc */
2204 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002205 0, /* tp_free */
2206 0, /* tp_is_gc */
2207 0, /* tp_bases */
2208 0, /* tp_mro */
2209 0, /* tp_cache */
2210 0, /* tp_subclasses */
2211 0, /* tp_weaklist */
2212 0, /* tp_del */
2213 0, /* tp_version_tag */
2214 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215};
2216
2217
2218
2219/*
2220 * BufferedRWPair
2221 */
2222
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 "A buffered reader and writer object together.\n"
2225 "\n"
2226 "A buffered reader object and buffered writer object put together to\n"
2227 "form a sequential IO object that can read and write. This is typically\n"
2228 "used with a socket or two-way pipe.\n"
2229 "\n"
2230 "reader and writer are RawIOBase objects that are readable and\n"
2231 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002232 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233 );
2234
2235/* XXX The usefulness of this (compared to having two separate IO objects) is
2236 * questionable.
2237 */
2238
2239typedef struct {
2240 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002241 buffered *reader;
2242 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002243 PyObject *dict;
2244 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002245} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246
2247static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002248bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249{
2250 PyObject *reader, *writer;
2251 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002252
Florent Xicluna109d5732012-07-07 17:03:22 +02002253 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2254 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255 return -1;
2256 }
2257
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002258 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002260 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261 return -1;
2262
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002263 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002264 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265 if (self->reader == NULL)
2266 return -1;
2267
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002268 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002269 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270 if (self->writer == NULL) {
2271 Py_CLEAR(self->reader);
2272 return -1;
2273 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002274
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002275 return 0;
2276}
2277
2278static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002279bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002280{
2281 Py_VISIT(self->dict);
2282 return 0;
2283}
2284
2285static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002286bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002287{
2288 Py_CLEAR(self->reader);
2289 Py_CLEAR(self->writer);
2290 Py_CLEAR(self->dict);
2291 return 0;
2292}
2293
2294static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002295bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296{
2297 _PyObject_GC_UNTRACK(self);
2298 Py_CLEAR(self->reader);
2299 Py_CLEAR(self->writer);
2300 Py_CLEAR(self->dict);
2301 Py_TYPE(self)->tp_free((PyObject *) self);
2302}
2303
2304static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002305_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002306{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002307 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308 PyObject *ret;
2309
2310 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002311 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312 return NULL;
2313 }
2314
2315 ret = PyObject_CallObject(func, args);
2316 Py_DECREF(func);
2317 return ret;
2318}
2319
2320static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002321bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002322{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002323 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002324}
2325
2326static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002327bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002329 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002330}
2331
2332static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002333bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002335 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002336}
2337
2338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002340{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002341 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002342}
2343
2344static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002345bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002346{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002347 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002348}
2349
2350static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002351bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002352{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002353 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002354}
2355
2356static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002357bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002358{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002359 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002360}
2361
2362static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002363bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002364{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002365 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002366}
2367
2368static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002369bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002370{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002371 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002372 if (ret == NULL)
2373 return NULL;
2374 Py_DECREF(ret);
2375
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002376 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377}
2378
2379static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002380bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002381{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002382 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002383
2384 if (ret != Py_False) {
2385 /* either True or exception */
2386 return ret;
2387 }
2388 Py_DECREF(ret);
2389
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002390 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002391}
2392
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002393static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002394bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002395{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002396 if (self->writer == NULL) {
2397 PyErr_SetString(PyExc_RuntimeError,
2398 "the BufferedRWPair object is being garbage-collected");
2399 return NULL;
2400 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002401 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2402}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002403
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002404static PyMethodDef bufferedrwpair_methods[] = {
2405 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2406 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2407 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2408 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002409
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002410 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2411 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002412
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002413 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2414 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002415
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002416 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2417 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418
Antoine Pitrou243757e2010-11-05 21:15:39 +00002419 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2420
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002421 {NULL, NULL}
2422};
2423
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002424static PyGetSetDef bufferedrwpair_getset[] = {
2425 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002426 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002427};
2428
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002429PyTypeObject PyBufferedRWPair_Type = {
2430 PyVarObject_HEAD_INIT(NULL, 0)
2431 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002432 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002433 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002434 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002435 0, /*tp_print*/
2436 0, /*tp_getattr*/
2437 0, /*tp_setattr*/
2438 0, /*tp_compare */
2439 0, /*tp_repr*/
2440 0, /*tp_as_number*/
2441 0, /*tp_as_sequence*/
2442 0, /*tp_as_mapping*/
2443 0, /*tp_hash */
2444 0, /*tp_call*/
2445 0, /*tp_str*/
2446 0, /*tp_getattro*/
2447 0, /*tp_setattro*/
2448 0, /*tp_as_buffer*/
2449 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002450 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002451 bufferedrwpair_doc, /* tp_doc */
2452 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2453 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002454 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002455 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 0, /* tp_iter */
2457 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002458 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002460 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461 0, /* tp_base */
2462 0, /* tp_dict */
2463 0, /* tp_descr_get */
2464 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002465 offsetof(rwpair, dict), /* tp_dictoffset */
2466 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002467 0, /* tp_alloc */
2468 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002469 0, /* tp_free */
2470 0, /* tp_is_gc */
2471 0, /* tp_bases */
2472 0, /* tp_mro */
2473 0, /* tp_cache */
2474 0, /* tp_subclasses */
2475 0, /* tp_weaklist */
2476 0, /* tp_del */
2477 0, /* tp_version_tag */
2478 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002479};
2480
2481
2482
2483/*
2484 * BufferedRandom
2485 */
2486
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002487PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002488 "A buffered interface to random access streams.\n"
2489 "\n"
2490 "The constructor creates a reader and writer for a seekable stream,\n"
2491 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002492 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002493 );
2494
2495static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002496bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002497{
Florent Xicluna109d5732012-07-07 17:03:22 +02002498 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002499 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500 PyObject *raw;
2501
2502 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002503 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002504
R David Murray9f10f562013-02-23 22:07:55 -05002505 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002506 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507 return -1;
2508 }
2509
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002510 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002511 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002512 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002513 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002514 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002515 return -1;
2516
2517 Py_CLEAR(self->raw);
2518 Py_INCREF(raw);
2519 self->raw = raw;
2520 self->buffer_size = buffer_size;
2521 self->readable = 1;
2522 self->writable = 1;
2523
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002524 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002525 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002526 _bufferedreader_reset_buf(self);
2527 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002528 self->pos = 0;
2529
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002530 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2531 Py_TYPE(raw) == &PyFileIO_Type);
2532
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002533 self->ok = 1;
2534 return 0;
2535}
2536
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002537static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002538 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002539 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2540 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2541 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2542 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2543 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2544 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2545 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002546 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002547 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002548
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002549 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002550
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002551 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2552 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2553 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2554 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2555 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2556 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2557 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2558 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2559 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002560 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002561 {NULL, NULL}
2562};
2563
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002564static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002565 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002566 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002567 {NULL}
2568};
2569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570static PyGetSetDef bufferedrandom_getset[] = {
2571 {"closed", (getter)buffered_closed_get, NULL, NULL},
2572 {"name", (getter)buffered_name_get, NULL, NULL},
2573 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002574 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575};
2576
2577
2578PyTypeObject PyBufferedRandom_Type = {
2579 PyVarObject_HEAD_INIT(NULL, 0)
2580 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002581 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002583 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002584 0, /*tp_print*/
2585 0, /*tp_getattr*/
2586 0, /*tp_setattr*/
2587 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002588 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589 0, /*tp_as_number*/
2590 0, /*tp_as_sequence*/
2591 0, /*tp_as_mapping*/
2592 0, /*tp_hash */
2593 0, /*tp_call*/
2594 0, /*tp_str*/
2595 0, /*tp_getattro*/
2596 0, /*tp_setattro*/
2597 0, /*tp_as_buffer*/
2598 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002599 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002600 bufferedrandom_doc, /* tp_doc */
2601 (traverseproc)buffered_traverse, /* tp_traverse */
2602 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002603 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002604 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002605 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002606 (iternextfunc)buffered_iternext, /* tp_iternext */
2607 bufferedrandom_methods, /* tp_methods */
2608 bufferedrandom_members, /* tp_members */
2609 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002610 0, /* tp_base */
2611 0, /*tp_dict*/
2612 0, /* tp_descr_get */
2613 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002614 offsetof(buffered, dict), /*tp_dictoffset*/
2615 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616 0, /* tp_alloc */
2617 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002618 0, /* tp_free */
2619 0, /* tp_is_gc */
2620 0, /* tp_bases */
2621 0, /* tp_mro */
2622 0, /* tp_cache */
2623 0, /* tp_subclasses */
2624 0, /* tp_weaklist */
2625 0, /* tp_del */
2626 0, /* tp_version_tag */
2627 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002628};