blob: 02cf038d672d7796e6db8975f19a61e54a24de01 [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) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300546 _PyErr_ChainExceptions(exc, val, tb);
547 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600548 }
549
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000550end:
551 LEAVE_BUFFERED(self)
552 return res;
553}
554
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000555/* detach */
556
557static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000558buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000559{
560 PyObject *raw, *res;
561 CHECK_INITIALIZED(self)
562 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
563 if (res == NULL)
564 return NULL;
565 Py_DECREF(res);
566 raw = self->raw;
567 self->raw = NULL;
568 self->detached = 1;
569 self->ok = 0;
570 return raw;
571}
572
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573/* Inquiries */
574
575static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000576buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000577{
578 CHECK_INITIALIZED(self)
579 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
580}
581
582static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000583buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584{
585 CHECK_INITIALIZED(self)
586 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
587}
588
589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000590buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591{
592 CHECK_INITIALIZED(self)
593 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
594}
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598{
599 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200600 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601}
602
603static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000604buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000605{
606 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200607 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608}
609
610/* Lower-level APIs */
611
612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614{
615 CHECK_INITIALIZED(self)
616 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
617}
618
619static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000621{
622 CHECK_INITIALIZED(self)
623 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
624}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000625
Antoine Pitrou243757e2010-11-05 21:15:39 +0000626/* Serialization */
627
628static PyObject *
629buffered_getstate(buffered *self, PyObject *args)
630{
631 PyErr_Format(PyExc_TypeError,
632 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
633 return NULL;
634}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000635
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000636/* Forward decls */
637static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100638_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000642_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000644_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000645static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200646_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000648_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000649static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000650_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000651static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200653static Py_ssize_t
654_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655
656/*
657 * Helpers
658 */
659
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100660/* Sets the current error to BlockingIOError */
661static void
662_set_BlockingIOError(char *msg, Py_ssize_t written)
663{
664 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200665#ifdef Py_DEBUG
666 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
667 if an exception is set when it is called */
668 PyErr_Clear();
669#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100670 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
671 errno, msg, written);
672 if (err)
673 PyErr_SetObject(PyExc_BlockingIOError, err);
674 Py_XDECREF(err);
675}
676
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677/* Returns the address of the `written` member if a BlockingIOError was
678 raised, NULL otherwise. The error is always re-raised. */
679static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000680_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681{
682 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200683 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684
685 PyErr_Fetch(&t, &v, &tb);
686 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
687 PyErr_Restore(t, v, tb);
688 return NULL;
689 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200690 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691 /* TODO: sanity check (err->written >= 0) */
692 PyErr_Restore(t, v, tb);
693 return &err->written;
694}
695
696static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000697_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000699 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000700 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000701 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
702 if (res == NULL)
703 return -1;
704 n = PyNumber_AsOff_t(res, PyExc_ValueError);
705 Py_DECREF(res);
706 if (n < 0) {
707 if (!PyErr_Occurred())
708 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000709 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200710 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711 return -1;
712 }
713 self->abs_pos = n;
714 return n;
715}
716
717static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000718_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000719{
720 PyObject *res, *posobj, *whenceobj;
721 Py_off_t n;
722
723 posobj = PyLong_FromOff_t(target);
724 if (posobj == NULL)
725 return -1;
726 whenceobj = PyLong_FromLong(whence);
727 if (whenceobj == NULL) {
728 Py_DECREF(posobj);
729 return -1;
730 }
731 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
732 posobj, whenceobj, NULL);
733 Py_DECREF(posobj);
734 Py_DECREF(whenceobj);
735 if (res == NULL)
736 return -1;
737 n = PyNumber_AsOff_t(res, PyExc_ValueError);
738 Py_DECREF(res);
739 if (n < 0) {
740 if (!PyErr_Occurred())
741 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000742 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200743 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000744 return -1;
745 }
746 self->abs_pos = n;
747 return n;
748}
749
750static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000751_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000752{
753 Py_ssize_t n;
754 if (self->buffer_size <= 0) {
755 PyErr_SetString(PyExc_ValueError,
756 "buffer size must be strictly positive");
757 return -1;
758 }
759 if (self->buffer)
760 PyMem_Free(self->buffer);
761 self->buffer = PyMem_Malloc(self->buffer_size);
762 if (self->buffer == NULL) {
763 PyErr_NoMemory();
764 return -1;
765 }
Georg Brandldfd73442009-04-05 11:47:34 +0000766#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000767 if (self->lock)
768 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000769 self->lock = PyThread_allocate_lock();
770 if (self->lock == NULL) {
771 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
772 return -1;
773 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000774 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000775#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000776 /* Find out whether buffer_size is a power of 2 */
777 /* XXX is this optimization useful? */
778 for (n = self->buffer_size - 1; n & 1; n >>= 1)
779 ;
780 if (n == 0)
781 self->buffer_mask = self->buffer_size - 1;
782 else
783 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000784 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000785 PyErr_Clear();
786 return 0;
787}
788
Antoine Pitrou707ce822011-02-25 21:24:11 +0000789/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
790 clears the error indicator), 0 otherwise.
791 Should only be called when PyErr_Occurred() is true.
792*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700793int
794_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000795{
796 static PyObject *eintr_int = NULL;
797 PyObject *typ, *val, *tb;
798 PyEnvironmentErrorObject *env_err;
799
800 if (eintr_int == NULL) {
801 eintr_int = PyLong_FromLong(EINTR);
802 assert(eintr_int != NULL);
803 }
804 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
805 return 0;
806 PyErr_Fetch(&typ, &val, &tb);
807 PyErr_NormalizeException(&typ, &val, &tb);
808 env_err = (PyEnvironmentErrorObject *) val;
809 assert(env_err != NULL);
810 if (env_err->myerrno != NULL &&
811 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
812 Py_DECREF(typ);
813 Py_DECREF(val);
814 Py_XDECREF(tb);
815 return 1;
816 }
817 /* This silences any error set by PyObject_RichCompareBool() */
818 PyErr_Restore(typ, val, tb);
819 return 0;
820}
821
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822/*
823 * Shared methods and wrappers
824 */
825
826static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200827buffered_flush_and_rewind_unlocked(buffered *self)
828{
829 PyObject *res;
830
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100831 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200832 if (res == NULL)
833 return NULL;
834 Py_DECREF(res);
835
836 if (self->readable) {
837 /* Rewind the raw stream so that its position corresponds to
838 the current logical position. */
839 Py_off_t n;
840 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
841 _bufferedreader_reset_buf(self);
842 if (n == -1)
843 return NULL;
844 }
845 Py_RETURN_NONE;
846}
847
848static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000849buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850{
851 PyObject *res;
852
853 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000854 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000856 if (!ENTER_BUFFERED(self))
857 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200858 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859 LEAVE_BUFFERED(self)
860
861 return res;
862}
863
864static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000865buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866{
867 Py_ssize_t n = 0;
868 PyObject *res = NULL;
869
870 CHECK_INITIALIZED(self)
871 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
872 return NULL;
873 }
874
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000875 if (!ENTER_BUFFERED(self))
876 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000877
878 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200879 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880 if (res == NULL)
881 goto end;
882 Py_CLEAR(res);
883 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200884 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885
886end:
887 LEAVE_BUFFERED(self)
888 return res;
889}
890
891static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000892buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000893{
894 Py_ssize_t n = -1;
895 PyObject *res;
896
897 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000898 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899 return NULL;
900 }
901 if (n < -1) {
902 PyErr_SetString(PyExc_ValueError,
903 "read length must be positive or -1");
904 return NULL;
905 }
906
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000907 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000908
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000909 if (n == -1) {
910 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000911 if (!ENTER_BUFFERED(self))
912 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000913 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000914 }
915 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000916 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200917 if (res != Py_None)
918 return res;
919 Py_DECREF(res);
920 if (!ENTER_BUFFERED(self))
921 return NULL;
922 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000923 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924
Antoine Pitroue05565e2011-08-20 14:39:23 +0200925 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000926 return res;
927}
928
929static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000930buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931{
932 Py_ssize_t n, have, r;
933 PyObject *res = NULL;
934
935 CHECK_INITIALIZED(self)
936 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
937 return NULL;
938 }
939
940 if (n < 0) {
941 PyErr_SetString(PyExc_ValueError,
942 "read length must be positive");
943 return NULL;
944 }
945 if (n == 0)
946 return PyBytes_FromStringAndSize(NULL, 0);
947
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 /* Return up to n bytes. If at least one byte is buffered, we
949 only return buffered bytes. Otherwise, we do one raw read. */
950
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000951 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
952 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100953 n = Py_MIN(have, n);
954 res = _bufferedreader_read_fast(self, n);
955 assert(res != Py_None);
956 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100958 res = PyBytes_FromStringAndSize(NULL, n);
959 if (res == NULL)
960 return NULL;
961 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200962 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100963 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200964 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000965 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100966 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
967 LEAVE_BUFFERED(self)
968 if (r == -1) {
969 Py_DECREF(res);
970 return NULL;
971 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 if (r == -2)
973 r = 0;
974 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100975 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000976 return res;
977}
978
979static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000980buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200982 Py_buffer buf;
983 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 PyObject *res = NULL;
985
986 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200987
988 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
989 return NULL;
990
991 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
992 if (n > 0) {
993 if (n >= buf.len) {
994 memcpy(buf.buf, self->buffer + self->pos, buf.len);
995 self->pos += buf.len;
996 res = PyLong_FromSsize_t(buf.len);
997 goto end_unlocked;
998 }
999 memcpy(buf.buf, self->buffer + self->pos, n);
1000 self->pos += n;
1001 written = n;
1002 }
1003
1004 if (!ENTER_BUFFERED(self))
1005 goto end_unlocked;
1006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001007 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001008 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001009 if (res == NULL)
1010 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001011 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001013
1014 _bufferedreader_reset_buf(self);
1015 self->pos = 0;
1016
1017 for (remaining = buf.len - written;
1018 remaining > 0;
1019 written += n, remaining -= n) {
1020 /* If remaining bytes is larger than internal buffer size, copy
1021 * directly into caller's buffer. */
1022 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001023 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1024 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001025 }
1026 else {
1027 n = _bufferedreader_fill_buffer(self);
1028 if (n > 0) {
1029 if (n > remaining)
1030 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001031 memcpy((char *) buf.buf + written,
1032 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001033 self->pos += n;
1034 continue; /* short circuit */
1035 }
1036 }
1037 if (n == 0 || (n == -2 && written > 0))
1038 break;
1039 if (n < 0) {
1040 if (n == -2) {
1041 Py_INCREF(Py_None);
1042 res = Py_None;
1043 }
1044 goto end;
1045 }
1046 }
1047 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001048
1049end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001050 LEAVE_BUFFERED(self);
1051end_unlocked:
1052 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001053 return res;
1054}
1055
1056static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001057_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058{
1059 PyObject *res = NULL;
1060 PyObject *chunks = NULL;
1061 Py_ssize_t n, written = 0;
1062 const char *start, *s, *end;
1063
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001064 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001066 /* First, try to find a line in the buffer. This can run unlocked because
1067 the calls to the C API are simple enough that they can't trigger
1068 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001069 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1070 if (limit >= 0 && n > limit)
1071 n = limit;
1072 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001073 s = memchr(start, '\n', n);
1074 if (s != NULL) {
1075 res = PyBytes_FromStringAndSize(start, s - start + 1);
1076 if (res != NULL)
1077 self->pos += s - start + 1;
1078 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079 }
1080 if (n == limit) {
1081 res = PyBytes_FromStringAndSize(start, n);
1082 if (res != NULL)
1083 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001084 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001085 }
1086
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001087 if (!ENTER_BUFFERED(self))
1088 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001091 chunks = PyList_New(0);
1092 if (chunks == NULL)
1093 goto end;
1094 if (n > 0) {
1095 res = PyBytes_FromStringAndSize(start, n);
1096 if (res == NULL)
1097 goto end;
1098 if (PyList_Append(chunks, res) < 0) {
1099 Py_CLEAR(res);
1100 goto end;
1101 }
1102 Py_CLEAR(res);
1103 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001104 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105 if (limit >= 0)
1106 limit -= n;
1107 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001108 if (self->writable) {
1109 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1110 if (r == NULL)
1111 goto end;
1112 Py_DECREF(r);
1113 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001114
1115 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001116 _bufferedreader_reset_buf(self);
1117 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001118 if (n == -1)
1119 goto end;
1120 if (n <= 0)
1121 break;
1122 if (limit >= 0 && n > limit)
1123 n = limit;
1124 start = self->buffer;
1125 end = start + n;
1126 s = start;
1127 while (s < end) {
1128 if (*s++ == '\n') {
1129 res = PyBytes_FromStringAndSize(start, s - start);
1130 if (res == NULL)
1131 goto end;
1132 self->pos = s - start;
1133 goto found;
1134 }
1135 }
1136 res = PyBytes_FromStringAndSize(start, n);
1137 if (res == NULL)
1138 goto end;
1139 if (n == limit) {
1140 self->pos = n;
1141 break;
1142 }
1143 if (PyList_Append(chunks, res) < 0) {
1144 Py_CLEAR(res);
1145 goto end;
1146 }
1147 Py_CLEAR(res);
1148 written += n;
1149 if (limit >= 0)
1150 limit -= n;
1151 }
1152found:
1153 if (res != NULL && PyList_Append(chunks, res) < 0) {
1154 Py_CLEAR(res);
1155 goto end;
1156 }
1157 Py_CLEAR(res);
1158 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1159
1160end:
1161 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001162end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001163 Py_XDECREF(chunks);
1164 return res;
1165}
1166
1167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001168buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001169{
1170 Py_ssize_t limit = -1;
1171
1172 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001173 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001175 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176}
1177
1178
1179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001180buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001181{
1182 Py_off_t pos;
1183
1184 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001185 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186 if (pos == -1)
1187 return NULL;
1188 pos -= RAW_OFFSET(self);
1189 /* TODO: sanity check (pos >= 0) */
1190 return PyLong_FromOff_t(pos);
1191}
1192
1193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001194buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001195{
1196 Py_off_t target, n;
1197 int whence = 0;
1198 PyObject *targetobj, *res = NULL;
1199
1200 CHECK_INITIALIZED(self)
1201 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1202 return NULL;
1203 }
Jesus Cea94363612012-06-22 18:32:07 +02001204
1205 /* Do some error checking instead of trusting OS 'seek()'
1206 ** error detection, just in case.
1207 */
1208 if ((whence < 0 || whence >2)
1209#ifdef SEEK_HOLE
1210 && (whence != SEEK_HOLE)
1211#endif
1212#ifdef SEEK_DATA
1213 && (whence != SEEK_DATA)
1214#endif
1215 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001216 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001217 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001218 return NULL;
1219 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001220
1221 CHECK_CLOSED(self, "seek of closed file")
1222
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001223 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1224 return NULL;
1225
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1227 if (target == -1 && PyErr_Occurred())
1228 return NULL;
1229
Jesus Cea94363612012-06-22 18:32:07 +02001230 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1231 buffer. Other whence values must be managed without this optimization.
1232 Some Operating Systems can provide additional values, like
1233 SEEK_HOLE/SEEK_DATA. */
1234 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001235 Py_off_t current, avail;
1236 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001237 so as to return quickly if possible. Also, we needn't take the
1238 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001240 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1241 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001242 current = RAW_TELL(self);
1243 avail = READAHEAD(self);
1244 if (avail > 0) {
1245 Py_off_t offset;
1246 if (whence == 0)
1247 offset = target - (current - RAW_OFFSET(self));
1248 else
1249 offset = target;
1250 if (offset >= -self->pos && offset <= avail) {
1251 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001252 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001253 }
1254 }
1255 }
1256
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001257 if (!ENTER_BUFFERED(self))
1258 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001259
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260 /* Fallback: invoke raw seek() method and clear buffer */
1261 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001262 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 if (res == NULL)
1264 goto end;
1265 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001266 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001267 }
1268
1269 /* TODO: align on block boundary and read buffer if needed? */
1270 if (whence == 1)
1271 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001272 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 if (n == -1)
1274 goto end;
1275 self->raw_pos = -1;
1276 res = PyLong_FromOff_t(n);
1277 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001278 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001279
1280end:
1281 LEAVE_BUFFERED(self)
1282 return res;
1283}
1284
1285static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001286buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001287{
1288 PyObject *pos = Py_None;
1289 PyObject *res = NULL;
1290
1291 CHECK_INITIALIZED(self)
1292 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1293 return NULL;
1294 }
1295
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001296 if (!ENTER_BUFFERED(self))
1297 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298
1299 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001300 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 if (res == NULL)
1302 goto end;
1303 Py_CLEAR(res);
1304 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001305 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1306 if (res == NULL)
1307 goto end;
1308 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001309 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 PyErr_Clear();
1311
1312end:
1313 LEAVE_BUFFERED(self)
1314 return res;
1315}
1316
1317static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001318buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319{
1320 PyObject *line;
1321 PyTypeObject *tp;
1322
1323 CHECK_INITIALIZED(self);
1324
1325 tp = Py_TYPE(self);
1326 if (tp == &PyBufferedReader_Type ||
1327 tp == &PyBufferedRandom_Type) {
1328 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001329 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330 }
1331 else {
1332 line = PyObject_CallMethodObjArgs((PyObject *)self,
1333 _PyIO_str_readline, NULL);
1334 if (line && !PyBytes_Check(line)) {
1335 PyErr_Format(PyExc_IOError,
1336 "readline() should have returned a bytes object, "
1337 "not '%.200s'", Py_TYPE(line)->tp_name);
1338 Py_DECREF(line);
1339 return NULL;
1340 }
1341 }
1342
1343 if (line == NULL)
1344 return NULL;
1345
1346 if (PyBytes_GET_SIZE(line) == 0) {
1347 /* Reached EOF or would have blocked */
1348 Py_DECREF(line);
1349 return NULL;
1350 }
1351
1352 return line;
1353}
1354
Antoine Pitrou716c4442009-05-23 19:04:03 +00001355static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001356buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001357{
1358 PyObject *nameobj, *res;
1359
Martin v. Löwis767046a2011-10-14 15:35:36 +02001360 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001361 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001362 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001363 PyErr_Clear();
1364 else
1365 return NULL;
1366 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1367 }
1368 else {
1369 res = PyUnicode_FromFormat("<%s name=%R>",
1370 Py_TYPE(self)->tp_name, nameobj);
1371 Py_DECREF(nameobj);
1372 }
1373 return res;
1374}
1375
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001376/*
1377 * class BufferedReader
1378 */
1379
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001380PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381 "Create a new buffered reader using the given readable raw IO object.");
1382
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001383static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001384{
1385 self->read_end = -1;
1386}
1387
1388static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001389bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001390{
1391 char *kwlist[] = {"raw", "buffer_size", NULL};
1392 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1393 PyObject *raw;
1394
1395 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001396 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001397
1398 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1399 &raw, &buffer_size)) {
1400 return -1;
1401 }
1402
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001403 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001404 return -1;
1405
1406 Py_CLEAR(self->raw);
1407 Py_INCREF(raw);
1408 self->raw = raw;
1409 self->buffer_size = buffer_size;
1410 self->readable = 1;
1411 self->writable = 0;
1412
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001413 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001414 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001415 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001417 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1418 Py_TYPE(raw) == &PyFileIO_Type);
1419
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001420 self->ok = 1;
1421 return 0;
1422}
1423
1424static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001425_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001426{
1427 Py_buffer buf;
1428 PyObject *memobj, *res;
1429 Py_ssize_t n;
1430 /* NOTE: the buffer needn't be released as its object is NULL. */
1431 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1432 return -1;
1433 memobj = PyMemoryView_FromBuffer(&buf);
1434 if (memobj == NULL)
1435 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001436 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1437 occurs so we needn't do it ourselves.
1438 We then retry reading, ignoring the signal if no handler has
1439 raised (see issue #10956).
1440 */
1441 do {
1442 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001443 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001444 Py_DECREF(memobj);
1445 if (res == NULL)
1446 return -1;
1447 if (res == Py_None) {
1448 /* Non-blocking stream would have blocked. Special return code! */
1449 Py_DECREF(res);
1450 return -2;
1451 }
1452 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1453 Py_DECREF(res);
1454 if (n < 0 || n > len) {
1455 PyErr_Format(PyExc_IOError,
1456 "raw readinto() returned invalid length %zd "
1457 "(should have been between 0 and %zd)", n, len);
1458 return -1;
1459 }
1460 if (n > 0 && self->abs_pos != -1)
1461 self->abs_pos += n;
1462 return n;
1463}
1464
1465static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001466_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001467{
1468 Py_ssize_t start, len, n;
1469 if (VALID_READ_BUFFER(self))
1470 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1471 else
1472 start = 0;
1473 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001474 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001475 if (n <= 0)
1476 return n;
1477 self->read_end = start + n;
1478 self->raw_pos = start + n;
1479 return n;
1480}
1481
1482static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001483_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001485 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001486 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001487
1488 /* First copy what we have in the current buffer. */
1489 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1490 if (current_size) {
1491 data = PyBytes_FromStringAndSize(
1492 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001493 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001494 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001495 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001496 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001497 /* We're going past the buffer's bounds, flush it */
1498 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001499 tmp = buffered_flush_and_rewind_unlocked(self);
1500 if (tmp == NULL)
1501 goto cleanup;
1502 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001503 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001504 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001505
1506 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001507 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1508 if (tmp == NULL)
1509 goto cleanup;
1510 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001511 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001512 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001513 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001514 if (tmp == Py_None) {
1515 if (current_size == 0) {
1516 res = Py_None;
1517 goto cleanup;
1518 } else {
1519 res = data;
1520 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001521 }
1522 }
1523 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001524 PyBytes_Concat(&data, tmp);
1525 res = data;
1526 goto cleanup;
1527 }
1528 else {
1529 res = tmp;
1530 goto cleanup;
1531 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001532 }
1533
1534 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001535 if (chunks == NULL)
1536 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001537
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001538 while (1) {
1539 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001540 if (PyList_Append(chunks, data) < 0)
1541 goto cleanup;
1542 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001543 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001544
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001545 /* Read until EOF or until read() would block. */
1546 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001547 if (data == NULL)
1548 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001549 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001550 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001551 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001552 }
1553 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1554 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001555 res = data;
1556 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001557 }
1558 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001559 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1560 res = tmp;
1561 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001562 }
1563 }
1564 current_size += PyBytes_GET_SIZE(data);
1565 if (self->abs_pos != -1)
1566 self->abs_pos += PyBytes_GET_SIZE(data);
1567 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001568cleanup:
1569 /* res is either NULL or a borrowed ref */
1570 Py_XINCREF(res);
1571 Py_XDECREF(data);
1572 Py_XDECREF(tmp);
1573 Py_XDECREF(chunks);
1574 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001575}
1576
1577/* Read n bytes from the buffer if it can, otherwise return None.
1578 This function is simple enough that it can run unlocked. */
1579static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001580_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581{
1582 Py_ssize_t current_size;
1583
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001584 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1585 if (n <= current_size) {
1586 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001587 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1588 if (res != NULL)
1589 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001590 return res;
1591 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001592 Py_RETURN_NONE;
1593}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001594
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595/* Generic read function: read from the stream until enough bytes are read,
1596 * or until an EOF occurs or until read() would block.
1597 */
1598static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001599_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001600{
1601 PyObject *res = NULL;
1602 Py_ssize_t current_size, remaining, written;
1603 char *out;
1604
1605 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1606 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001607 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001609 res = PyBytes_FromStringAndSize(NULL, n);
1610 if (res == NULL)
1611 goto error;
1612 out = PyBytes_AS_STRING(res);
1613 remaining = n;
1614 written = 0;
1615 if (current_size > 0) {
1616 memcpy(out, self->buffer + self->pos, current_size);
1617 remaining -= current_size;
1618 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001619 self->pos += current_size;
1620 }
1621 /* Flush the write buffer if necessary */
1622 if (self->writable) {
1623 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1624 if (r == NULL)
1625 goto error;
1626 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001627 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001628 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001629 while (remaining > 0) {
1630 /* We want to read a whole block at the end into buffer.
1631 If we had readv() we could do this in one pass. */
1632 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1633 if (r == 0)
1634 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001635 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001636 if (r == -1)
1637 goto error;
1638 if (r == 0 || r == -2) {
1639 /* EOF occurred or read() would block. */
1640 if (r == 0 || written > 0) {
1641 if (_PyBytes_Resize(&res, written))
1642 goto error;
1643 return res;
1644 }
1645 Py_DECREF(res);
1646 Py_INCREF(Py_None);
1647 return Py_None;
1648 }
1649 remaining -= r;
1650 written += r;
1651 }
1652 assert(remaining <= self->buffer_size);
1653 self->pos = 0;
1654 self->raw_pos = 0;
1655 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001656 /* NOTE: when the read is satisfied, we avoid issuing any additional
1657 reads, which could block indefinitely (e.g. on a socket).
1658 See issue #9550. */
1659 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001660 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001661 if (r == -1)
1662 goto error;
1663 if (r == 0 || r == -2) {
1664 /* EOF occurred or read() would block. */
1665 if (r == 0 || written > 0) {
1666 if (_PyBytes_Resize(&res, written))
1667 goto error;
1668 return res;
1669 }
1670 Py_DECREF(res);
1671 Py_INCREF(Py_None);
1672 return Py_None;
1673 }
1674 if (remaining > r) {
1675 memcpy(out + written, self->buffer + self->pos, r);
1676 written += r;
1677 self->pos += r;
1678 remaining -= r;
1679 }
1680 else if (remaining > 0) {
1681 memcpy(out + written, self->buffer + self->pos, remaining);
1682 written += remaining;
1683 self->pos += remaining;
1684 remaining = 0;
1685 }
1686 if (remaining == 0)
1687 break;
1688 }
1689
1690 return res;
1691
1692error:
1693 Py_XDECREF(res);
1694 return NULL;
1695}
1696
1697static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001698_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001699{
1700 Py_ssize_t have, r;
1701
1702 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1703 /* Constraints:
1704 1. we don't want to advance the file position.
1705 2. we don't want to lose block alignment, so we can't shift the buffer
1706 to make some place.
1707 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1708 */
1709 if (have > 0) {
1710 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1711 }
1712
1713 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001714 _bufferedreader_reset_buf(self);
1715 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001716 if (r == -1)
1717 return NULL;
1718 if (r == -2)
1719 r = 0;
1720 self->pos = 0;
1721 return PyBytes_FromStringAndSize(self->buffer, r);
1722}
1723
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001724static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001725 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001726 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1727 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1728 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1729 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1730 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1731 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1732 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1733 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001734 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001735 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001736
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001737 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1738 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1739 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001740 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001741 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1742 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1743 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1744 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001745 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746 {NULL, NULL}
1747};
1748
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001749static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001750 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001751 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001752 {NULL}
1753};
1754
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001755static PyGetSetDef bufferedreader_getset[] = {
1756 {"closed", (getter)buffered_closed_get, NULL, NULL},
1757 {"name", (getter)buffered_name_get, NULL, NULL},
1758 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001759 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760};
1761
1762
1763PyTypeObject PyBufferedReader_Type = {
1764 PyVarObject_HEAD_INIT(NULL, 0)
1765 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001766 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001768 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769 0, /*tp_print*/
1770 0, /*tp_getattr*/
1771 0, /*tp_setattr*/
1772 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001773 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774 0, /*tp_as_number*/
1775 0, /*tp_as_sequence*/
1776 0, /*tp_as_mapping*/
1777 0, /*tp_hash */
1778 0, /*tp_call*/
1779 0, /*tp_str*/
1780 0, /*tp_getattro*/
1781 0, /*tp_setattro*/
1782 0, /*tp_as_buffer*/
1783 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001784 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001785 bufferedreader_doc, /* tp_doc */
1786 (traverseproc)buffered_traverse, /* tp_traverse */
1787 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001789 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001791 (iternextfunc)buffered_iternext, /* tp_iternext */
1792 bufferedreader_methods, /* tp_methods */
1793 bufferedreader_members, /* tp_members */
1794 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 0, /* tp_base */
1796 0, /* tp_dict */
1797 0, /* tp_descr_get */
1798 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 offsetof(buffered, dict), /* tp_dictoffset */
1800 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 0, /* tp_alloc */
1802 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001803 0, /* tp_free */
1804 0, /* tp_is_gc */
1805 0, /* tp_bases */
1806 0, /* tp_mro */
1807 0, /* tp_cache */
1808 0, /* tp_subclasses */
1809 0, /* tp_weaklist */
1810 0, /* tp_del */
1811 0, /* tp_version_tag */
1812 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813};
1814
1815
Benjamin Peterson59406a92009-03-26 17:10:29 +00001816
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001817/*
1818 * class BufferedWriter
1819 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001820PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001821 "A buffer for a writeable sequential RawIO object.\n"
1822 "\n"
1823 "The constructor creates a BufferedWriter for the given writeable raw\n"
1824 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001825 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001826 );
1827
1828static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001829_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830{
1831 self->write_pos = 0;
1832 self->write_end = -1;
1833}
1834
1835static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001836bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001837{
Florent Xicluna109d5732012-07-07 17:03:22 +02001838 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001839 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001840 PyObject *raw;
1841
1842 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001843 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844
R David Murray9f10f562013-02-23 22:07:55 -05001845 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001846 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847 return -1;
1848 }
1849
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001850 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 return -1;
1852
1853 Py_CLEAR(self->raw);
1854 Py_INCREF(raw);
1855 self->raw = raw;
1856 self->readable = 0;
1857 self->writable = 1;
1858
1859 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001860 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001861 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001862 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863 self->pos = 0;
1864
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001865 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1866 Py_TYPE(raw) == &PyFileIO_Type);
1867
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001868 self->ok = 1;
1869 return 0;
1870}
1871
1872static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001873_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001874{
1875 Py_buffer buf;
1876 PyObject *memobj, *res;
1877 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001878 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001879 /* NOTE: the buffer needn't be released as its object is NULL. */
1880 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1881 return -1;
1882 memobj = PyMemoryView_FromBuffer(&buf);
1883 if (memobj == NULL)
1884 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001885 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1886 occurs so we needn't do it ourselves.
1887 We then retry writing, ignoring the signal if no handler has
1888 raised (see issue #10956).
1889 */
1890 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001891 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001892 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001893 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001894 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001895 Py_DECREF(memobj);
1896 if (res == NULL)
1897 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001898 if (res == Py_None) {
1899 /* Non-blocking stream would have blocked. Special return code!
1900 Being paranoid we reset errno in case it is changed by code
1901 triggered by a decref. errno is used by _set_BlockingIOError(). */
1902 Py_DECREF(res);
1903 errno = errnum;
1904 return -2;
1905 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1907 Py_DECREF(res);
1908 if (n < 0 || n > len) {
1909 PyErr_Format(PyExc_IOError,
1910 "raw write() returned invalid length %zd "
1911 "(should have been between 0 and %zd)", n, len);
1912 return -1;
1913 }
1914 if (n > 0 && self->abs_pos != -1)
1915 self->abs_pos += n;
1916 return n;
1917}
1918
1919/* `restore_pos` is 1 if we need to restore the raw stream position at
1920 the end, 0 otherwise. */
1921static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001922_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923{
1924 Py_ssize_t written = 0;
1925 Py_off_t n, rewind;
1926
1927 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1928 goto end;
1929 /* First, rewind */
1930 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1931 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001932 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933 if (n < 0) {
1934 goto error;
1935 }
1936 self->raw_pos -= rewind;
1937 }
1938 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001939 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001940 self->buffer + self->write_pos,
1941 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1942 Py_off_t, Py_ssize_t));
1943 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001944 goto error;
1945 }
1946 else if (n == -2) {
1947 _set_BlockingIOError("write could not complete without blocking",
1948 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 goto error;
1950 }
1951 self->write_pos += n;
1952 self->raw_pos = self->write_pos;
1953 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001954 /* Partial writes can return successfully when interrupted by a
1955 signal (see write(2)). We must run signal handlers before
1956 blocking another time, possibly indefinitely. */
1957 if (PyErr_CheckSignals() < 0)
1958 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001959 }
1960
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001961 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001962
1963end:
1964 Py_RETURN_NONE;
1965
1966error:
1967 return NULL;
1968}
1969
1970static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001971bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972{
1973 PyObject *res = NULL;
1974 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001975 Py_ssize_t written, avail, remaining;
1976 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001977
1978 CHECK_INITIALIZED(self)
1979 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1980 return NULL;
1981 }
1982
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001983 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001984 PyErr_SetString(PyExc_ValueError, "write to closed file");
1985 PyBuffer_Release(&buf);
1986 return NULL;
1987 }
1988
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001989 if (!ENTER_BUFFERED(self)) {
1990 PyBuffer_Release(&buf);
1991 return NULL;
1992 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993
1994 /* Fast path: the data to write can be fully buffered. */
1995 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1996 self->pos = 0;
1997 self->raw_pos = 0;
1998 }
1999 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2000 if (buf.len <= avail) {
2001 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002002 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003 self->write_pos = self->pos;
2004 }
2005 ADJUST_POSITION(self, self->pos + buf.len);
2006 if (self->pos > self->write_end)
2007 self->write_end = self->pos;
2008 written = buf.len;
2009 goto end;
2010 }
2011
2012 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002013 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002015 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002016 if (w == NULL)
2017 goto error;
2018 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002019 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 /* Make some place by shifting the buffer. */
2021 assert(VALID_WRITE_BUFFER(self));
2022 memmove(self->buffer, self->buffer + self->write_pos,
2023 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2024 Py_off_t, Py_ssize_t));
2025 self->write_end -= self->write_pos;
2026 self->raw_pos -= self->write_pos;
2027 self->pos -= self->write_pos;
2028 self->write_pos = 0;
2029 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2030 Py_off_t, Py_ssize_t);
2031 if (buf.len <= avail) {
2032 /* Everything can be buffered */
2033 PyErr_Clear();
2034 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2035 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002036 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 written = buf.len;
2038 goto end;
2039 }
2040 /* Buffer as much as possible. */
2041 memcpy(self->buffer + self->write_end, buf.buf, avail);
2042 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002043 self->pos += avail;
2044 /* XXX Modifying the existing exception e using the pointer w
2045 will change e.characters_written but not e.args[2].
2046 Therefore we just replace with a new error. */
2047 _set_BlockingIOError("write could not complete without blocking",
2048 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002049 goto error;
2050 }
2051 Py_CLEAR(res);
2052
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002053 /* Adjust the raw stream position if it is away from the logical stream
2054 position. This happens if the read buffer has been filled but not
2055 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2056 the raw stream by itself).
2057 Fixes issue #6629.
2058 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002059 offset = RAW_OFFSET(self);
2060 if (offset != 0) {
2061 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002062 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002063 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002064 }
2065
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 /* Then write buf itself. At this point the buffer has been emptied. */
2067 remaining = buf.len;
2068 written = 0;
2069 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002070 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071 self, (char *) buf.buf + written, buf.len - written);
2072 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002073 goto error;
2074 } else if (n == -2) {
2075 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076 if (remaining > self->buffer_size) {
2077 /* Can't buffer everything, still buffer as much as possible */
2078 memcpy(self->buffer,
2079 (char *) buf.buf + written, self->buffer_size);
2080 self->raw_pos = 0;
2081 ADJUST_POSITION(self, self->buffer_size);
2082 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002083 written += self->buffer_size;
2084 _set_BlockingIOError("write could not complete without "
2085 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086 goto error;
2087 }
2088 PyErr_Clear();
2089 break;
2090 }
2091 written += n;
2092 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002093 /* Partial writes can return successfully when interrupted by a
2094 signal (see write(2)). We must run signal handlers before
2095 blocking another time, possibly indefinitely. */
2096 if (PyErr_CheckSignals() < 0)
2097 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098 }
2099 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 if (remaining > 0) {
2102 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2103 written += remaining;
2104 }
2105 self->write_pos = 0;
2106 /* TODO: sanity check (remaining >= 0) */
2107 self->write_end = remaining;
2108 ADJUST_POSITION(self, remaining);
2109 self->raw_pos = 0;
2110
2111end:
2112 res = PyLong_FromSsize_t(written);
2113
2114error:
2115 LEAVE_BUFFERED(self)
2116 PyBuffer_Release(&buf);
2117 return res;
2118}
2119
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002122 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2123 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2124 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2125 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2126 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2127 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2128 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002129 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002130 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002132 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2133 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2134 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2135 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2136 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002137 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138 {NULL, NULL}
2139};
2140
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002141static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002142 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002143 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002144 {NULL}
2145};
2146
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147static PyGetSetDef bufferedwriter_getset[] = {
2148 {"closed", (getter)buffered_closed_get, NULL, NULL},
2149 {"name", (getter)buffered_name_get, NULL, NULL},
2150 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002151 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152};
2153
2154
2155PyTypeObject PyBufferedWriter_Type = {
2156 PyVarObject_HEAD_INIT(NULL, 0)
2157 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002158 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002160 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161 0, /*tp_print*/
2162 0, /*tp_getattr*/
2163 0, /*tp_setattr*/
2164 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 0, /*tp_as_number*/
2167 0, /*tp_as_sequence*/
2168 0, /*tp_as_mapping*/
2169 0, /*tp_hash */
2170 0, /*tp_call*/
2171 0, /*tp_str*/
2172 0, /*tp_getattro*/
2173 0, /*tp_setattro*/
2174 0, /*tp_as_buffer*/
2175 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002176 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002177 bufferedwriter_doc, /* tp_doc */
2178 (traverseproc)buffered_traverse, /* tp_traverse */
2179 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002181 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182 0, /* tp_iter */
2183 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184 bufferedwriter_methods, /* tp_methods */
2185 bufferedwriter_members, /* tp_members */
2186 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187 0, /* tp_base */
2188 0, /* tp_dict */
2189 0, /* tp_descr_get */
2190 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002191 offsetof(buffered, dict), /* tp_dictoffset */
2192 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193 0, /* tp_alloc */
2194 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002195 0, /* tp_free */
2196 0, /* tp_is_gc */
2197 0, /* tp_bases */
2198 0, /* tp_mro */
2199 0, /* tp_cache */
2200 0, /* tp_subclasses */
2201 0, /* tp_weaklist */
2202 0, /* tp_del */
2203 0, /* tp_version_tag */
2204 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205};
2206
2207
2208
2209/*
2210 * BufferedRWPair
2211 */
2212
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002213PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214 "A buffered reader and writer object together.\n"
2215 "\n"
2216 "A buffered reader object and buffered writer object put together to\n"
2217 "form a sequential IO object that can read and write. This is typically\n"
2218 "used with a socket or two-way pipe.\n"
2219 "\n"
2220 "reader and writer are RawIOBase objects that are readable and\n"
2221 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002222 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223 );
2224
2225/* XXX The usefulness of this (compared to having two separate IO objects) is
2226 * questionable.
2227 */
2228
2229typedef struct {
2230 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002231 buffered *reader;
2232 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233 PyObject *dict;
2234 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002235} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236
2237static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002238bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239{
2240 PyObject *reader, *writer;
2241 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242
Florent Xicluna109d5732012-07-07 17:03:22 +02002243 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2244 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245 return -1;
2246 }
2247
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002248 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251 return -1;
2252
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002253 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002254 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255 if (self->reader == NULL)
2256 return -1;
2257
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002258 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002259 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260 if (self->writer == NULL) {
2261 Py_CLEAR(self->reader);
2262 return -1;
2263 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002264
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265 return 0;
2266}
2267
2268static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002269bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270{
2271 Py_VISIT(self->dict);
2272 return 0;
2273}
2274
2275static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002276bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277{
2278 Py_CLEAR(self->reader);
2279 Py_CLEAR(self->writer);
2280 Py_CLEAR(self->dict);
2281 return 0;
2282}
2283
2284static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002285bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286{
2287 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002288 if (self->weakreflist != NULL)
2289 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290 Py_CLEAR(self->reader);
2291 Py_CLEAR(self->writer);
2292 Py_CLEAR(self->dict);
2293 Py_TYPE(self)->tp_free((PyObject *) self);
2294}
2295
2296static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002297_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002299 PyObject *func, *ret;
2300 if (self == NULL) {
2301 PyErr_SetString(PyExc_ValueError,
2302 "I/O operation on uninitialized object");
2303 return NULL;
2304 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002306 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002308 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002309 return NULL;
2310 }
2311
2312 ret = PyObject_CallObject(func, args);
2313 Py_DECREF(func);
2314 return ret;
2315}
2316
2317static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002318bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002320 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002321}
2322
2323static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002324bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002325{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002326 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002327}
2328
2329static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002330bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002332 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002333}
2334
2335static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002336bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002337{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002338 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002339}
2340
2341static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002342bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002343{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002344 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002345}
2346
2347static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002348bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002349{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002350 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002351}
2352
2353static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002354bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002355{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002356 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002357}
2358
2359static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002360bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002362 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002363}
2364
2365static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002366bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002367{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002368 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002369 if (ret == NULL)
2370 return NULL;
2371 Py_DECREF(ret);
2372
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002373 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002374}
2375
2376static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002377bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002378{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002379 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002380
2381 if (ret != Py_False) {
2382 /* either True or exception */
2383 return ret;
2384 }
2385 Py_DECREF(ret);
2386
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002387 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388}
2389
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002390static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002391bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002392{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002393 if (self->writer == NULL) {
2394 PyErr_SetString(PyExc_RuntimeError,
2395 "the BufferedRWPair object is being garbage-collected");
2396 return NULL;
2397 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002398 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2399}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002400
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002401static PyMethodDef bufferedrwpair_methods[] = {
2402 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2403 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2404 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2405 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002406
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002407 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2408 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002409
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002410 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2411 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002412
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002413 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2414 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002415
Antoine Pitrou243757e2010-11-05 21:15:39 +00002416 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2417
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 {NULL, NULL}
2419};
2420
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002421static PyGetSetDef bufferedrwpair_getset[] = {
2422 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002423 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002424};
2425
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426PyTypeObject PyBufferedRWPair_Type = {
2427 PyVarObject_HEAD_INIT(NULL, 0)
2428 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002431 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432 0, /*tp_print*/
2433 0, /*tp_getattr*/
2434 0, /*tp_setattr*/
2435 0, /*tp_compare */
2436 0, /*tp_repr*/
2437 0, /*tp_as_number*/
2438 0, /*tp_as_sequence*/
2439 0, /*tp_as_mapping*/
2440 0, /*tp_hash */
2441 0, /*tp_call*/
2442 0, /*tp_str*/
2443 0, /*tp_getattro*/
2444 0, /*tp_setattro*/
2445 0, /*tp_as_buffer*/
2446 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002447 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002448 bufferedrwpair_doc, /* tp_doc */
2449 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2450 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002451 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002452 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453 0, /* tp_iter */
2454 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002455 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002457 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458 0, /* tp_base */
2459 0, /* tp_dict */
2460 0, /* tp_descr_get */
2461 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002462 offsetof(rwpair, dict), /* tp_dictoffset */
2463 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002464 0, /* tp_alloc */
2465 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002466 0, /* tp_free */
2467 0, /* tp_is_gc */
2468 0, /* tp_bases */
2469 0, /* tp_mro */
2470 0, /* tp_cache */
2471 0, /* tp_subclasses */
2472 0, /* tp_weaklist */
2473 0, /* tp_del */
2474 0, /* tp_version_tag */
2475 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002476};
2477
2478
2479
2480/*
2481 * BufferedRandom
2482 */
2483
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002484PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485 "A buffered interface to random access streams.\n"
2486 "\n"
2487 "The constructor creates a reader and writer for a seekable stream,\n"
2488 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002489 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002490 );
2491
2492static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002493bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494{
Florent Xicluna109d5732012-07-07 17:03:22 +02002495 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002496 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002497 PyObject *raw;
2498
2499 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002500 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002501
R David Murray9f10f562013-02-23 22:07:55 -05002502 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002503 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002504 return -1;
2505 }
2506
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002507 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002508 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002509 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002510 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002511 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002512 return -1;
2513
2514 Py_CLEAR(self->raw);
2515 Py_INCREF(raw);
2516 self->raw = raw;
2517 self->buffer_size = buffer_size;
2518 self->readable = 1;
2519 self->writable = 1;
2520
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002521 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002522 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002523 _bufferedreader_reset_buf(self);
2524 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002525 self->pos = 0;
2526
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002527 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2528 Py_TYPE(raw) == &PyFileIO_Type);
2529
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002530 self->ok = 1;
2531 return 0;
2532}
2533
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002534static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2537 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2538 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2539 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2540 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2541 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2542 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002543 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002544 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002545
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002546 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002547
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002548 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2549 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2550 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2551 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2552 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2553 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2554 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2555 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2556 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002557 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002558 {NULL, NULL}
2559};
2560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002561static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002562 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002563 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002564 {NULL}
2565};
2566
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567static PyGetSetDef bufferedrandom_getset[] = {
2568 {"closed", (getter)buffered_closed_get, NULL, NULL},
2569 {"name", (getter)buffered_name_get, NULL, NULL},
2570 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002571 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572};
2573
2574
2575PyTypeObject PyBufferedRandom_Type = {
2576 PyVarObject_HEAD_INIT(NULL, 0)
2577 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002578 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002581 0, /*tp_print*/
2582 0, /*tp_getattr*/
2583 0, /*tp_setattr*/
2584 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002585 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586 0, /*tp_as_number*/
2587 0, /*tp_as_sequence*/
2588 0, /*tp_as_mapping*/
2589 0, /*tp_hash */
2590 0, /*tp_call*/
2591 0, /*tp_str*/
2592 0, /*tp_getattro*/
2593 0, /*tp_setattro*/
2594 0, /*tp_as_buffer*/
2595 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002596 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002597 bufferedrandom_doc, /* tp_doc */
2598 (traverseproc)buffered_traverse, /* tp_traverse */
2599 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002600 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002602 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002603 (iternextfunc)buffered_iternext, /* tp_iternext */
2604 bufferedrandom_methods, /* tp_methods */
2605 bufferedrandom_members, /* tp_members */
2606 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002607 0, /* tp_base */
2608 0, /*tp_dict*/
2609 0, /* tp_descr_get */
2610 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002611 offsetof(buffered, dict), /*tp_dictoffset*/
2612 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613 0, /* tp_alloc */
2614 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002615 0, /* tp_free */
2616 0, /* tp_is_gc */
2617 0, /* tp_bases */
2618 0, /* tp_mro */
2619 0, /* tp_cache */
2620 0, /* tp_subclasses */
2621 0, /* tp_weaklist */
2622 0, /* tp_del */
2623 0, /* tp_version_tag */
2624 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002625};