blob: d0e92e5f7f129f9fcb4520e965701eb8ba25589e [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;
Serhiy Storchaka8a8f7f92014-06-09 09:13:04 +0300552 PyErr_NormalizeException(&exc, &val, &tb);
Benjamin Peterson68623612012-12-20 11:53:11 -0600553 Py_DECREF(exc);
554 Py_XDECREF(tb);
555 PyErr_Fetch(&exc, &val2, &tb);
556 PyErr_NormalizeException(&exc, &val2, &tb);
557 PyException_SetContext(val2, val);
558 PyErr_Restore(exc, val2, tb);
559 }
560 }
561
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562end:
563 LEAVE_BUFFERED(self)
564 return res;
565}
566
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000567/* detach */
568
569static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000570buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000571{
572 PyObject *raw, *res;
573 CHECK_INITIALIZED(self)
574 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
575 if (res == NULL)
576 return NULL;
577 Py_DECREF(res);
578 raw = self->raw;
579 self->raw = NULL;
580 self->detached = 1;
581 self->ok = 0;
582 return raw;
583}
584
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585/* Inquiries */
586
587static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589{
590 CHECK_INITIALIZED(self)
591 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
592}
593
594static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000595buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000596{
597 CHECK_INITIALIZED(self)
598 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
599}
600
601static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000602buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000603{
604 CHECK_INITIALIZED(self)
605 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
606}
607
608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000610{
611 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200612 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000613}
614
615static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000616buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617{
618 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200619 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620}
621
622/* Lower-level APIs */
623
624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000626{
627 CHECK_INITIALIZED(self)
628 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
629}
630
631static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000632buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633{
634 CHECK_INITIALIZED(self)
635 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
636}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000637
Antoine Pitrou243757e2010-11-05 21:15:39 +0000638/* Serialization */
639
640static PyObject *
641buffered_getstate(buffered *self, PyObject *args)
642{
643 PyErr_Format(PyExc_TypeError,
644 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
645 return NULL;
646}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648/* Forward decls */
649static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100650_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000654_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000656_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200658_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000659static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000660_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000661static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000662_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000663static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000664_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200665static Py_ssize_t
666_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000667
668/*
669 * Helpers
670 */
671
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100672/* Sets the current error to BlockingIOError */
673static void
674_set_BlockingIOError(char *msg, Py_ssize_t written)
675{
676 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200677#ifdef Py_DEBUG
678 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
679 if an exception is set when it is called */
680 PyErr_Clear();
681#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100682 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
683 errno, msg, written);
684 if (err)
685 PyErr_SetObject(PyExc_BlockingIOError, err);
686 Py_XDECREF(err);
687}
688
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689/* Returns the address of the `written` member if a BlockingIOError was
690 raised, NULL otherwise. The error is always re-raised. */
691static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000692_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000693{
694 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200695 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696
697 PyErr_Fetch(&t, &v, &tb);
698 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
699 PyErr_Restore(t, v, tb);
700 return NULL;
701 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200702 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000703 /* TODO: sanity check (err->written >= 0) */
704 PyErr_Restore(t, v, tb);
705 return &err->written;
706}
707
708static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000709_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000712 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000713 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
714 if (res == NULL)
715 return -1;
716 n = PyNumber_AsOff_t(res, PyExc_ValueError);
717 Py_DECREF(res);
718 if (n < 0) {
719 if (!PyErr_Occurred())
720 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000721 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200722 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723 return -1;
724 }
725 self->abs_pos = n;
726 return n;
727}
728
729static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000730_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731{
732 PyObject *res, *posobj, *whenceobj;
733 Py_off_t n;
734
735 posobj = PyLong_FromOff_t(target);
736 if (posobj == NULL)
737 return -1;
738 whenceobj = PyLong_FromLong(whence);
739 if (whenceobj == NULL) {
740 Py_DECREF(posobj);
741 return -1;
742 }
743 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
744 posobj, whenceobj, NULL);
745 Py_DECREF(posobj);
746 Py_DECREF(whenceobj);
747 if (res == NULL)
748 return -1;
749 n = PyNumber_AsOff_t(res, PyExc_ValueError);
750 Py_DECREF(res);
751 if (n < 0) {
752 if (!PyErr_Occurred())
753 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000754 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200755 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000756 return -1;
757 }
758 self->abs_pos = n;
759 return n;
760}
761
762static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000763_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000764{
765 Py_ssize_t n;
766 if (self->buffer_size <= 0) {
767 PyErr_SetString(PyExc_ValueError,
768 "buffer size must be strictly positive");
769 return -1;
770 }
771 if (self->buffer)
772 PyMem_Free(self->buffer);
773 self->buffer = PyMem_Malloc(self->buffer_size);
774 if (self->buffer == NULL) {
775 PyErr_NoMemory();
776 return -1;
777 }
Georg Brandldfd73442009-04-05 11:47:34 +0000778#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000779 if (self->lock)
780 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000781 self->lock = PyThread_allocate_lock();
782 if (self->lock == NULL) {
783 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
784 return -1;
785 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000786 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000787#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000788 /* Find out whether buffer_size is a power of 2 */
789 /* XXX is this optimization useful? */
790 for (n = self->buffer_size - 1; n & 1; n >>= 1)
791 ;
792 if (n == 0)
793 self->buffer_mask = self->buffer_size - 1;
794 else
795 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000796 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000797 PyErr_Clear();
798 return 0;
799}
800
Antoine Pitrou707ce822011-02-25 21:24:11 +0000801/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
802 clears the error indicator), 0 otherwise.
803 Should only be called when PyErr_Occurred() is true.
804*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700805int
806_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000807{
808 static PyObject *eintr_int = NULL;
809 PyObject *typ, *val, *tb;
810 PyEnvironmentErrorObject *env_err;
811
812 if (eintr_int == NULL) {
813 eintr_int = PyLong_FromLong(EINTR);
814 assert(eintr_int != NULL);
815 }
816 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
817 return 0;
818 PyErr_Fetch(&typ, &val, &tb);
819 PyErr_NormalizeException(&typ, &val, &tb);
820 env_err = (PyEnvironmentErrorObject *) val;
821 assert(env_err != NULL);
822 if (env_err->myerrno != NULL &&
823 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
824 Py_DECREF(typ);
825 Py_DECREF(val);
826 Py_XDECREF(tb);
827 return 1;
828 }
829 /* This silences any error set by PyObject_RichCompareBool() */
830 PyErr_Restore(typ, val, tb);
831 return 0;
832}
833
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000834/*
835 * Shared methods and wrappers
836 */
837
838static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200839buffered_flush_and_rewind_unlocked(buffered *self)
840{
841 PyObject *res;
842
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100843 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200844 if (res == NULL)
845 return NULL;
846 Py_DECREF(res);
847
848 if (self->readable) {
849 /* Rewind the raw stream so that its position corresponds to
850 the current logical position. */
851 Py_off_t n;
852 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
853 _bufferedreader_reset_buf(self);
854 if (n == -1)
855 return NULL;
856 }
857 Py_RETURN_NONE;
858}
859
860static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000861buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000862{
863 PyObject *res;
864
865 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000866 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000867
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000868 if (!ENTER_BUFFERED(self))
869 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200870 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871 LEAVE_BUFFERED(self)
872
873 return res;
874}
875
876static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000877buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000878{
879 Py_ssize_t n = 0;
880 PyObject *res = NULL;
881
882 CHECK_INITIALIZED(self)
883 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
884 return NULL;
885 }
886
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000887 if (!ENTER_BUFFERED(self))
888 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889
890 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200891 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000892 if (res == NULL)
893 goto end;
894 Py_CLEAR(res);
895 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200896 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000897
898end:
899 LEAVE_BUFFERED(self)
900 return res;
901}
902
903static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000904buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000905{
906 Py_ssize_t n = -1;
907 PyObject *res;
908
909 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000910 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000911 return NULL;
912 }
913 if (n < -1) {
914 PyErr_SetString(PyExc_ValueError,
915 "read length must be positive or -1");
916 return NULL;
917 }
918
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000919 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000921 if (n == -1) {
922 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000923 if (!ENTER_BUFFERED(self))
924 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000925 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000926 }
927 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000928 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200929 if (res != Py_None)
930 return res;
931 Py_DECREF(res);
932 if (!ENTER_BUFFERED(self))
933 return NULL;
934 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000935 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936
Antoine Pitroue05565e2011-08-20 14:39:23 +0200937 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 return res;
939}
940
941static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000942buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943{
944 Py_ssize_t n, have, r;
945 PyObject *res = NULL;
946
947 CHECK_INITIALIZED(self)
948 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
949 return NULL;
950 }
951
952 if (n < 0) {
953 PyErr_SetString(PyExc_ValueError,
954 "read length must be positive");
955 return NULL;
956 }
957 if (n == 0)
958 return PyBytes_FromStringAndSize(NULL, 0);
959
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960 /* Return up to n bytes. If at least one byte is buffered, we
961 only return buffered bytes. Otherwise, we do one raw read. */
962
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
964 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100965 n = Py_MIN(have, n);
966 res = _bufferedreader_read_fast(self, n);
967 assert(res != Py_None);
968 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100970 res = PyBytes_FromStringAndSize(NULL, n);
971 if (res == NULL)
972 return NULL;
973 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200974 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100975 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200976 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000977 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100978 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
979 LEAVE_BUFFERED(self)
980 if (r == -1) {
981 Py_DECREF(res);
982 return NULL;
983 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 if (r == -2)
985 r = 0;
986 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100987 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000988 return res;
989}
990
991static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000992buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200994 Py_buffer buf;
995 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000996 PyObject *res = NULL;
997
998 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200999
1000 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
1001 return NULL;
1002
1003 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1004 if (n > 0) {
1005 if (n >= buf.len) {
1006 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1007 self->pos += buf.len;
1008 res = PyLong_FromSsize_t(buf.len);
1009 goto end_unlocked;
1010 }
1011 memcpy(buf.buf, self->buffer + self->pos, n);
1012 self->pos += n;
1013 written = n;
1014 }
1015
1016 if (!ENTER_BUFFERED(self))
1017 goto end_unlocked;
1018
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001019 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001020 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021 if (res == NULL)
1022 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001023 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001024 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001025
1026 _bufferedreader_reset_buf(self);
1027 self->pos = 0;
1028
1029 for (remaining = buf.len - written;
1030 remaining > 0;
1031 written += n, remaining -= n) {
1032 /* If remaining bytes is larger than internal buffer size, copy
1033 * directly into caller's buffer. */
1034 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001035 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1036 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001037 }
1038 else {
1039 n = _bufferedreader_fill_buffer(self);
1040 if (n > 0) {
1041 if (n > remaining)
1042 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001043 memcpy((char *) buf.buf + written,
1044 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001045 self->pos += n;
1046 continue; /* short circuit */
1047 }
1048 }
1049 if (n == 0 || (n == -2 && written > 0))
1050 break;
1051 if (n < 0) {
1052 if (n == -2) {
1053 Py_INCREF(Py_None);
1054 res = Py_None;
1055 }
1056 goto end;
1057 }
1058 }
1059 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001060
1061end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001062 LEAVE_BUFFERED(self);
1063end_unlocked:
1064 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065 return res;
1066}
1067
1068static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001069_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070{
1071 PyObject *res = NULL;
1072 PyObject *chunks = NULL;
1073 Py_ssize_t n, written = 0;
1074 const char *start, *s, *end;
1075
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001076 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001077
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001078 /* First, try to find a line in the buffer. This can run unlocked because
1079 the calls to the C API are simple enough that they can't trigger
1080 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1082 if (limit >= 0 && n > limit)
1083 n = limit;
1084 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001085 s = memchr(start, '\n', n);
1086 if (s != NULL) {
1087 res = PyBytes_FromStringAndSize(start, s - start + 1);
1088 if (res != NULL)
1089 self->pos += s - start + 1;
1090 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001091 }
1092 if (n == limit) {
1093 res = PyBytes_FromStringAndSize(start, n);
1094 if (res != NULL)
1095 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001096 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001097 }
1098
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001099 if (!ENTER_BUFFERED(self))
1100 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001101
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001103 chunks = PyList_New(0);
1104 if (chunks == NULL)
1105 goto end;
1106 if (n > 0) {
1107 res = PyBytes_FromStringAndSize(start, n);
1108 if (res == NULL)
1109 goto end;
1110 if (PyList_Append(chunks, res) < 0) {
1111 Py_CLEAR(res);
1112 goto end;
1113 }
1114 Py_CLEAR(res);
1115 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001116 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001117 if (limit >= 0)
1118 limit -= n;
1119 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001120 if (self->writable) {
1121 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1122 if (r == NULL)
1123 goto end;
1124 Py_DECREF(r);
1125 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126
1127 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001128 _bufferedreader_reset_buf(self);
1129 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001130 if (n == -1)
1131 goto end;
1132 if (n <= 0)
1133 break;
1134 if (limit >= 0 && n > limit)
1135 n = limit;
1136 start = self->buffer;
1137 end = start + n;
1138 s = start;
1139 while (s < end) {
1140 if (*s++ == '\n') {
1141 res = PyBytes_FromStringAndSize(start, s - start);
1142 if (res == NULL)
1143 goto end;
1144 self->pos = s - start;
1145 goto found;
1146 }
1147 }
1148 res = PyBytes_FromStringAndSize(start, n);
1149 if (res == NULL)
1150 goto end;
1151 if (n == limit) {
1152 self->pos = n;
1153 break;
1154 }
1155 if (PyList_Append(chunks, res) < 0) {
1156 Py_CLEAR(res);
1157 goto end;
1158 }
1159 Py_CLEAR(res);
1160 written += n;
1161 if (limit >= 0)
1162 limit -= n;
1163 }
1164found:
1165 if (res != NULL && PyList_Append(chunks, res) < 0) {
1166 Py_CLEAR(res);
1167 goto end;
1168 }
1169 Py_CLEAR(res);
1170 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1171
1172end:
1173 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001174end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001175 Py_XDECREF(chunks);
1176 return res;
1177}
1178
1179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001180buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001181{
1182 Py_ssize_t limit = -1;
1183
1184 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001185 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001187 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001188}
1189
1190
1191static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001192buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001193{
1194 Py_off_t pos;
1195
1196 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001197 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001198 if (pos == -1)
1199 return NULL;
1200 pos -= RAW_OFFSET(self);
1201 /* TODO: sanity check (pos >= 0) */
1202 return PyLong_FromOff_t(pos);
1203}
1204
1205static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001206buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207{
1208 Py_off_t target, n;
1209 int whence = 0;
1210 PyObject *targetobj, *res = NULL;
1211
1212 CHECK_INITIALIZED(self)
1213 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1214 return NULL;
1215 }
Jesus Cea94363612012-06-22 18:32:07 +02001216
1217 /* Do some error checking instead of trusting OS 'seek()'
1218 ** error detection, just in case.
1219 */
1220 if ((whence < 0 || whence >2)
1221#ifdef SEEK_HOLE
1222 && (whence != SEEK_HOLE)
1223#endif
1224#ifdef SEEK_DATA
1225 && (whence != SEEK_DATA)
1226#endif
1227 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001228 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001229 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 return NULL;
1231 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001232
1233 CHECK_CLOSED(self, "seek of closed file")
1234
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001235 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1236 return NULL;
1237
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1239 if (target == -1 && PyErr_Occurred())
1240 return NULL;
1241
Jesus Cea94363612012-06-22 18:32:07 +02001242 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1243 buffer. Other whence values must be managed without this optimization.
1244 Some Operating Systems can provide additional values, like
1245 SEEK_HOLE/SEEK_DATA. */
1246 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001247 Py_off_t current, avail;
1248 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001249 so as to return quickly if possible. Also, we needn't take the
1250 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001252 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1253 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 current = RAW_TELL(self);
1255 avail = READAHEAD(self);
1256 if (avail > 0) {
1257 Py_off_t offset;
1258 if (whence == 0)
1259 offset = target - (current - RAW_OFFSET(self));
1260 else
1261 offset = target;
1262 if (offset >= -self->pos && offset <= avail) {
1263 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001264 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265 }
1266 }
1267 }
1268
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001269 if (!ENTER_BUFFERED(self))
1270 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001271
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001272 /* Fallback: invoke raw seek() method and clear buffer */
1273 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001274 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275 if (res == NULL)
1276 goto end;
1277 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001278 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001279 }
1280
1281 /* TODO: align on block boundary and read buffer if needed? */
1282 if (whence == 1)
1283 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001284 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285 if (n == -1)
1286 goto end;
1287 self->raw_pos = -1;
1288 res = PyLong_FromOff_t(n);
1289 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001290 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001291
1292end:
1293 LEAVE_BUFFERED(self)
1294 return res;
1295}
1296
1297static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001298buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001299{
1300 PyObject *pos = Py_None;
1301 PyObject *res = NULL;
1302
1303 CHECK_INITIALIZED(self)
1304 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1305 return NULL;
1306 }
1307
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001308 if (!ENTER_BUFFERED(self))
1309 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310
1311 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001312 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 if (res == NULL)
1314 goto end;
1315 Py_CLEAR(res);
1316 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001317 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1318 if (res == NULL)
1319 goto end;
1320 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001321 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 PyErr_Clear();
1323
1324end:
1325 LEAVE_BUFFERED(self)
1326 return res;
1327}
1328
1329static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001330buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331{
1332 PyObject *line;
1333 PyTypeObject *tp;
1334
1335 CHECK_INITIALIZED(self);
1336
1337 tp = Py_TYPE(self);
1338 if (tp == &PyBufferedReader_Type ||
1339 tp == &PyBufferedRandom_Type) {
1340 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001341 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001342 }
1343 else {
1344 line = PyObject_CallMethodObjArgs((PyObject *)self,
1345 _PyIO_str_readline, NULL);
1346 if (line && !PyBytes_Check(line)) {
1347 PyErr_Format(PyExc_IOError,
1348 "readline() should have returned a bytes object, "
1349 "not '%.200s'", Py_TYPE(line)->tp_name);
1350 Py_DECREF(line);
1351 return NULL;
1352 }
1353 }
1354
1355 if (line == NULL)
1356 return NULL;
1357
1358 if (PyBytes_GET_SIZE(line) == 0) {
1359 /* Reached EOF or would have blocked */
1360 Py_DECREF(line);
1361 return NULL;
1362 }
1363
1364 return line;
1365}
1366
Antoine Pitrou716c4442009-05-23 19:04:03 +00001367static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001368buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001369{
1370 PyObject *nameobj, *res;
1371
Martin v. Löwis767046a2011-10-14 15:35:36 +02001372 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001373 if (nameobj == NULL) {
1374 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1375 PyErr_Clear();
1376 else
1377 return NULL;
1378 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1379 }
1380 else {
1381 res = PyUnicode_FromFormat("<%s name=%R>",
1382 Py_TYPE(self)->tp_name, nameobj);
1383 Py_DECREF(nameobj);
1384 }
1385 return res;
1386}
1387
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388/*
1389 * class BufferedReader
1390 */
1391
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001392PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393 "Create a new buffered reader using the given readable raw IO object.");
1394
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001395static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001396{
1397 self->read_end = -1;
1398}
1399
1400static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001401bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001402{
1403 char *kwlist[] = {"raw", "buffer_size", NULL};
1404 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1405 PyObject *raw;
1406
1407 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001408 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001409
1410 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1411 &raw, &buffer_size)) {
1412 return -1;
1413 }
1414
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001415 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416 return -1;
1417
1418 Py_CLEAR(self->raw);
1419 Py_INCREF(raw);
1420 self->raw = raw;
1421 self->buffer_size = buffer_size;
1422 self->readable = 1;
1423 self->writable = 0;
1424
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001425 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001426 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001427 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001428
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001429 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1430 Py_TYPE(raw) == &PyFileIO_Type);
1431
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001432 self->ok = 1;
1433 return 0;
1434}
1435
1436static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001437_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438{
1439 Py_buffer buf;
1440 PyObject *memobj, *res;
1441 Py_ssize_t n;
1442 /* NOTE: the buffer needn't be released as its object is NULL. */
1443 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1444 return -1;
1445 memobj = PyMemoryView_FromBuffer(&buf);
1446 if (memobj == NULL)
1447 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001448 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1449 occurs so we needn't do it ourselves.
1450 We then retry reading, ignoring the signal if no handler has
1451 raised (see issue #10956).
1452 */
1453 do {
1454 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001455 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001456 Py_DECREF(memobj);
1457 if (res == NULL)
1458 return -1;
1459 if (res == Py_None) {
1460 /* Non-blocking stream would have blocked. Special return code! */
1461 Py_DECREF(res);
1462 return -2;
1463 }
1464 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1465 Py_DECREF(res);
1466 if (n < 0 || n > len) {
1467 PyErr_Format(PyExc_IOError,
1468 "raw readinto() returned invalid length %zd "
1469 "(should have been between 0 and %zd)", n, len);
1470 return -1;
1471 }
1472 if (n > 0 && self->abs_pos != -1)
1473 self->abs_pos += n;
1474 return n;
1475}
1476
1477static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001478_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479{
1480 Py_ssize_t start, len, n;
1481 if (VALID_READ_BUFFER(self))
1482 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1483 else
1484 start = 0;
1485 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001486 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001487 if (n <= 0)
1488 return n;
1489 self->read_end = start + n;
1490 self->raw_pos = start + n;
1491 return n;
1492}
1493
1494static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001495_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001496{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001497 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001498 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001499
1500 /* First copy what we have in the current buffer. */
1501 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1502 if (current_size) {
1503 data = PyBytes_FromStringAndSize(
1504 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001505 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001506 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001507 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001508 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001509 /* We're going past the buffer's bounds, flush it */
1510 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001511 tmp = buffered_flush_and_rewind_unlocked(self);
1512 if (tmp == NULL)
1513 goto cleanup;
1514 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001515 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001516 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001517
1518 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001519 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1520 if (tmp == NULL)
1521 goto cleanup;
1522 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001523 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001524 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001525 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001526 if (tmp == Py_None) {
1527 if (current_size == 0) {
1528 res = Py_None;
1529 goto cleanup;
1530 } else {
1531 res = data;
1532 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001533 }
1534 }
1535 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001536 PyBytes_Concat(&data, tmp);
1537 res = data;
1538 goto cleanup;
1539 }
1540 else {
1541 res = tmp;
1542 goto cleanup;
1543 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001544 }
1545
1546 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001547 if (chunks == NULL)
1548 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001549
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001550 while (1) {
1551 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001552 if (PyList_Append(chunks, data) < 0)
1553 goto cleanup;
1554 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001555 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001556
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001557 /* Read until EOF or until read() would block. */
1558 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001559 if (data == NULL)
1560 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001561 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001562 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001563 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001564 }
1565 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1566 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001567 res = data;
1568 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001569 }
1570 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001571 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1572 res = tmp;
1573 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001574 }
1575 }
1576 current_size += PyBytes_GET_SIZE(data);
1577 if (self->abs_pos != -1)
1578 self->abs_pos += PyBytes_GET_SIZE(data);
1579 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001580cleanup:
1581 /* res is either NULL or a borrowed ref */
1582 Py_XINCREF(res);
1583 Py_XDECREF(data);
1584 Py_XDECREF(tmp);
1585 Py_XDECREF(chunks);
1586 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001587}
1588
1589/* Read n bytes from the buffer if it can, otherwise return None.
1590 This function is simple enough that it can run unlocked. */
1591static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001592_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001593{
1594 Py_ssize_t current_size;
1595
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001596 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1597 if (n <= current_size) {
1598 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1600 if (res != NULL)
1601 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001602 return res;
1603 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001604 Py_RETURN_NONE;
1605}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607/* Generic read function: read from the stream until enough bytes are read,
1608 * or until an EOF occurs or until read() would block.
1609 */
1610static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001611_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001612{
1613 PyObject *res = NULL;
1614 Py_ssize_t current_size, remaining, written;
1615 char *out;
1616
1617 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1618 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001619 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001620
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001621 res = PyBytes_FromStringAndSize(NULL, n);
1622 if (res == NULL)
1623 goto error;
1624 out = PyBytes_AS_STRING(res);
1625 remaining = n;
1626 written = 0;
1627 if (current_size > 0) {
1628 memcpy(out, self->buffer + self->pos, current_size);
1629 remaining -= current_size;
1630 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001631 self->pos += current_size;
1632 }
1633 /* Flush the write buffer if necessary */
1634 if (self->writable) {
1635 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1636 if (r == NULL)
1637 goto error;
1638 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001639 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001640 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001641 while (remaining > 0) {
1642 /* We want to read a whole block at the end into buffer.
1643 If we had readv() we could do this in one pass. */
1644 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1645 if (r == 0)
1646 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001647 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001648 if (r == -1)
1649 goto error;
1650 if (r == 0 || r == -2) {
1651 /* EOF occurred or read() would block. */
1652 if (r == 0 || written > 0) {
1653 if (_PyBytes_Resize(&res, written))
1654 goto error;
1655 return res;
1656 }
1657 Py_DECREF(res);
1658 Py_INCREF(Py_None);
1659 return Py_None;
1660 }
1661 remaining -= r;
1662 written += r;
1663 }
1664 assert(remaining <= self->buffer_size);
1665 self->pos = 0;
1666 self->raw_pos = 0;
1667 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001668 /* NOTE: when the read is satisfied, we avoid issuing any additional
1669 reads, which could block indefinitely (e.g. on a socket).
1670 See issue #9550. */
1671 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001672 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001673 if (r == -1)
1674 goto error;
1675 if (r == 0 || r == -2) {
1676 /* EOF occurred or read() would block. */
1677 if (r == 0 || written > 0) {
1678 if (_PyBytes_Resize(&res, written))
1679 goto error;
1680 return res;
1681 }
1682 Py_DECREF(res);
1683 Py_INCREF(Py_None);
1684 return Py_None;
1685 }
1686 if (remaining > r) {
1687 memcpy(out + written, self->buffer + self->pos, r);
1688 written += r;
1689 self->pos += r;
1690 remaining -= r;
1691 }
1692 else if (remaining > 0) {
1693 memcpy(out + written, self->buffer + self->pos, remaining);
1694 written += remaining;
1695 self->pos += remaining;
1696 remaining = 0;
1697 }
1698 if (remaining == 0)
1699 break;
1700 }
1701
1702 return res;
1703
1704error:
1705 Py_XDECREF(res);
1706 return NULL;
1707}
1708
1709static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001710_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001711{
1712 Py_ssize_t have, r;
1713
1714 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1715 /* Constraints:
1716 1. we don't want to advance the file position.
1717 2. we don't want to lose block alignment, so we can't shift the buffer
1718 to make some place.
1719 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1720 */
1721 if (have > 0) {
1722 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1723 }
1724
1725 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001726 _bufferedreader_reset_buf(self);
1727 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001728 if (r == -1)
1729 return NULL;
1730 if (r == -2)
1731 r = 0;
1732 self->pos = 0;
1733 return PyBytes_FromStringAndSize(self->buffer, r);
1734}
1735
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001736static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001738 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1739 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1740 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1741 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1742 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1743 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1744 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1745 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001746 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001747 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001748
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001749 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1750 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1751 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001752 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001753 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1754 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1755 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1756 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001757 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001758 {NULL, NULL}
1759};
1760
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001761static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001762 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001763 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764 {NULL}
1765};
1766
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001767static PyGetSetDef bufferedreader_getset[] = {
1768 {"closed", (getter)buffered_closed_get, NULL, NULL},
1769 {"name", (getter)buffered_name_get, NULL, NULL},
1770 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001771 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001772};
1773
1774
1775PyTypeObject PyBufferedReader_Type = {
1776 PyVarObject_HEAD_INIT(NULL, 0)
1777 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001778 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001780 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781 0, /*tp_print*/
1782 0, /*tp_getattr*/
1783 0, /*tp_setattr*/
1784 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001785 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 0, /*tp_as_number*/
1787 0, /*tp_as_sequence*/
1788 0, /*tp_as_mapping*/
1789 0, /*tp_hash */
1790 0, /*tp_call*/
1791 0, /*tp_str*/
1792 0, /*tp_getattro*/
1793 0, /*tp_setattro*/
1794 0, /*tp_as_buffer*/
1795 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001796 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001797 bufferedreader_doc, /* tp_doc */
1798 (traverseproc)buffered_traverse, /* tp_traverse */
1799 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001801 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001803 (iternextfunc)buffered_iternext, /* tp_iternext */
1804 bufferedreader_methods, /* tp_methods */
1805 bufferedreader_members, /* tp_members */
1806 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807 0, /* tp_base */
1808 0, /* tp_dict */
1809 0, /* tp_descr_get */
1810 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001811 offsetof(buffered, dict), /* tp_dictoffset */
1812 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813 0, /* tp_alloc */
1814 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001815 0, /* tp_free */
1816 0, /* tp_is_gc */
1817 0, /* tp_bases */
1818 0, /* tp_mro */
1819 0, /* tp_cache */
1820 0, /* tp_subclasses */
1821 0, /* tp_weaklist */
1822 0, /* tp_del */
1823 0, /* tp_version_tag */
1824 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825};
1826
1827
Benjamin Peterson59406a92009-03-26 17:10:29 +00001828
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001829/*
1830 * class BufferedWriter
1831 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001832PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001833 "A buffer for a writeable sequential RawIO object.\n"
1834 "\n"
1835 "The constructor creates a BufferedWriter for the given writeable raw\n"
1836 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001837 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838 );
1839
1840static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001841_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001842{
1843 self->write_pos = 0;
1844 self->write_end = -1;
1845}
1846
1847static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001848bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849{
Florent Xicluna109d5732012-07-07 17:03:22 +02001850 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001852 PyObject *raw;
1853
1854 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001855 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856
R David Murray9f10f562013-02-23 22:07:55 -05001857 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001858 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859 return -1;
1860 }
1861
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001862 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863 return -1;
1864
1865 Py_CLEAR(self->raw);
1866 Py_INCREF(raw);
1867 self->raw = raw;
1868 self->readable = 0;
1869 self->writable = 1;
1870
1871 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001872 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001873 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001874 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875 self->pos = 0;
1876
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001877 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1878 Py_TYPE(raw) == &PyFileIO_Type);
1879
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880 self->ok = 1;
1881 return 0;
1882}
1883
1884static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001885_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001886{
1887 Py_buffer buf;
1888 PyObject *memobj, *res;
1889 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001890 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001891 /* NOTE: the buffer needn't be released as its object is NULL. */
1892 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1893 return -1;
1894 memobj = PyMemoryView_FromBuffer(&buf);
1895 if (memobj == NULL)
1896 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001897 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1898 occurs so we needn't do it ourselves.
1899 We then retry writing, ignoring the signal if no handler has
1900 raised (see issue #10956).
1901 */
1902 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001903 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001904 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001905 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001906 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001907 Py_DECREF(memobj);
1908 if (res == NULL)
1909 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001910 if (res == Py_None) {
1911 /* Non-blocking stream would have blocked. Special return code!
1912 Being paranoid we reset errno in case it is changed by code
1913 triggered by a decref. errno is used by _set_BlockingIOError(). */
1914 Py_DECREF(res);
1915 errno = errnum;
1916 return -2;
1917 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1919 Py_DECREF(res);
1920 if (n < 0 || n > len) {
1921 PyErr_Format(PyExc_IOError,
1922 "raw write() returned invalid length %zd "
1923 "(should have been between 0 and %zd)", n, len);
1924 return -1;
1925 }
1926 if (n > 0 && self->abs_pos != -1)
1927 self->abs_pos += n;
1928 return n;
1929}
1930
1931/* `restore_pos` is 1 if we need to restore the raw stream position at
1932 the end, 0 otherwise. */
1933static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001934_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935{
1936 Py_ssize_t written = 0;
1937 Py_off_t n, rewind;
1938
1939 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1940 goto end;
1941 /* First, rewind */
1942 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1943 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001944 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945 if (n < 0) {
1946 goto error;
1947 }
1948 self->raw_pos -= rewind;
1949 }
1950 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 self->buffer + self->write_pos,
1953 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1954 Py_off_t, Py_ssize_t));
1955 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001956 goto error;
1957 }
1958 else if (n == -2) {
1959 _set_BlockingIOError("write could not complete without blocking",
1960 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001961 goto error;
1962 }
1963 self->write_pos += n;
1964 self->raw_pos = self->write_pos;
1965 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001966 /* Partial writes can return successfully when interrupted by a
1967 signal (see write(2)). We must run signal handlers before
1968 blocking another time, possibly indefinitely. */
1969 if (PyErr_CheckSignals() < 0)
1970 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001971 }
1972
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001973 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001974
1975end:
1976 Py_RETURN_NONE;
1977
1978error:
1979 return NULL;
1980}
1981
1982static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001983bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001984{
1985 PyObject *res = NULL;
1986 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001987 Py_ssize_t written, avail, remaining;
1988 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001989
1990 CHECK_INITIALIZED(self)
1991 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1992 return NULL;
1993 }
1994
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001995 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 PyErr_SetString(PyExc_ValueError, "write to closed file");
1997 PyBuffer_Release(&buf);
1998 return NULL;
1999 }
2000
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00002001 if (!ENTER_BUFFERED(self)) {
2002 PyBuffer_Release(&buf);
2003 return NULL;
2004 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002005
2006 /* Fast path: the data to write can be fully buffered. */
2007 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2008 self->pos = 0;
2009 self->raw_pos = 0;
2010 }
2011 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2012 if (buf.len <= avail) {
2013 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002014 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 self->write_pos = self->pos;
2016 }
2017 ADJUST_POSITION(self, self->pos + buf.len);
2018 if (self->pos > self->write_end)
2019 self->write_end = self->pos;
2020 written = buf.len;
2021 goto end;
2022 }
2023
2024 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002025 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002027 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002028 if (w == NULL)
2029 goto error;
2030 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002031 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002032 /* Make some place by shifting the buffer. */
2033 assert(VALID_WRITE_BUFFER(self));
2034 memmove(self->buffer, self->buffer + self->write_pos,
2035 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2036 Py_off_t, Py_ssize_t));
2037 self->write_end -= self->write_pos;
2038 self->raw_pos -= self->write_pos;
2039 self->pos -= self->write_pos;
2040 self->write_pos = 0;
2041 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2042 Py_off_t, Py_ssize_t);
2043 if (buf.len <= avail) {
2044 /* Everything can be buffered */
2045 PyErr_Clear();
2046 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2047 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002048 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002049 written = buf.len;
2050 goto end;
2051 }
2052 /* Buffer as much as possible. */
2053 memcpy(self->buffer + self->write_end, buf.buf, avail);
2054 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002055 self->pos += avail;
2056 /* XXX Modifying the existing exception e using the pointer w
2057 will change e.characters_written but not e.args[2].
2058 Therefore we just replace with a new error. */
2059 _set_BlockingIOError("write could not complete without blocking",
2060 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 goto error;
2062 }
2063 Py_CLEAR(res);
2064
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002065 /* Adjust the raw stream position if it is away from the logical stream
2066 position. This happens if the read buffer has been filled but not
2067 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2068 the raw stream by itself).
2069 Fixes issue #6629.
2070 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002071 offset = RAW_OFFSET(self);
2072 if (offset != 0) {
2073 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002074 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002075 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002076 }
2077
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078 /* Then write buf itself. At this point the buffer has been emptied. */
2079 remaining = buf.len;
2080 written = 0;
2081 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002082 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083 self, (char *) buf.buf + written, buf.len - written);
2084 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002085 goto error;
2086 } else if (n == -2) {
2087 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002088 if (remaining > self->buffer_size) {
2089 /* Can't buffer everything, still buffer as much as possible */
2090 memcpy(self->buffer,
2091 (char *) buf.buf + written, self->buffer_size);
2092 self->raw_pos = 0;
2093 ADJUST_POSITION(self, self->buffer_size);
2094 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002095 written += self->buffer_size;
2096 _set_BlockingIOError("write could not complete without "
2097 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098 goto error;
2099 }
2100 PyErr_Clear();
2101 break;
2102 }
2103 written += n;
2104 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002105 /* Partial writes can return successfully when interrupted by a
2106 signal (see write(2)). We must run signal handlers before
2107 blocking another time, possibly indefinitely. */
2108 if (PyErr_CheckSignals() < 0)
2109 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110 }
2111 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113 if (remaining > 0) {
2114 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2115 written += remaining;
2116 }
2117 self->write_pos = 0;
2118 /* TODO: sanity check (remaining >= 0) */
2119 self->write_end = remaining;
2120 ADJUST_POSITION(self, remaining);
2121 self->raw_pos = 0;
2122
2123end:
2124 res = PyLong_FromSsize_t(written);
2125
2126error:
2127 LEAVE_BUFFERED(self)
2128 PyBuffer_Release(&buf);
2129 return res;
2130}
2131
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002132static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002134 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2135 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2136 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2137 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2138 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2139 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2140 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002141 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002142 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002144 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2145 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2146 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2147 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2148 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002149 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150 {NULL, NULL}
2151};
2152
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002153static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002154 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002155 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 {NULL}
2157};
2158
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002159static PyGetSetDef bufferedwriter_getset[] = {
2160 {"closed", (getter)buffered_closed_get, NULL, NULL},
2161 {"name", (getter)buffered_name_get, NULL, NULL},
2162 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002163 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002164};
2165
2166
2167PyTypeObject PyBufferedWriter_Type = {
2168 PyVarObject_HEAD_INIT(NULL, 0)
2169 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002172 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173 0, /*tp_print*/
2174 0, /*tp_getattr*/
2175 0, /*tp_setattr*/
2176 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002177 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178 0, /*tp_as_number*/
2179 0, /*tp_as_sequence*/
2180 0, /*tp_as_mapping*/
2181 0, /*tp_hash */
2182 0, /*tp_call*/
2183 0, /*tp_str*/
2184 0, /*tp_getattro*/
2185 0, /*tp_setattro*/
2186 0, /*tp_as_buffer*/
2187 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002188 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002189 bufferedwriter_doc, /* tp_doc */
2190 (traverseproc)buffered_traverse, /* tp_traverse */
2191 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002193 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194 0, /* tp_iter */
2195 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002196 bufferedwriter_methods, /* tp_methods */
2197 bufferedwriter_members, /* tp_members */
2198 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199 0, /* tp_base */
2200 0, /* tp_dict */
2201 0, /* tp_descr_get */
2202 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002203 offsetof(buffered, dict), /* tp_dictoffset */
2204 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205 0, /* tp_alloc */
2206 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002207 0, /* tp_free */
2208 0, /* tp_is_gc */
2209 0, /* tp_bases */
2210 0, /* tp_mro */
2211 0, /* tp_cache */
2212 0, /* tp_subclasses */
2213 0, /* tp_weaklist */
2214 0, /* tp_del */
2215 0, /* tp_version_tag */
2216 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217};
2218
2219
2220
2221/*
2222 * BufferedRWPair
2223 */
2224
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002225PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226 "A buffered reader and writer object together.\n"
2227 "\n"
2228 "A buffered reader object and buffered writer object put together to\n"
2229 "form a sequential IO object that can read and write. This is typically\n"
2230 "used with a socket or two-way pipe.\n"
2231 "\n"
2232 "reader and writer are RawIOBase objects that are readable and\n"
2233 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002234 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235 );
2236
2237/* XXX The usefulness of this (compared to having two separate IO objects) is
2238 * questionable.
2239 */
2240
2241typedef struct {
2242 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002243 buffered *reader;
2244 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245 PyObject *dict;
2246 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002247} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002248
2249static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251{
2252 PyObject *reader, *writer;
2253 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254
Florent Xicluna109d5732012-07-07 17:03:22 +02002255 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2256 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002257 return -1;
2258 }
2259
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002260 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263 return -1;
2264
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002266 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267 if (self->reader == NULL)
2268 return -1;
2269
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002270 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002271 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002272 if (self->writer == NULL) {
2273 Py_CLEAR(self->reader);
2274 return -1;
2275 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002276
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277 return 0;
2278}
2279
2280static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002281bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002282{
2283 Py_VISIT(self->dict);
2284 return 0;
2285}
2286
2287static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002288bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002289{
2290 Py_CLEAR(self->reader);
2291 Py_CLEAR(self->writer);
2292 Py_CLEAR(self->dict);
2293 return 0;
2294}
2295
2296static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002297bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298{
2299 _PyObject_GC_UNTRACK(self);
2300 Py_CLEAR(self->reader);
2301 Py_CLEAR(self->writer);
2302 Py_CLEAR(self->dict);
2303 Py_TYPE(self)->tp_free((PyObject *) self);
2304}
2305
2306static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002307_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002309 PyObject *func, *ret;
2310 if (self == NULL) {
2311 PyErr_SetString(PyExc_ValueError,
2312 "I/O operation on uninitialized object");
2313 return NULL;
2314 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002315
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002316 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002318 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319 return NULL;
2320 }
2321
2322 ret = PyObject_CallObject(func, args);
2323 Py_DECREF(func);
2324 return ret;
2325}
2326
2327static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002328bufferedrwpair_read(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_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331}
2332
2333static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002334bufferedrwpair_peek(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_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002337}
2338
2339static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002340bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002341{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002342 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002343}
2344
2345static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002346bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002347{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002348 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002349}
2350
2351static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002352bufferedrwpair_write(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_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355}
2356
2357static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002358bufferedrwpair_flush(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->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361}
2362
2363static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002364bufferedrwpair_readable(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->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002367}
2368
2369static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002370bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002372 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002373}
2374
2375static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002376bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002378 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002379 if (ret == NULL)
2380 return NULL;
2381 Py_DECREF(ret);
2382
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002383 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002384}
2385
2386static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002387bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002389 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002390
2391 if (ret != Py_False) {
2392 /* either True or exception */
2393 return ret;
2394 }
2395 Py_DECREF(ret);
2396
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002397 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002398}
2399
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002400static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002401bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002402{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002403 if (self->writer == NULL) {
2404 PyErr_SetString(PyExc_RuntimeError,
2405 "the BufferedRWPair object is being garbage-collected");
2406 return NULL;
2407 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002408 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2409}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002410
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002411static PyMethodDef bufferedrwpair_methods[] = {
2412 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2413 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2414 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2415 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002416
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002417 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2418 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002419
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002420 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2421 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002422
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002423 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2424 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002425
Antoine Pitrou243757e2010-11-05 21:15:39 +00002426 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2427
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428 {NULL, NULL}
2429};
2430
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002431static PyGetSetDef bufferedrwpair_getset[] = {
2432 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002433 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002434};
2435
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436PyTypeObject PyBufferedRWPair_Type = {
2437 PyVarObject_HEAD_INIT(NULL, 0)
2438 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002439 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002440 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002441 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442 0, /*tp_print*/
2443 0, /*tp_getattr*/
2444 0, /*tp_setattr*/
2445 0, /*tp_compare */
2446 0, /*tp_repr*/
2447 0, /*tp_as_number*/
2448 0, /*tp_as_sequence*/
2449 0, /*tp_as_mapping*/
2450 0, /*tp_hash */
2451 0, /*tp_call*/
2452 0, /*tp_str*/
2453 0, /*tp_getattro*/
2454 0, /*tp_setattro*/
2455 0, /*tp_as_buffer*/
2456 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002457 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002458 bufferedrwpair_doc, /* tp_doc */
2459 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2460 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002461 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002462 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002463 0, /* tp_iter */
2464 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002465 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002467 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002468 0, /* tp_base */
2469 0, /* tp_dict */
2470 0, /* tp_descr_get */
2471 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002472 offsetof(rwpair, dict), /* tp_dictoffset */
2473 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002474 0, /* tp_alloc */
2475 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002476 0, /* tp_free */
2477 0, /* tp_is_gc */
2478 0, /* tp_bases */
2479 0, /* tp_mro */
2480 0, /* tp_cache */
2481 0, /* tp_subclasses */
2482 0, /* tp_weaklist */
2483 0, /* tp_del */
2484 0, /* tp_version_tag */
2485 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002486};
2487
2488
2489
2490/*
2491 * BufferedRandom
2492 */
2493
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002494PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002495 "A buffered interface to random access streams.\n"
2496 "\n"
2497 "The constructor creates a reader and writer for a seekable stream,\n"
2498 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002499 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500 );
2501
2502static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002503bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002504{
Florent Xicluna109d5732012-07-07 17:03:22 +02002505 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002506 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507 PyObject *raw;
2508
2509 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002510 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002511
R David Murray9f10f562013-02-23 22:07:55 -05002512 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002513 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002514 return -1;
2515 }
2516
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002517 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002518 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002519 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002520 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002521 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002522 return -1;
2523
2524 Py_CLEAR(self->raw);
2525 Py_INCREF(raw);
2526 self->raw = raw;
2527 self->buffer_size = buffer_size;
2528 self->readable = 1;
2529 self->writable = 1;
2530
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002531 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002533 _bufferedreader_reset_buf(self);
2534 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 self->pos = 0;
2536
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002537 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2538 Py_TYPE(raw) == &PyFileIO_Type);
2539
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002540 self->ok = 1;
2541 return 0;
2542}
2543
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002544static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002545 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002546 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2547 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2548 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2549 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2550 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2551 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2552 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002553 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002554 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002555
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002556 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002557
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002558 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2559 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2560 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2561 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2562 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2563 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2564 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2565 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2566 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002567 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002568 {NULL, NULL}
2569};
2570
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002571static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002572 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002573 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002574 {NULL}
2575};
2576
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002577static PyGetSetDef bufferedrandom_getset[] = {
2578 {"closed", (getter)buffered_closed_get, NULL, NULL},
2579 {"name", (getter)buffered_name_get, NULL, NULL},
2580 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002581 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582};
2583
2584
2585PyTypeObject PyBufferedRandom_Type = {
2586 PyVarObject_HEAD_INIT(NULL, 0)
2587 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002588 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002590 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002591 0, /*tp_print*/
2592 0, /*tp_getattr*/
2593 0, /*tp_setattr*/
2594 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002595 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002596 0, /*tp_as_number*/
2597 0, /*tp_as_sequence*/
2598 0, /*tp_as_mapping*/
2599 0, /*tp_hash */
2600 0, /*tp_call*/
2601 0, /*tp_str*/
2602 0, /*tp_getattro*/
2603 0, /*tp_setattro*/
2604 0, /*tp_as_buffer*/
2605 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002606 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002607 bufferedrandom_doc, /* tp_doc */
2608 (traverseproc)buffered_traverse, /* tp_traverse */
2609 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002610 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002611 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002612 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002613 (iternextfunc)buffered_iternext, /* tp_iternext */
2614 bufferedrandom_methods, /* tp_methods */
2615 bufferedrandom_members, /* tp_members */
2616 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002617 0, /* tp_base */
2618 0, /*tp_dict*/
2619 0, /* tp_descr_get */
2620 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002621 offsetof(buffered, dict), /*tp_dictoffset*/
2622 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623 0, /* tp_alloc */
2624 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002625 0, /* tp_free */
2626 0, /* tp_is_gc */
2627 0, /* tp_bases */
2628 0, /* tp_mro */
2629 0, /* tp_cache */
2630 0, /* tp_subclasses */
2631 0, /* tp_weaklist */
2632 0, /* tp_del */
2633 0, /* tp_version_tag */
2634 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635};