blob: 34c2bb97bd670cb8026fca8062eb173aa6cde9fa [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;
55
56 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
57 return NULL;
58 }
59
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020060 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000061 if (data == NULL)
62 goto error;
63
64 if (!PyBytes_Check(data)) {
65 Py_DECREF(data);
66 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
67 goto error;
68 }
69
70 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030071 if (len > buf.len) {
72 PyErr_Format(PyExc_ValueError,
73 "read() returned too much data: "
74 "%zd bytes requested, %zd returned",
75 buf.len, len);
76 Py_DECREF(data);
77 goto error;
78 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000079 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
80
81 PyBuffer_Release(&buf);
82 Py_DECREF(data);
83
84 return PyLong_FromSsize_t(len);
85
86 error:
87 PyBuffer_Release(&buf);
88 return NULL;
89}
90
91static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000092bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000093{
Antoine Pitrou712cb732013-12-21 15:51:54 +010094 _PyIO_State *state = IO_STATE();
95 if (state != NULL)
96 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000097 return NULL;
98}
99
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000100PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000101 "Disconnect this buffer from its underlying raw stream and return it.\n"
102 "\n"
103 "After the raw stream has been detached, the buffer is in an unusable\n"
104 "state.\n");
105
106static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000107bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000108{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000109 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000110}
111
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000112PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000113 "Read and return up to n bytes.\n"
114 "\n"
115 "If the argument is omitted, None, or negative, reads and\n"
116 "returns all data until EOF.\n"
117 "\n"
118 "If the argument is positive, and the underlying raw stream is\n"
119 "not 'interactive', multiple raw reads may be issued to satisfy\n"
120 "the byte count (unless EOF is reached first). But for\n"
121 "interactive raw streams (as well as sockets and pipes), at most\n"
122 "one raw read will be issued, and a short result does not imply\n"
123 "that EOF is imminent.\n"
124 "\n"
125 "Returns an empty bytes object on EOF.\n"
126 "\n"
127 "Returns None if the underlying raw stream was open in non-blocking\n"
128 "mode and no data is available at the moment.\n");
129
130static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000131bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000132{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000133 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000134}
135
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000136PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000137 "Read and return up to n bytes, with at most one read() call\n"
138 "to the underlying raw stream. A short result does not imply\n"
139 "that EOF is imminent.\n"
140 "\n"
141 "Returns an empty bytes object on EOF.\n");
142
143static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000145{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000146 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000147}
148
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000149PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000150 "Write the given buffer to the IO stream.\n"
151 "\n"
152 "Returns the number of bytes written, which is never less than\n"
153 "len(b).\n"
154 "\n"
155 "Raises BlockingIOError if the buffer is full and the\n"
156 "underlying raw stream cannot accept more data at the moment.\n");
157
158static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000159bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000160{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000161 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000162}
163
164
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165static PyMethodDef bufferediobase_methods[] = {
166 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
167 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
168 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
169 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
170 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171 {NULL, NULL}
172};
173
174PyTypeObject PyBufferedIOBase_Type = {
175 PyVarObject_HEAD_INIT(NULL, 0)
176 "_io._BufferedIOBase", /*tp_name*/
177 0, /*tp_basicsize*/
178 0, /*tp_itemsize*/
179 0, /*tp_dealloc*/
180 0, /*tp_print*/
181 0, /*tp_getattr*/
182 0, /*tp_setattr*/
183 0, /*tp_compare */
184 0, /*tp_repr*/
185 0, /*tp_as_number*/
186 0, /*tp_as_sequence*/
187 0, /*tp_as_mapping*/
188 0, /*tp_hash */
189 0, /*tp_call*/
190 0, /*tp_str*/
191 0, /*tp_getattro*/
192 0, /*tp_setattro*/
193 0, /*tp_as_buffer*/
Antoine Pitrou796564c2013-07-30 19:59:21 +0200194 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
195 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197 0, /* tp_traverse */
198 0, /* tp_clear */
199 0, /* tp_richcompare */
200 0, /* tp_weaklistoffset */
201 0, /* tp_iter */
202 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000203 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000204 0, /* tp_members */
205 0, /* tp_getset */
206 &PyIOBase_Type, /* tp_base */
207 0, /* tp_dict */
208 0, /* tp_descr_get */
209 0, /* tp_descr_set */
210 0, /* tp_dictoffset */
211 0, /* tp_init */
212 0, /* tp_alloc */
213 0, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200214 0, /* tp_free */
215 0, /* tp_is_gc */
216 0, /* tp_bases */
217 0, /* tp_mro */
218 0, /* tp_cache */
219 0, /* tp_subclasses */
220 0, /* tp_weaklist */
221 0, /* tp_del */
222 0, /* tp_version_tag */
223 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000224};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000225
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000226
227typedef struct {
228 PyObject_HEAD
229
230 PyObject *raw;
231 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000232 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000233 int readable;
234 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200235 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200236
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000237 /* True if this is a vanilla Buffered object (rather than a user derived
238 class) *and* the raw stream is a vanilla FileIO object. */
239 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000240
241 /* Absolute position inside the raw stream (-1 if unknown). */
242 Py_off_t abs_pos;
243
244 /* A static buffer of size `buffer_size` */
245 char *buffer;
246 /* Current logical position in the buffer. */
247 Py_off_t pos;
248 /* Position of the raw stream in the buffer. */
249 Py_off_t raw_pos;
250
251 /* Just after the last buffered byte in the buffer, or -1 if the buffer
252 isn't ready for reading. */
253 Py_off_t read_end;
254
255 /* Just after the last byte actually written */
256 Py_off_t write_pos;
257 /* Just after the last byte waiting to be written, or -1 if the buffer
258 isn't ready for writing. */
259 Py_off_t write_end;
260
Georg Brandldfd73442009-04-05 11:47:34 +0000261#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000262 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000263 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000264#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000265
266 Py_ssize_t buffer_size;
267 Py_ssize_t buffer_mask;
268
269 PyObject *dict;
270 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000271} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000272
273/*
274 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200275
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000276 * BufferedReader, BufferedWriter and BufferedRandom try to share most
277 methods (this is helped by the members `readable` and `writable`, which
278 are initialized in the respective constructors)
279 * They also share a single buffer for reading and writing. This enables
280 interleaved reads and writes without flushing. It also makes the logic
281 a bit trickier to get right.
282 * The absolute position of the raw stream is cached, if possible, in the
283 `abs_pos` member. It must be updated every time an operation is done
284 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000285 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000286 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000287 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
288 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000289
290 NOTE: we should try to maintain block alignment of reads and writes to the
291 raw stream (according to the buffer size), but for now it is only done
292 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200293
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000294*/
295
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000296/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000297
Georg Brandldfd73442009-04-05 11:47:34 +0000298#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000299
300static int
301_enter_buffered_busy(buffered *self)
302{
303 if (self->owner == PyThread_get_thread_ident()) {
304 PyErr_Format(PyExc_RuntimeError,
305 "reentrant call inside %R", self);
306 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000307 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000308 Py_BEGIN_ALLOW_THREADS
309 PyThread_acquire_lock(self->lock, 1);
310 Py_END_ALLOW_THREADS
311 return 1;
312}
313
314#define ENTER_BUFFERED(self) \
315 ( (PyThread_acquire_lock(self->lock, 0) ? \
316 1 : _enter_buffered_busy(self)) \
317 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000318
319#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000320 do { \
321 self->owner = 0; \
322 PyThread_release_lock(self->lock); \
323 } while(0);
324
Georg Brandldfd73442009-04-05 11:47:34 +0000325#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000326#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000327#define LEAVE_BUFFERED(self)
328#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000329
330#define CHECK_INITIALIZED(self) \
331 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000332 if (self->detached) { \
333 PyErr_SetString(PyExc_ValueError, \
334 "raw stream has been detached"); \
335 } else { \
336 PyErr_SetString(PyExc_ValueError, \
337 "I/O operation on uninitialized object"); \
338 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 return NULL; \
340 }
341
342#define CHECK_INITIALIZED_INT(self) \
343 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000344 if (self->detached) { \
345 PyErr_SetString(PyExc_ValueError, \
346 "raw stream has been detached"); \
347 } else { \
348 PyErr_SetString(PyExc_ValueError, \
349 "I/O operation on uninitialized object"); \
350 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000351 return -1; \
352 }
353
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000354#define IS_CLOSED(self) \
355 (self->fast_closed_checks \
356 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000357 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000358
359#define CHECK_CLOSED(self, error_msg) \
360 if (IS_CLOSED(self)) { \
361 PyErr_SetString(PyExc_ValueError, error_msg); \
362 return NULL; \
363 }
364
365
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000366#define VALID_READ_BUFFER(self) \
367 (self->readable && self->read_end != -1)
368
369#define VALID_WRITE_BUFFER(self) \
370 (self->writable && self->write_end != -1)
371
372#define ADJUST_POSITION(self, _new_pos) \
373 do { \
374 self->pos = _new_pos; \
375 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
376 self->read_end = self->pos; \
377 } while(0)
378
379#define READAHEAD(self) \
380 ((self->readable && VALID_READ_BUFFER(self)) \
381 ? (self->read_end - self->pos) : 0)
382
383#define RAW_OFFSET(self) \
384 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
385 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
386
387#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000388 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000389
390#define MINUS_LAST_BLOCK(self, size) \
391 (self->buffer_mask ? \
392 (size & ~self->buffer_mask) : \
393 (self->buffer_size * (size / self->buffer_size)))
394
395
396static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000397buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000398{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200399 self->finalizing = 1;
400 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000401 return;
402 _PyObject_GC_UNTRACK(self);
403 self->ok = 0;
404 if (self->weakreflist != NULL)
405 PyObject_ClearWeakRefs((PyObject *)self);
406 Py_CLEAR(self->raw);
407 if (self->buffer) {
408 PyMem_Free(self->buffer);
409 self->buffer = NULL;
410 }
Georg Brandldfd73442009-04-05 11:47:34 +0000411#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000412 if (self->lock) {
413 PyThread_free_lock(self->lock);
414 self->lock = NULL;
415 }
Georg Brandldfd73442009-04-05 11:47:34 +0000416#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000417 Py_CLEAR(self->dict);
418 Py_TYPE(self)->tp_free((PyObject *)self);
419}
420
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200421static PyObject *
422buffered_sizeof(buffered *self, void *unused)
423{
424 Py_ssize_t res;
425
426 res = sizeof(buffered);
427 if (self->buffer)
428 res += self->buffer_size;
429 return PyLong_FromSsize_t(res);
430}
431
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000432static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000433buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000434{
435 Py_VISIT(self->raw);
436 Py_VISIT(self->dict);
437 return 0;
438}
439
440static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000441buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000442{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000443 self->ok = 0;
444 Py_CLEAR(self->raw);
445 Py_CLEAR(self->dict);
446 return 0;
447}
448
Antoine Pitroue033e062010-10-29 10:38:18 +0000449/* Because this can call arbitrary code, it shouldn't be called when
450 the refcount is 0 (that is, not directly from tp_dealloc unless
451 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000452static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000453buffered_dealloc_warn(buffered *self, PyObject *source)
454{
455 if (self->ok && self->raw) {
456 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200457 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000458 if (r)
459 Py_DECREF(r);
460 else
461 PyErr_Clear();
462 }
463 Py_RETURN_NONE;
464}
465
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466/*
467 * _BufferedIOMixin methods
468 * This is not a class, just a collection of methods that will be reused
469 * by BufferedReader and BufferedWriter
470 */
471
472/* Flush and close */
473
474static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000475buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000476{
477 CHECK_INITIALIZED(self)
478 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
479}
480
481static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000482buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000483{
484 int closed;
485 PyObject *res;
486 CHECK_INITIALIZED_INT(self)
487 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
488 if (res == NULL)
489 return -1;
490 closed = PyObject_IsTrue(res);
491 Py_DECREF(res);
492 return closed;
493}
494
495static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000496buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000497{
498 CHECK_INITIALIZED(self)
499 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
500}
501
502static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000503buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504{
Benjamin Peterson68623612012-12-20 11:53:11 -0600505 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506 int r;
507
508 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000509 if (!ENTER_BUFFERED(self))
510 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000512 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513 if (r < 0)
514 goto end;
515 if (r > 0) {
516 res = Py_None;
517 Py_INCREF(res);
518 goto end;
519 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000520
Antoine Pitrou796564c2013-07-30 19:59:21 +0200521 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000522 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
523 if (r)
524 Py_DECREF(r);
525 else
526 PyErr_Clear();
527 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000528 /* flush() will most probably re-take the lock, so drop it first */
529 LEAVE_BUFFERED(self)
530 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000531 if (!ENTER_BUFFERED(self))
532 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600533 if (res == NULL)
534 PyErr_Fetch(&exc, &val, &tb);
535 else
536 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000537
538 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
539
Jesus Ceadc469452012-10-04 12:37:56 +0200540 if (self->buffer) {
541 PyMem_Free(self->buffer);
542 self->buffer = NULL;
543 }
544
Benjamin Peterson68623612012-12-20 11:53:11 -0600545 if (exc != NULL) {
546 if (res != NULL) {
547 Py_CLEAR(res);
548 PyErr_Restore(exc, val, tb);
549 }
550 else {
551 PyObject *val2;
552 Py_DECREF(exc);
553 Py_XDECREF(tb);
554 PyErr_Fetch(&exc, &val2, &tb);
555 PyErr_NormalizeException(&exc, &val2, &tb);
556 PyException_SetContext(val2, val);
557 PyErr_Restore(exc, val2, tb);
558 }
559 }
560
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000561end:
562 LEAVE_BUFFERED(self)
563 return res;
564}
565
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000566/* detach */
567
568static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000569buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000570{
571 PyObject *raw, *res;
572 CHECK_INITIALIZED(self)
573 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
574 if (res == NULL)
575 return NULL;
576 Py_DECREF(res);
577 raw = self->raw;
578 self->raw = NULL;
579 self->detached = 1;
580 self->ok = 0;
581 return raw;
582}
583
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584/* Inquiries */
585
586static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000587buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000588{
589 CHECK_INITIALIZED(self)
590 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
591}
592
593static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000594buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000595{
596 CHECK_INITIALIZED(self)
597 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
598}
599
600static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000601buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602{
603 CHECK_INITIALIZED(self)
604 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
605}
606
607static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000608buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609{
610 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200611 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000612}
613
614static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616{
617 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200618 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619}
620
621/* Lower-level APIs */
622
623static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000624buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000625{
626 CHECK_INITIALIZED(self)
627 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
628}
629
630static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000631buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000632{
633 CHECK_INITIALIZED(self)
634 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
635}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000636
Antoine Pitrou243757e2010-11-05 21:15:39 +0000637/* Serialization */
638
639static PyObject *
640buffered_getstate(buffered *self, PyObject *args)
641{
642 PyErr_Format(PyExc_TypeError,
643 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
644 return NULL;
645}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000646
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647/* Forward decls */
648static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100649_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000650static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000655_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200657_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000659_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000660static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000661_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000662static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000663_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200664static Py_ssize_t
665_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000666
667/*
668 * Helpers
669 */
670
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100671/* Sets the current error to BlockingIOError */
672static void
673_set_BlockingIOError(char *msg, Py_ssize_t written)
674{
675 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200676#ifdef Py_DEBUG
677 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
678 if an exception is set when it is called */
679 PyErr_Clear();
680#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100681 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
682 errno, msg, written);
683 if (err)
684 PyErr_SetObject(PyExc_BlockingIOError, err);
685 Py_XDECREF(err);
686}
687
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688/* Returns the address of the `written` member if a BlockingIOError was
689 raised, NULL otherwise. The error is always re-raised. */
690static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000691_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692{
693 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200694 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695
696 PyErr_Fetch(&t, &v, &tb);
697 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
698 PyErr_Restore(t, v, tb);
699 return NULL;
700 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200701 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 /* TODO: sanity check (err->written >= 0) */
703 PyErr_Restore(t, v, tb);
704 return &err->written;
705}
706
707static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000708_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000711 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
713 if (res == NULL)
714 return -1;
715 n = PyNumber_AsOff_t(res, PyExc_ValueError);
716 Py_DECREF(res);
717 if (n < 0) {
718 if (!PyErr_Occurred())
719 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000720 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200721 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000722 return -1;
723 }
724 self->abs_pos = n;
725 return n;
726}
727
728static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000729_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000730{
731 PyObject *res, *posobj, *whenceobj;
732 Py_off_t n;
733
734 posobj = PyLong_FromOff_t(target);
735 if (posobj == NULL)
736 return -1;
737 whenceobj = PyLong_FromLong(whence);
738 if (whenceobj == NULL) {
739 Py_DECREF(posobj);
740 return -1;
741 }
742 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
743 posobj, whenceobj, NULL);
744 Py_DECREF(posobj);
745 Py_DECREF(whenceobj);
746 if (res == NULL)
747 return -1;
748 n = PyNumber_AsOff_t(res, PyExc_ValueError);
749 Py_DECREF(res);
750 if (n < 0) {
751 if (!PyErr_Occurred())
752 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000753 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200754 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000755 return -1;
756 }
757 self->abs_pos = n;
758 return n;
759}
760
761static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000762_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000763{
764 Py_ssize_t n;
765 if (self->buffer_size <= 0) {
766 PyErr_SetString(PyExc_ValueError,
767 "buffer size must be strictly positive");
768 return -1;
769 }
770 if (self->buffer)
771 PyMem_Free(self->buffer);
772 self->buffer = PyMem_Malloc(self->buffer_size);
773 if (self->buffer == NULL) {
774 PyErr_NoMemory();
775 return -1;
776 }
Georg Brandldfd73442009-04-05 11:47:34 +0000777#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000778 if (self->lock)
779 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000780 self->lock = PyThread_allocate_lock();
781 if (self->lock == NULL) {
782 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
783 return -1;
784 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000785 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000786#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000787 /* Find out whether buffer_size is a power of 2 */
788 /* XXX is this optimization useful? */
789 for (n = self->buffer_size - 1; n & 1; n >>= 1)
790 ;
791 if (n == 0)
792 self->buffer_mask = self->buffer_size - 1;
793 else
794 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000795 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000796 PyErr_Clear();
797 return 0;
798}
799
Antoine Pitrou707ce822011-02-25 21:24:11 +0000800/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
801 clears the error indicator), 0 otherwise.
802 Should only be called when PyErr_Occurred() is true.
803*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700804int
805_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000806{
807 static PyObject *eintr_int = NULL;
808 PyObject *typ, *val, *tb;
809 PyEnvironmentErrorObject *env_err;
810
811 if (eintr_int == NULL) {
812 eintr_int = PyLong_FromLong(EINTR);
813 assert(eintr_int != NULL);
814 }
815 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
816 return 0;
817 PyErr_Fetch(&typ, &val, &tb);
818 PyErr_NormalizeException(&typ, &val, &tb);
819 env_err = (PyEnvironmentErrorObject *) val;
820 assert(env_err != NULL);
821 if (env_err->myerrno != NULL &&
822 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
823 Py_DECREF(typ);
824 Py_DECREF(val);
825 Py_XDECREF(tb);
826 return 1;
827 }
828 /* This silences any error set by PyObject_RichCompareBool() */
829 PyErr_Restore(typ, val, tb);
830 return 0;
831}
832
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833/*
834 * Shared methods and wrappers
835 */
836
837static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200838buffered_flush_and_rewind_unlocked(buffered *self)
839{
840 PyObject *res;
841
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100842 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200843 if (res == NULL)
844 return NULL;
845 Py_DECREF(res);
846
847 if (self->readable) {
848 /* Rewind the raw stream so that its position corresponds to
849 the current logical position. */
850 Py_off_t n;
851 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
852 _bufferedreader_reset_buf(self);
853 if (n == -1)
854 return NULL;
855 }
856 Py_RETURN_NONE;
857}
858
859static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000860buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000861{
862 PyObject *res;
863
864 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000865 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000867 if (!ENTER_BUFFERED(self))
868 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200869 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000870 LEAVE_BUFFERED(self)
871
872 return res;
873}
874
875static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000876buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000877{
878 Py_ssize_t n = 0;
879 PyObject *res = NULL;
880
881 CHECK_INITIALIZED(self)
882 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
883 return NULL;
884 }
885
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000886 if (!ENTER_BUFFERED(self))
887 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000888
889 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200890 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000891 if (res == NULL)
892 goto end;
893 Py_CLEAR(res);
894 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200895 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896
897end:
898 LEAVE_BUFFERED(self)
899 return res;
900}
901
902static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000903buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000904{
905 Py_ssize_t n = -1;
906 PyObject *res;
907
908 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000909 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000910 return NULL;
911 }
912 if (n < -1) {
913 PyErr_SetString(PyExc_ValueError,
914 "read length must be positive or -1");
915 return NULL;
916 }
917
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000918 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000919
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000920 if (n == -1) {
921 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000922 if (!ENTER_BUFFERED(self))
923 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000924 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000925 }
926 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000927 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200928 if (res != Py_None)
929 return res;
930 Py_DECREF(res);
931 if (!ENTER_BUFFERED(self))
932 return NULL;
933 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000934 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000935
Antoine Pitroue05565e2011-08-20 14:39:23 +0200936 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000937 return res;
938}
939
940static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000941buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942{
943 Py_ssize_t n, have, r;
944 PyObject *res = NULL;
945
946 CHECK_INITIALIZED(self)
947 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
948 return NULL;
949 }
950
951 if (n < 0) {
952 PyErr_SetString(PyExc_ValueError,
953 "read length must be positive");
954 return NULL;
955 }
956 if (n == 0)
957 return PyBytes_FromStringAndSize(NULL, 0);
958
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 /* Return up to n bytes. If at least one byte is buffered, we
960 only return buffered bytes. Otherwise, we do one raw read. */
961
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
963 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100964 n = Py_MIN(have, n);
965 res = _bufferedreader_read_fast(self, n);
966 assert(res != Py_None);
967 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100969 res = PyBytes_FromStringAndSize(NULL, n);
970 if (res == NULL)
971 return NULL;
972 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200973 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100974 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200975 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000976 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100977 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
978 LEAVE_BUFFERED(self)
979 if (r == -1) {
980 Py_DECREF(res);
981 return NULL;
982 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983 if (r == -2)
984 r = 0;
985 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100986 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987 return res;
988}
989
990static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000991buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200993 Py_buffer buf;
994 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995 PyObject *res = NULL;
996
997 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200998
999 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
1000 return NULL;
1001
1002 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1003 if (n > 0) {
1004 if (n >= buf.len) {
1005 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1006 self->pos += buf.len;
1007 res = PyLong_FromSsize_t(buf.len);
1008 goto end_unlocked;
1009 }
1010 memcpy(buf.buf, self->buffer + self->pos, n);
1011 self->pos += n;
1012 written = n;
1013 }
1014
1015 if (!ENTER_BUFFERED(self))
1016 goto end_unlocked;
1017
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001019 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001020 if (res == NULL)
1021 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001023 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001024
1025 _bufferedreader_reset_buf(self);
1026 self->pos = 0;
1027
1028 for (remaining = buf.len - written;
1029 remaining > 0;
1030 written += n, remaining -= n) {
1031 /* If remaining bytes is larger than internal buffer size, copy
1032 * directly into caller's buffer. */
1033 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001034 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1035 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001036 }
1037 else {
1038 n = _bufferedreader_fill_buffer(self);
1039 if (n > 0) {
1040 if (n > remaining)
1041 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001042 memcpy((char *) buf.buf + written,
1043 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001044 self->pos += n;
1045 continue; /* short circuit */
1046 }
1047 }
1048 if (n == 0 || (n == -2 && written > 0))
1049 break;
1050 if (n < 0) {
1051 if (n == -2) {
1052 Py_INCREF(Py_None);
1053 res = Py_None;
1054 }
1055 goto end;
1056 }
1057 }
1058 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001059
1060end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001061 LEAVE_BUFFERED(self);
1062end_unlocked:
1063 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001064 return res;
1065}
1066
1067static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001068_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001069{
1070 PyObject *res = NULL;
1071 PyObject *chunks = NULL;
1072 Py_ssize_t n, written = 0;
1073 const char *start, *s, *end;
1074
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001075 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001076
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001077 /* First, try to find a line in the buffer. This can run unlocked because
1078 the calls to the C API are simple enough that they can't trigger
1079 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001080 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1081 if (limit >= 0 && n > limit)
1082 n = limit;
1083 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001084 s = memchr(start, '\n', n);
1085 if (s != NULL) {
1086 res = PyBytes_FromStringAndSize(start, s - start + 1);
1087 if (res != NULL)
1088 self->pos += s - start + 1;
1089 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 }
1091 if (n == limit) {
1092 res = PyBytes_FromStringAndSize(start, n);
1093 if (res != NULL)
1094 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001095 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001096 }
1097
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001098 if (!ENTER_BUFFERED(self))
1099 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001100
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102 chunks = PyList_New(0);
1103 if (chunks == NULL)
1104 goto end;
1105 if (n > 0) {
1106 res = PyBytes_FromStringAndSize(start, n);
1107 if (res == NULL)
1108 goto end;
1109 if (PyList_Append(chunks, res) < 0) {
1110 Py_CLEAR(res);
1111 goto end;
1112 }
1113 Py_CLEAR(res);
1114 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001115 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001116 if (limit >= 0)
1117 limit -= n;
1118 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001119 if (self->writable) {
1120 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1121 if (r == NULL)
1122 goto end;
1123 Py_DECREF(r);
1124 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001125
1126 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001127 _bufferedreader_reset_buf(self);
1128 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001129 if (n == -1)
1130 goto end;
1131 if (n <= 0)
1132 break;
1133 if (limit >= 0 && n > limit)
1134 n = limit;
1135 start = self->buffer;
1136 end = start + n;
1137 s = start;
1138 while (s < end) {
1139 if (*s++ == '\n') {
1140 res = PyBytes_FromStringAndSize(start, s - start);
1141 if (res == NULL)
1142 goto end;
1143 self->pos = s - start;
1144 goto found;
1145 }
1146 }
1147 res = PyBytes_FromStringAndSize(start, n);
1148 if (res == NULL)
1149 goto end;
1150 if (n == limit) {
1151 self->pos = n;
1152 break;
1153 }
1154 if (PyList_Append(chunks, res) < 0) {
1155 Py_CLEAR(res);
1156 goto end;
1157 }
1158 Py_CLEAR(res);
1159 written += n;
1160 if (limit >= 0)
1161 limit -= n;
1162 }
1163found:
1164 if (res != NULL && PyList_Append(chunks, res) < 0) {
1165 Py_CLEAR(res);
1166 goto end;
1167 }
1168 Py_CLEAR(res);
1169 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1170
1171end:
1172 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001173end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 Py_XDECREF(chunks);
1175 return res;
1176}
1177
1178static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001179buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001180{
1181 Py_ssize_t limit = -1;
1182
1183 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001184 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001186 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001187}
1188
1189
1190static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001191buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192{
1193 Py_off_t pos;
1194
1195 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001196 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197 if (pos == -1)
1198 return NULL;
1199 pos -= RAW_OFFSET(self);
1200 /* TODO: sanity check (pos >= 0) */
1201 return PyLong_FromOff_t(pos);
1202}
1203
1204static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001205buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206{
1207 Py_off_t target, n;
1208 int whence = 0;
1209 PyObject *targetobj, *res = NULL;
1210
1211 CHECK_INITIALIZED(self)
1212 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1213 return NULL;
1214 }
Jesus Cea94363612012-06-22 18:32:07 +02001215
1216 /* Do some error checking instead of trusting OS 'seek()'
1217 ** error detection, just in case.
1218 */
1219 if ((whence < 0 || whence >2)
1220#ifdef SEEK_HOLE
1221 && (whence != SEEK_HOLE)
1222#endif
1223#ifdef SEEK_DATA
1224 && (whence != SEEK_DATA)
1225#endif
1226 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001228 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001229 return NULL;
1230 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001231
1232 CHECK_CLOSED(self, "seek of closed file")
1233
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001234 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1235 return NULL;
1236
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001237 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1238 if (target == -1 && PyErr_Occurred())
1239 return NULL;
1240
Jesus Cea94363612012-06-22 18:32:07 +02001241 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1242 buffer. Other whence values must be managed without this optimization.
1243 Some Operating Systems can provide additional values, like
1244 SEEK_HOLE/SEEK_DATA. */
1245 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 Py_off_t current, avail;
1247 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001248 so as to return quickly if possible. Also, we needn't take the
1249 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001251 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1252 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001253 current = RAW_TELL(self);
1254 avail = READAHEAD(self);
1255 if (avail > 0) {
1256 Py_off_t offset;
1257 if (whence == 0)
1258 offset = target - (current - RAW_OFFSET(self));
1259 else
1260 offset = target;
1261 if (offset >= -self->pos && offset <= avail) {
1262 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001263 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 }
1265 }
1266 }
1267
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001268 if (!ENTER_BUFFERED(self))
1269 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001270
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001271 /* Fallback: invoke raw seek() method and clear buffer */
1272 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001273 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 if (res == NULL)
1275 goto end;
1276 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001277 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278 }
1279
1280 /* TODO: align on block boundary and read buffer if needed? */
1281 if (whence == 1)
1282 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001283 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001284 if (n == -1)
1285 goto end;
1286 self->raw_pos = -1;
1287 res = PyLong_FromOff_t(n);
1288 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001289 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290
1291end:
1292 LEAVE_BUFFERED(self)
1293 return res;
1294}
1295
1296static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001297buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298{
1299 PyObject *pos = Py_None;
1300 PyObject *res = NULL;
1301
1302 CHECK_INITIALIZED(self)
1303 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1304 return NULL;
1305 }
1306
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001307 if (!ENTER_BUFFERED(self))
1308 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001309
1310 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001311 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001312 if (res == NULL)
1313 goto end;
1314 Py_CLEAR(res);
1315 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001316 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1317 if (res == NULL)
1318 goto end;
1319 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001320 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321 PyErr_Clear();
1322
1323end:
1324 LEAVE_BUFFERED(self)
1325 return res;
1326}
1327
1328static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001329buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330{
1331 PyObject *line;
1332 PyTypeObject *tp;
1333
1334 CHECK_INITIALIZED(self);
1335
1336 tp = Py_TYPE(self);
1337 if (tp == &PyBufferedReader_Type ||
1338 tp == &PyBufferedRandom_Type) {
1339 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001340 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341 }
1342 else {
1343 line = PyObject_CallMethodObjArgs((PyObject *)self,
1344 _PyIO_str_readline, NULL);
1345 if (line && !PyBytes_Check(line)) {
1346 PyErr_Format(PyExc_IOError,
1347 "readline() should have returned a bytes object, "
1348 "not '%.200s'", Py_TYPE(line)->tp_name);
1349 Py_DECREF(line);
1350 return NULL;
1351 }
1352 }
1353
1354 if (line == NULL)
1355 return NULL;
1356
1357 if (PyBytes_GET_SIZE(line) == 0) {
1358 /* Reached EOF or would have blocked */
1359 Py_DECREF(line);
1360 return NULL;
1361 }
1362
1363 return line;
1364}
1365
Antoine Pitrou716c4442009-05-23 19:04:03 +00001366static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001367buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001368{
1369 PyObject *nameobj, *res;
1370
Martin v. Löwis767046a2011-10-14 15:35:36 +02001371 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001372 if (nameobj == NULL) {
1373 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1374 PyErr_Clear();
1375 else
1376 return NULL;
1377 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1378 }
1379 else {
1380 res = PyUnicode_FromFormat("<%s name=%R>",
1381 Py_TYPE(self)->tp_name, nameobj);
1382 Py_DECREF(nameobj);
1383 }
1384 return res;
1385}
1386
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001387/*
1388 * class BufferedReader
1389 */
1390
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001391PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001392 "Create a new buffered reader using the given readable raw IO object.");
1393
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001394static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001395{
1396 self->read_end = -1;
1397}
1398
1399static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001400bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001401{
1402 char *kwlist[] = {"raw", "buffer_size", NULL};
1403 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1404 PyObject *raw;
1405
1406 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001407 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001408
1409 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1410 &raw, &buffer_size)) {
1411 return -1;
1412 }
1413
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001414 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001415 return -1;
1416
1417 Py_CLEAR(self->raw);
1418 Py_INCREF(raw);
1419 self->raw = raw;
1420 self->buffer_size = buffer_size;
1421 self->readable = 1;
1422 self->writable = 0;
1423
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001424 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001425 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001426 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001427
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001428 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1429 Py_TYPE(raw) == &PyFileIO_Type);
1430
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001431 self->ok = 1;
1432 return 0;
1433}
1434
1435static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001436_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437{
1438 Py_buffer buf;
1439 PyObject *memobj, *res;
1440 Py_ssize_t n;
1441 /* NOTE: the buffer needn't be released as its object is NULL. */
1442 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1443 return -1;
1444 memobj = PyMemoryView_FromBuffer(&buf);
1445 if (memobj == NULL)
1446 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001447 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1448 occurs so we needn't do it ourselves.
1449 We then retry reading, ignoring the signal if no handler has
1450 raised (see issue #10956).
1451 */
1452 do {
1453 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001454 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001455 Py_DECREF(memobj);
1456 if (res == NULL)
1457 return -1;
1458 if (res == Py_None) {
1459 /* Non-blocking stream would have blocked. Special return code! */
1460 Py_DECREF(res);
1461 return -2;
1462 }
1463 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1464 Py_DECREF(res);
1465 if (n < 0 || n > len) {
1466 PyErr_Format(PyExc_IOError,
1467 "raw readinto() returned invalid length %zd "
1468 "(should have been between 0 and %zd)", n, len);
1469 return -1;
1470 }
1471 if (n > 0 && self->abs_pos != -1)
1472 self->abs_pos += n;
1473 return n;
1474}
1475
1476static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001477_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001478{
1479 Py_ssize_t start, len, n;
1480 if (VALID_READ_BUFFER(self))
1481 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1482 else
1483 start = 0;
1484 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001485 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001486 if (n <= 0)
1487 return n;
1488 self->read_end = start + n;
1489 self->raw_pos = start + n;
1490 return n;
1491}
1492
1493static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001494_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001495{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001496 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001497 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001498
1499 /* First copy what we have in the current buffer. */
1500 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1501 if (current_size) {
1502 data = PyBytes_FromStringAndSize(
1503 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001504 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001505 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001506 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001507 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001508 /* We're going past the buffer's bounds, flush it */
1509 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001510 tmp = buffered_flush_and_rewind_unlocked(self);
1511 if (tmp == NULL)
1512 goto cleanup;
1513 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001514 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001515 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001516
1517 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001518 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1519 if (tmp == NULL)
1520 goto cleanup;
1521 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001522 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001523 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001524 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001525 if (tmp == Py_None) {
1526 if (current_size == 0) {
1527 res = Py_None;
1528 goto cleanup;
1529 } else {
1530 res = data;
1531 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001532 }
1533 }
1534 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001535 PyBytes_Concat(&data, tmp);
1536 res = data;
1537 goto cleanup;
1538 }
1539 else {
1540 res = tmp;
1541 goto cleanup;
1542 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001543 }
1544
1545 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001546 if (chunks == NULL)
1547 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001548
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001549 while (1) {
1550 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001551 if (PyList_Append(chunks, data) < 0)
1552 goto cleanup;
1553 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001554 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001555
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001556 /* Read until EOF or until read() would block. */
1557 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001558 if (data == NULL)
1559 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001560 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001561 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001562 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001563 }
1564 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1565 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001566 res = data;
1567 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001568 }
1569 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001570 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1571 res = tmp;
1572 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001573 }
1574 }
1575 current_size += PyBytes_GET_SIZE(data);
1576 if (self->abs_pos != -1)
1577 self->abs_pos += PyBytes_GET_SIZE(data);
1578 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001579cleanup:
1580 /* res is either NULL or a borrowed ref */
1581 Py_XINCREF(res);
1582 Py_XDECREF(data);
1583 Py_XDECREF(tmp);
1584 Py_XDECREF(chunks);
1585 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586}
1587
1588/* Read n bytes from the buffer if it can, otherwise return None.
1589 This function is simple enough that it can run unlocked. */
1590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001591_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001592{
1593 Py_ssize_t current_size;
1594
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001595 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1596 if (n <= current_size) {
1597 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001598 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1599 if (res != NULL)
1600 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001601 return res;
1602 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001603 Py_RETURN_NONE;
1604}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001605
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001606/* Generic read function: read from the stream until enough bytes are read,
1607 * or until an EOF occurs or until read() would block.
1608 */
1609static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001610_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611{
1612 PyObject *res = NULL;
1613 Py_ssize_t current_size, remaining, written;
1614 char *out;
1615
1616 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1617 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001618 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001619
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620 res = PyBytes_FromStringAndSize(NULL, n);
1621 if (res == NULL)
1622 goto error;
1623 out = PyBytes_AS_STRING(res);
1624 remaining = n;
1625 written = 0;
1626 if (current_size > 0) {
1627 memcpy(out, self->buffer + self->pos, current_size);
1628 remaining -= current_size;
1629 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001630 self->pos += current_size;
1631 }
1632 /* Flush the write buffer if necessary */
1633 if (self->writable) {
1634 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1635 if (r == NULL)
1636 goto error;
1637 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001638 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001639 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001640 while (remaining > 0) {
1641 /* We want to read a whole block at the end into buffer.
1642 If we had readv() we could do this in one pass. */
1643 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1644 if (r == 0)
1645 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001646 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001647 if (r == -1)
1648 goto error;
1649 if (r == 0 || r == -2) {
1650 /* EOF occurred or read() would block. */
1651 if (r == 0 || written > 0) {
1652 if (_PyBytes_Resize(&res, written))
1653 goto error;
1654 return res;
1655 }
1656 Py_DECREF(res);
1657 Py_INCREF(Py_None);
1658 return Py_None;
1659 }
1660 remaining -= r;
1661 written += r;
1662 }
1663 assert(remaining <= self->buffer_size);
1664 self->pos = 0;
1665 self->raw_pos = 0;
1666 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001667 /* NOTE: when the read is satisfied, we avoid issuing any additional
1668 reads, which could block indefinitely (e.g. on a socket).
1669 See issue #9550. */
1670 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001671 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001672 if (r == -1)
1673 goto error;
1674 if (r == 0 || r == -2) {
1675 /* EOF occurred or read() would block. */
1676 if (r == 0 || written > 0) {
1677 if (_PyBytes_Resize(&res, written))
1678 goto error;
1679 return res;
1680 }
1681 Py_DECREF(res);
1682 Py_INCREF(Py_None);
1683 return Py_None;
1684 }
1685 if (remaining > r) {
1686 memcpy(out + written, self->buffer + self->pos, r);
1687 written += r;
1688 self->pos += r;
1689 remaining -= r;
1690 }
1691 else if (remaining > 0) {
1692 memcpy(out + written, self->buffer + self->pos, remaining);
1693 written += remaining;
1694 self->pos += remaining;
1695 remaining = 0;
1696 }
1697 if (remaining == 0)
1698 break;
1699 }
1700
1701 return res;
1702
1703error:
1704 Py_XDECREF(res);
1705 return NULL;
1706}
1707
1708static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001709_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001710{
1711 Py_ssize_t have, r;
1712
1713 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1714 /* Constraints:
1715 1. we don't want to advance the file position.
1716 2. we don't want to lose block alignment, so we can't shift the buffer
1717 to make some place.
1718 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1719 */
1720 if (have > 0) {
1721 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1722 }
1723
1724 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001725 _bufferedreader_reset_buf(self);
1726 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001727 if (r == -1)
1728 return NULL;
1729 if (r == -2)
1730 r = 0;
1731 self->pos = 0;
1732 return PyBytes_FromStringAndSize(self->buffer, r);
1733}
1734
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001736 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001737 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1738 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1739 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1740 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1741 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1742 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1743 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1744 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001745 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001746 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001747
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001748 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1749 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1750 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001751 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001752 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1753 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1754 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1755 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001756 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757 {NULL, NULL}
1758};
1759
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001760static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001761 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001762 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763 {NULL}
1764};
1765
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001766static PyGetSetDef bufferedreader_getset[] = {
1767 {"closed", (getter)buffered_closed_get, NULL, NULL},
1768 {"name", (getter)buffered_name_get, NULL, NULL},
1769 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001770 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001771};
1772
1773
1774PyTypeObject PyBufferedReader_Type = {
1775 PyVarObject_HEAD_INIT(NULL, 0)
1776 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001777 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001779 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 0, /*tp_print*/
1781 0, /*tp_getattr*/
1782 0, /*tp_setattr*/
1783 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 0, /*tp_as_number*/
1786 0, /*tp_as_sequence*/
1787 0, /*tp_as_mapping*/
1788 0, /*tp_hash */
1789 0, /*tp_call*/
1790 0, /*tp_str*/
1791 0, /*tp_getattro*/
1792 0, /*tp_setattro*/
1793 0, /*tp_as_buffer*/
1794 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001795 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001796 bufferedreader_doc, /* tp_doc */
1797 (traverseproc)buffered_traverse, /* tp_traverse */
1798 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001802 (iternextfunc)buffered_iternext, /* tp_iternext */
1803 bufferedreader_methods, /* tp_methods */
1804 bufferedreader_members, /* tp_members */
1805 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 0, /* tp_base */
1807 0, /* tp_dict */
1808 0, /* tp_descr_get */
1809 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001810 offsetof(buffered, dict), /* tp_dictoffset */
1811 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812 0, /* tp_alloc */
1813 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001814 0, /* tp_free */
1815 0, /* tp_is_gc */
1816 0, /* tp_bases */
1817 0, /* tp_mro */
1818 0, /* tp_cache */
1819 0, /* tp_subclasses */
1820 0, /* tp_weaklist */
1821 0, /* tp_del */
1822 0, /* tp_version_tag */
1823 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001824};
1825
1826
Benjamin Peterson59406a92009-03-26 17:10:29 +00001827
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828/*
1829 * class BufferedWriter
1830 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001831PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832 "A buffer for a writeable sequential RawIO object.\n"
1833 "\n"
1834 "The constructor creates a BufferedWriter for the given writeable raw\n"
1835 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001836 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001837 );
1838
1839static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001840_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841{
1842 self->write_pos = 0;
1843 self->write_end = -1;
1844}
1845
1846static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001847bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848{
Florent Xicluna109d5732012-07-07 17:03:22 +02001849 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001850 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 PyObject *raw;
1852
1853 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001854 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001855
R David Murray9f10f562013-02-23 22:07:55 -05001856 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001857 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858 return -1;
1859 }
1860
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001861 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862 return -1;
1863
1864 Py_CLEAR(self->raw);
1865 Py_INCREF(raw);
1866 self->raw = raw;
1867 self->readable = 0;
1868 self->writable = 1;
1869
1870 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001871 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001873 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001874 self->pos = 0;
1875
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001876 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1877 Py_TYPE(raw) == &PyFileIO_Type);
1878
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001879 self->ok = 1;
1880 return 0;
1881}
1882
1883static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001884_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885{
1886 Py_buffer buf;
1887 PyObject *memobj, *res;
1888 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001889 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001890 /* NOTE: the buffer needn't be released as its object is NULL. */
1891 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1892 return -1;
1893 memobj = PyMemoryView_FromBuffer(&buf);
1894 if (memobj == NULL)
1895 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001896 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1897 occurs so we needn't do it ourselves.
1898 We then retry writing, ignoring the signal if no handler has
1899 raised (see issue #10956).
1900 */
1901 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001902 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001903 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001904 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001905 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906 Py_DECREF(memobj);
1907 if (res == NULL)
1908 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001909 if (res == Py_None) {
1910 /* Non-blocking stream would have blocked. Special return code!
1911 Being paranoid we reset errno in case it is changed by code
1912 triggered by a decref. errno is used by _set_BlockingIOError(). */
1913 Py_DECREF(res);
1914 errno = errnum;
1915 return -2;
1916 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001917 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1918 Py_DECREF(res);
1919 if (n < 0 || n > len) {
1920 PyErr_Format(PyExc_IOError,
1921 "raw write() returned invalid length %zd "
1922 "(should have been between 0 and %zd)", n, len);
1923 return -1;
1924 }
1925 if (n > 0 && self->abs_pos != -1)
1926 self->abs_pos += n;
1927 return n;
1928}
1929
1930/* `restore_pos` is 1 if we need to restore the raw stream position at
1931 the end, 0 otherwise. */
1932static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001933_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934{
1935 Py_ssize_t written = 0;
1936 Py_off_t n, rewind;
1937
1938 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1939 goto end;
1940 /* First, rewind */
1941 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1942 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001943 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 if (n < 0) {
1945 goto error;
1946 }
1947 self->raw_pos -= rewind;
1948 }
1949 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001950 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951 self->buffer + self->write_pos,
1952 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1953 Py_off_t, Py_ssize_t));
1954 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001955 goto error;
1956 }
1957 else if (n == -2) {
1958 _set_BlockingIOError("write could not complete without blocking",
1959 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001960 goto error;
1961 }
1962 self->write_pos += n;
1963 self->raw_pos = self->write_pos;
1964 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001965 /* Partial writes can return successfully when interrupted by a
1966 signal (see write(2)). We must run signal handlers before
1967 blocking another time, possibly indefinitely. */
1968 if (PyErr_CheckSignals() < 0)
1969 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 }
1971
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001972 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973
1974end:
1975 Py_RETURN_NONE;
1976
1977error:
1978 return NULL;
1979}
1980
1981static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001982bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983{
1984 PyObject *res = NULL;
1985 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001986 Py_ssize_t written, avail, remaining;
1987 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988
1989 CHECK_INITIALIZED(self)
1990 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1991 return NULL;
1992 }
1993
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001994 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001995 PyErr_SetString(PyExc_ValueError, "write to closed file");
1996 PyBuffer_Release(&buf);
1997 return NULL;
1998 }
1999
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00002000 if (!ENTER_BUFFERED(self)) {
2001 PyBuffer_Release(&buf);
2002 return NULL;
2003 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004
2005 /* Fast path: the data to write can be fully buffered. */
2006 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2007 self->pos = 0;
2008 self->raw_pos = 0;
2009 }
2010 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2011 if (buf.len <= avail) {
2012 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002013 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 self->write_pos = self->pos;
2015 }
2016 ADJUST_POSITION(self, self->pos + buf.len);
2017 if (self->pos > self->write_end)
2018 self->write_end = self->pos;
2019 written = buf.len;
2020 goto end;
2021 }
2022
2023 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002024 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002026 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002027 if (w == NULL)
2028 goto error;
2029 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002030 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002031 /* Make some place by shifting the buffer. */
2032 assert(VALID_WRITE_BUFFER(self));
2033 memmove(self->buffer, self->buffer + self->write_pos,
2034 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2035 Py_off_t, Py_ssize_t));
2036 self->write_end -= self->write_pos;
2037 self->raw_pos -= self->write_pos;
2038 self->pos -= self->write_pos;
2039 self->write_pos = 0;
2040 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2041 Py_off_t, Py_ssize_t);
2042 if (buf.len <= avail) {
2043 /* Everything can be buffered */
2044 PyErr_Clear();
2045 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2046 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002047 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048 written = buf.len;
2049 goto end;
2050 }
2051 /* Buffer as much as possible. */
2052 memcpy(self->buffer + self->write_end, buf.buf, avail);
2053 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002054 self->pos += avail;
2055 /* XXX Modifying the existing exception e using the pointer w
2056 will change e.characters_written but not e.args[2].
2057 Therefore we just replace with a new error. */
2058 _set_BlockingIOError("write could not complete without blocking",
2059 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060 goto error;
2061 }
2062 Py_CLEAR(res);
2063
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002064 /* Adjust the raw stream position if it is away from the logical stream
2065 position. This happens if the read buffer has been filled but not
2066 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2067 the raw stream by itself).
2068 Fixes issue #6629.
2069 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002070 offset = RAW_OFFSET(self);
2071 if (offset != 0) {
2072 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002073 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002074 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002075 }
2076
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002077 /* Then write buf itself. At this point the buffer has been emptied. */
2078 remaining = buf.len;
2079 written = 0;
2080 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002081 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002082 self, (char *) buf.buf + written, buf.len - written);
2083 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002084 goto error;
2085 } else if (n == -2) {
2086 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002087 if (remaining > self->buffer_size) {
2088 /* Can't buffer everything, still buffer as much as possible */
2089 memcpy(self->buffer,
2090 (char *) buf.buf + written, self->buffer_size);
2091 self->raw_pos = 0;
2092 ADJUST_POSITION(self, self->buffer_size);
2093 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002094 written += self->buffer_size;
2095 _set_BlockingIOError("write could not complete without "
2096 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097 goto error;
2098 }
2099 PyErr_Clear();
2100 break;
2101 }
2102 written += n;
2103 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002104 /* Partial writes can return successfully when interrupted by a
2105 signal (see write(2)). We must run signal handlers before
2106 blocking another time, possibly indefinitely. */
2107 if (PyErr_CheckSignals() < 0)
2108 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 }
2110 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002111 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002112 if (remaining > 0) {
2113 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2114 written += remaining;
2115 }
2116 self->write_pos = 0;
2117 /* TODO: sanity check (remaining >= 0) */
2118 self->write_end = remaining;
2119 ADJUST_POSITION(self, remaining);
2120 self->raw_pos = 0;
2121
2122end:
2123 res = PyLong_FromSsize_t(written);
2124
2125error:
2126 LEAVE_BUFFERED(self)
2127 PyBuffer_Release(&buf);
2128 return res;
2129}
2130
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002132 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002133 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2134 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2135 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2136 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2137 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2138 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2139 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002140 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002141 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002142
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002143 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2144 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2145 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2146 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2147 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002148 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149 {NULL, NULL}
2150};
2151
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002152static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002153 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002154 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155 {NULL}
2156};
2157
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002158static PyGetSetDef bufferedwriter_getset[] = {
2159 {"closed", (getter)buffered_closed_get, NULL, NULL},
2160 {"name", (getter)buffered_name_get, NULL, NULL},
2161 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002162 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002163};
2164
2165
2166PyTypeObject PyBufferedWriter_Type = {
2167 PyVarObject_HEAD_INIT(NULL, 0)
2168 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002169 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002171 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172 0, /*tp_print*/
2173 0, /*tp_getattr*/
2174 0, /*tp_setattr*/
2175 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002176 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177 0, /*tp_as_number*/
2178 0, /*tp_as_sequence*/
2179 0, /*tp_as_mapping*/
2180 0, /*tp_hash */
2181 0, /*tp_call*/
2182 0, /*tp_str*/
2183 0, /*tp_getattro*/
2184 0, /*tp_setattro*/
2185 0, /*tp_as_buffer*/
2186 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002187 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002188 bufferedwriter_doc, /* tp_doc */
2189 (traverseproc)buffered_traverse, /* tp_traverse */
2190 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193 0, /* tp_iter */
2194 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002195 bufferedwriter_methods, /* tp_methods */
2196 bufferedwriter_members, /* tp_members */
2197 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002198 0, /* tp_base */
2199 0, /* tp_dict */
2200 0, /* tp_descr_get */
2201 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002202 offsetof(buffered, dict), /* tp_dictoffset */
2203 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002204 0, /* tp_alloc */
2205 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002206 0, /* tp_free */
2207 0, /* tp_is_gc */
2208 0, /* tp_bases */
2209 0, /* tp_mro */
2210 0, /* tp_cache */
2211 0, /* tp_subclasses */
2212 0, /* tp_weaklist */
2213 0, /* tp_del */
2214 0, /* tp_version_tag */
2215 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216};
2217
2218
2219
2220/*
2221 * BufferedRWPair
2222 */
2223
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225 "A buffered reader and writer object together.\n"
2226 "\n"
2227 "A buffered reader object and buffered writer object put together to\n"
2228 "form a sequential IO object that can read and write. This is typically\n"
2229 "used with a socket or two-way pipe.\n"
2230 "\n"
2231 "reader and writer are RawIOBase objects that are readable and\n"
2232 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002233 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234 );
2235
2236/* XXX The usefulness of this (compared to having two separate IO objects) is
2237 * questionable.
2238 */
2239
2240typedef struct {
2241 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002242 buffered *reader;
2243 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244 PyObject *dict;
2245 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002246} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002247
2248static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002249bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250{
2251 PyObject *reader, *writer;
2252 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002253
Florent Xicluna109d5732012-07-07 17:03:22 +02002254 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2255 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002256 return -1;
2257 }
2258
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002261 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262 return -1;
2263
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002264 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002265 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 if (self->reader == NULL)
2267 return -1;
2268
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002269 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002270 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271 if (self->writer == NULL) {
2272 Py_CLEAR(self->reader);
2273 return -1;
2274 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002275
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276 return 0;
2277}
2278
2279static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002280bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281{
2282 Py_VISIT(self->dict);
2283 return 0;
2284}
2285
2286static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002287bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002288{
2289 Py_CLEAR(self->reader);
2290 Py_CLEAR(self->writer);
2291 Py_CLEAR(self->dict);
2292 return 0;
2293}
2294
2295static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002296bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297{
2298 _PyObject_GC_UNTRACK(self);
2299 Py_CLEAR(self->reader);
2300 Py_CLEAR(self->writer);
2301 Py_CLEAR(self->dict);
2302 Py_TYPE(self)->tp_free((PyObject *) self);
2303}
2304
2305static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002306_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002308 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002309 PyObject *ret;
2310
2311 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002312 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313 return NULL;
2314 }
2315
2316 ret = PyObject_CallObject(func, args);
2317 Py_DECREF(func);
2318 return ret;
2319}
2320
2321static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002322bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002324 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002325}
2326
2327static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002328bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002330 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331}
2332
2333static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002334bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002335{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002336 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002337}
2338
2339static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002340bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002341{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002342 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002343}
2344
2345static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002346bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002348 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002349}
2350
2351static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002352bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002353{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002354 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355}
2356
2357static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002358bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002359{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002360 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361}
2362
2363static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002364bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002365{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002366 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002367}
2368
2369static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002370bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002372 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002373 if (ret == NULL)
2374 return NULL;
2375 Py_DECREF(ret);
2376
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002377 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002378}
2379
2380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002381bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002382{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002383 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002384
2385 if (ret != Py_False) {
2386 /* either True or exception */
2387 return ret;
2388 }
2389 Py_DECREF(ret);
2390
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002391 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002392}
2393
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002394static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002395bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002396{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002397 if (self->writer == NULL) {
2398 PyErr_SetString(PyExc_RuntimeError,
2399 "the BufferedRWPair object is being garbage-collected");
2400 return NULL;
2401 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002402 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2403}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002404
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002405static PyMethodDef bufferedrwpair_methods[] = {
2406 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2407 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2408 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2409 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002410
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002411 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2412 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002413
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002414 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2415 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002416
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002417 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2418 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002419
Antoine Pitrou243757e2010-11-05 21:15:39 +00002420 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2421
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002422 {NULL, NULL}
2423};
2424
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002425static PyGetSetDef bufferedrwpair_getset[] = {
2426 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002427 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002428};
2429
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430PyTypeObject PyBufferedRWPair_Type = {
2431 PyVarObject_HEAD_INIT(NULL, 0)
2432 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002433 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002434 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002435 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436 0, /*tp_print*/
2437 0, /*tp_getattr*/
2438 0, /*tp_setattr*/
2439 0, /*tp_compare */
2440 0, /*tp_repr*/
2441 0, /*tp_as_number*/
2442 0, /*tp_as_sequence*/
2443 0, /*tp_as_mapping*/
2444 0, /*tp_hash */
2445 0, /*tp_call*/
2446 0, /*tp_str*/
2447 0, /*tp_getattro*/
2448 0, /*tp_setattro*/
2449 0, /*tp_as_buffer*/
2450 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002451 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002452 bufferedrwpair_doc, /* tp_doc */
2453 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2454 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002455 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002456 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002457 0, /* tp_iter */
2458 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002460 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002461 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002462 0, /* tp_base */
2463 0, /* tp_dict */
2464 0, /* tp_descr_get */
2465 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002466 offsetof(rwpair, dict), /* tp_dictoffset */
2467 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002468 0, /* tp_alloc */
2469 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002470 0, /* tp_free */
2471 0, /* tp_is_gc */
2472 0, /* tp_bases */
2473 0, /* tp_mro */
2474 0, /* tp_cache */
2475 0, /* tp_subclasses */
2476 0, /* tp_weaklist */
2477 0, /* tp_del */
2478 0, /* tp_version_tag */
2479 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002480};
2481
2482
2483
2484/*
2485 * BufferedRandom
2486 */
2487
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002488PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002489 "A buffered interface to random access streams.\n"
2490 "\n"
2491 "The constructor creates a reader and writer for a seekable stream,\n"
2492 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002493 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494 );
2495
2496static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002497bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002498{
Florent Xicluna109d5732012-07-07 17:03:22 +02002499 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002501 PyObject *raw;
2502
2503 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002504 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002505
R David Murray9f10f562013-02-23 22:07:55 -05002506 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002507 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002508 return -1;
2509 }
2510
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002511 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002512 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002513 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002514 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002515 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002516 return -1;
2517
2518 Py_CLEAR(self->raw);
2519 Py_INCREF(raw);
2520 self->raw = raw;
2521 self->buffer_size = buffer_size;
2522 self->readable = 1;
2523 self->writable = 1;
2524
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002525 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002526 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002527 _bufferedreader_reset_buf(self);
2528 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002529 self->pos = 0;
2530
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002531 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2532 Py_TYPE(raw) == &PyFileIO_Type);
2533
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002534 self->ok = 1;
2535 return 0;
2536}
2537
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002538static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002539 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002540 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2541 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2542 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2543 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2544 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2545 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2546 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002547 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002548 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002549
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002550 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002551
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002552 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2553 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2554 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2555 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2556 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2557 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2558 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2559 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2560 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002561 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002562 {NULL, NULL}
2563};
2564
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002565static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002566 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002567 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002568 {NULL}
2569};
2570
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002571static PyGetSetDef bufferedrandom_getset[] = {
2572 {"closed", (getter)buffered_closed_get, NULL, NULL},
2573 {"name", (getter)buffered_name_get, NULL, NULL},
2574 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002575 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002576};
2577
2578
2579PyTypeObject PyBufferedRandom_Type = {
2580 PyVarObject_HEAD_INIT(NULL, 0)
2581 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002582 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002583 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002584 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585 0, /*tp_print*/
2586 0, /*tp_getattr*/
2587 0, /*tp_setattr*/
2588 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002589 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002590 0, /*tp_as_number*/
2591 0, /*tp_as_sequence*/
2592 0, /*tp_as_mapping*/
2593 0, /*tp_hash */
2594 0, /*tp_call*/
2595 0, /*tp_str*/
2596 0, /*tp_getattro*/
2597 0, /*tp_setattro*/
2598 0, /*tp_as_buffer*/
2599 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002600 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601 bufferedrandom_doc, /* tp_doc */
2602 (traverseproc)buffered_traverse, /* tp_traverse */
2603 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002604 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002605 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002606 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002607 (iternextfunc)buffered_iternext, /* tp_iternext */
2608 bufferedrandom_methods, /* tp_methods */
2609 bufferedrandom_members, /* tp_members */
2610 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002611 0, /* tp_base */
2612 0, /*tp_dict*/
2613 0, /* tp_descr_get */
2614 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002615 offsetof(buffered, dict), /*tp_dictoffset*/
2616 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002617 0, /* tp_alloc */
2618 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002619 0, /* tp_free */
2620 0, /* tp_is_gc */
2621 0, /* tp_bases */
2622 0, /* tp_mro */
2623 0, /* tp_cache */
2624 0, /* tp_subclasses */
2625 0, /* tp_weaklist */
2626 0, /* tp_del */
2627 0, /* tp_version_tag */
2628 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629};