blob: 3606cc8fe090bdf0ae1ead2a61eab6f385dfca25 [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{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200303 int relax_locking;
304 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000305 if (self->owner == PyThread_get_thread_ident()) {
306 PyErr_Format(PyExc_RuntimeError,
307 "reentrant call inside %R", self);
308 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000309 }
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200310 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000311 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200312 if (!relax_locking)
313 st = PyThread_acquire_lock(self->lock, 1);
314 else {
315 /* When finalizing, we don't want a deadlock to happen with daemon
316 * threads abruptly shut down while they owned the lock.
317 * Therefore, only wait for a grace period (1 s.).
318 * Note that non-daemon threads have already exited here, so this
319 * shouldn't affect carefully written threaded I/O code.
320 */
321 st = PyThread_acquire_lock_timed(self->lock, 1e6, 0);
322 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000323 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200324 if (relax_locking && st != PY_LOCK_ACQUIRED) {
325 PyObject *msgobj = PyUnicode_FromFormat(
326 "could not acquire lock for %A at interpreter "
327 "shutdown, possibly due to daemon threads",
328 (PyObject *) self);
329 char *msg = PyUnicode_AsUTF8(msgobj);
330 Py_FatalError(msg);
331 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000332 return 1;
333}
334
335#define ENTER_BUFFERED(self) \
336 ( (PyThread_acquire_lock(self->lock, 0) ? \
337 1 : _enter_buffered_busy(self)) \
338 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339
340#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000341 do { \
342 self->owner = 0; \
343 PyThread_release_lock(self->lock); \
344 } while(0);
345
Georg Brandldfd73442009-04-05 11:47:34 +0000346#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000347#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000348#define LEAVE_BUFFERED(self)
349#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000350
351#define CHECK_INITIALIZED(self) \
352 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000353 if (self->detached) { \
354 PyErr_SetString(PyExc_ValueError, \
355 "raw stream has been detached"); \
356 } else { \
357 PyErr_SetString(PyExc_ValueError, \
358 "I/O operation on uninitialized object"); \
359 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000360 return NULL; \
361 }
362
363#define CHECK_INITIALIZED_INT(self) \
364 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000365 if (self->detached) { \
366 PyErr_SetString(PyExc_ValueError, \
367 "raw stream has been detached"); \
368 } else { \
369 PyErr_SetString(PyExc_ValueError, \
370 "I/O operation on uninitialized object"); \
371 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000372 return -1; \
373 }
374
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000375#define IS_CLOSED(self) \
376 (self->fast_closed_checks \
377 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000378 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000379
380#define CHECK_CLOSED(self, error_msg) \
381 if (IS_CLOSED(self)) { \
382 PyErr_SetString(PyExc_ValueError, error_msg); \
383 return NULL; \
384 }
385
386
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387#define VALID_READ_BUFFER(self) \
388 (self->readable && self->read_end != -1)
389
390#define VALID_WRITE_BUFFER(self) \
391 (self->writable && self->write_end != -1)
392
393#define ADJUST_POSITION(self, _new_pos) \
394 do { \
395 self->pos = _new_pos; \
396 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
397 self->read_end = self->pos; \
398 } while(0)
399
400#define READAHEAD(self) \
401 ((self->readable && VALID_READ_BUFFER(self)) \
402 ? (self->read_end - self->pos) : 0)
403
404#define RAW_OFFSET(self) \
405 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
406 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
407
408#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000409 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000410
411#define MINUS_LAST_BLOCK(self, size) \
412 (self->buffer_mask ? \
413 (size & ~self->buffer_mask) : \
414 (self->buffer_size * (size / self->buffer_size)))
415
416
417static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000418buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000419{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200420 self->finalizing = 1;
421 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422 return;
423 _PyObject_GC_UNTRACK(self);
424 self->ok = 0;
425 if (self->weakreflist != NULL)
426 PyObject_ClearWeakRefs((PyObject *)self);
427 Py_CLEAR(self->raw);
428 if (self->buffer) {
429 PyMem_Free(self->buffer);
430 self->buffer = NULL;
431 }
Georg Brandldfd73442009-04-05 11:47:34 +0000432#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000433 if (self->lock) {
434 PyThread_free_lock(self->lock);
435 self->lock = NULL;
436 }
Georg Brandldfd73442009-04-05 11:47:34 +0000437#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000438 Py_CLEAR(self->dict);
439 Py_TYPE(self)->tp_free((PyObject *)self);
440}
441
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200442static PyObject *
443buffered_sizeof(buffered *self, void *unused)
444{
445 Py_ssize_t res;
446
447 res = sizeof(buffered);
448 if (self->buffer)
449 res += self->buffer_size;
450 return PyLong_FromSsize_t(res);
451}
452
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000453static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000454buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000455{
456 Py_VISIT(self->raw);
457 Py_VISIT(self->dict);
458 return 0;
459}
460
461static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000462buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000463{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464 self->ok = 0;
465 Py_CLEAR(self->raw);
466 Py_CLEAR(self->dict);
467 return 0;
468}
469
Antoine Pitroue033e062010-10-29 10:38:18 +0000470/* Because this can call arbitrary code, it shouldn't be called when
471 the refcount is 0 (that is, not directly from tp_dealloc unless
472 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000473static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000474buffered_dealloc_warn(buffered *self, PyObject *source)
475{
476 if (self->ok && self->raw) {
477 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200478 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000479 if (r)
480 Py_DECREF(r);
481 else
482 PyErr_Clear();
483 }
484 Py_RETURN_NONE;
485}
486
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487/*
488 * _BufferedIOMixin methods
489 * This is not a class, just a collection of methods that will be reused
490 * by BufferedReader and BufferedWriter
491 */
492
493/* Flush and close */
494
495static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000496buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000497{
498 CHECK_INITIALIZED(self)
499 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
500}
501
502static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000503buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504{
505 int closed;
506 PyObject *res;
507 CHECK_INITIALIZED_INT(self)
508 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
509 if (res == NULL)
510 return -1;
511 closed = PyObject_IsTrue(res);
512 Py_DECREF(res);
513 return closed;
514}
515
516static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000517buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000518{
519 CHECK_INITIALIZED(self)
520 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
521}
522
523static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000524buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000525{
Benjamin Peterson68623612012-12-20 11:53:11 -0600526 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000527 int r;
528
529 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000530 if (!ENTER_BUFFERED(self))
531 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000532
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000533 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000534 if (r < 0)
535 goto end;
536 if (r > 0) {
537 res = Py_None;
538 Py_INCREF(res);
539 goto end;
540 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000541
Antoine Pitrou796564c2013-07-30 19:59:21 +0200542 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000543 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
544 if (r)
545 Py_DECREF(r);
546 else
547 PyErr_Clear();
548 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000549 /* flush() will most probably re-take the lock, so drop it first */
550 LEAVE_BUFFERED(self)
551 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000552 if (!ENTER_BUFFERED(self))
553 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600554 if (res == NULL)
555 PyErr_Fetch(&exc, &val, &tb);
556 else
557 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000558
559 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
560
Jesus Ceadc469452012-10-04 12:37:56 +0200561 if (self->buffer) {
562 PyMem_Free(self->buffer);
563 self->buffer = NULL;
564 }
565
Benjamin Peterson68623612012-12-20 11:53:11 -0600566 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300567 _PyErr_ChainExceptions(exc, val, tb);
568 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600569 }
570
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000571end:
572 LEAVE_BUFFERED(self)
573 return res;
574}
575
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000576/* detach */
577
578static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000579buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000580{
581 PyObject *raw, *res;
582 CHECK_INITIALIZED(self)
583 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
584 if (res == NULL)
585 return NULL;
586 Py_DECREF(res);
587 raw = self->raw;
588 self->raw = NULL;
589 self->detached = 1;
590 self->ok = 0;
591 return raw;
592}
593
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594/* Inquiries */
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598{
599 CHECK_INITIALIZED(self)
600 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
601}
602
603static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000604buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000605{
606 CHECK_INITIALIZED(self)
607 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
608}
609
610static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000611buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000612{
613 CHECK_INITIALIZED(self)
614 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
615}
616
617static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000618buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619{
620 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200621 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622}
623
624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000626{
627 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200628 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629}
630
631/* Lower-level APIs */
632
633static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000634buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635{
636 CHECK_INITIALIZED(self)
637 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
638}
639
640static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642{
643 CHECK_INITIALIZED(self)
644 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
645}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000646
Antoine Pitrou243757e2010-11-05 21:15:39 +0000647/* Serialization */
648
649static PyObject *
650buffered_getstate(buffered *self, PyObject *args)
651{
652 PyErr_Format(PyExc_TypeError,
653 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
654 return NULL;
655}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000656
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657/* Forward decls */
658static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100659_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000661_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000663_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000665_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000666static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200667_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000669_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000670static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000671_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000672static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000673_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200674static Py_ssize_t
675_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000676
677/*
678 * Helpers
679 */
680
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100681/* Sets the current error to BlockingIOError */
682static void
683_set_BlockingIOError(char *msg, Py_ssize_t written)
684{
685 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200686#ifdef Py_DEBUG
687 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
688 if an exception is set when it is called */
689 PyErr_Clear();
690#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100691 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
692 errno, msg, written);
693 if (err)
694 PyErr_SetObject(PyExc_BlockingIOError, err);
695 Py_XDECREF(err);
696}
697
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698/* Returns the address of the `written` member if a BlockingIOError was
699 raised, NULL otherwise. The error is always re-raised. */
700static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000701_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702{
703 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200704 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000705
706 PyErr_Fetch(&t, &v, &tb);
707 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
708 PyErr_Restore(t, v, tb);
709 return NULL;
710 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200711 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712 /* TODO: sanity check (err->written >= 0) */
713 PyErr_Restore(t, v, tb);
714 return &err->written;
715}
716
717static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000718_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000719{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000720 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000721 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000722 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
723 if (res == NULL)
724 return -1;
725 n = PyNumber_AsOff_t(res, PyExc_ValueError);
726 Py_DECREF(res);
727 if (n < 0) {
728 if (!PyErr_Occurred())
729 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000730 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200731 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732 return -1;
733 }
734 self->abs_pos = n;
735 return n;
736}
737
738static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000739_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740{
741 PyObject *res, *posobj, *whenceobj;
742 Py_off_t n;
743
744 posobj = PyLong_FromOff_t(target);
745 if (posobj == NULL)
746 return -1;
747 whenceobj = PyLong_FromLong(whence);
748 if (whenceobj == NULL) {
749 Py_DECREF(posobj);
750 return -1;
751 }
752 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
753 posobj, whenceobj, NULL);
754 Py_DECREF(posobj);
755 Py_DECREF(whenceobj);
756 if (res == NULL)
757 return -1;
758 n = PyNumber_AsOff_t(res, PyExc_ValueError);
759 Py_DECREF(res);
760 if (n < 0) {
761 if (!PyErr_Occurred())
762 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000763 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200764 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000765 return -1;
766 }
767 self->abs_pos = n;
768 return n;
769}
770
771static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000772_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773{
774 Py_ssize_t n;
775 if (self->buffer_size <= 0) {
776 PyErr_SetString(PyExc_ValueError,
777 "buffer size must be strictly positive");
778 return -1;
779 }
780 if (self->buffer)
781 PyMem_Free(self->buffer);
782 self->buffer = PyMem_Malloc(self->buffer_size);
783 if (self->buffer == NULL) {
784 PyErr_NoMemory();
785 return -1;
786 }
Georg Brandldfd73442009-04-05 11:47:34 +0000787#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000788 if (self->lock)
789 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000790 self->lock = PyThread_allocate_lock();
791 if (self->lock == NULL) {
792 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
793 return -1;
794 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000795 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000796#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000797 /* Find out whether buffer_size is a power of 2 */
798 /* XXX is this optimization useful? */
799 for (n = self->buffer_size - 1; n & 1; n >>= 1)
800 ;
801 if (n == 0)
802 self->buffer_mask = self->buffer_size - 1;
803 else
804 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000805 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000806 PyErr_Clear();
807 return 0;
808}
809
Antoine Pitrou707ce822011-02-25 21:24:11 +0000810/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
811 clears the error indicator), 0 otherwise.
812 Should only be called when PyErr_Occurred() is true.
813*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700814int
815_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000816{
817 static PyObject *eintr_int = NULL;
818 PyObject *typ, *val, *tb;
819 PyEnvironmentErrorObject *env_err;
820
821 if (eintr_int == NULL) {
822 eintr_int = PyLong_FromLong(EINTR);
823 assert(eintr_int != NULL);
824 }
825 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
826 return 0;
827 PyErr_Fetch(&typ, &val, &tb);
828 PyErr_NormalizeException(&typ, &val, &tb);
829 env_err = (PyEnvironmentErrorObject *) val;
830 assert(env_err != NULL);
831 if (env_err->myerrno != NULL &&
832 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
833 Py_DECREF(typ);
834 Py_DECREF(val);
835 Py_XDECREF(tb);
836 return 1;
837 }
838 /* This silences any error set by PyObject_RichCompareBool() */
839 PyErr_Restore(typ, val, tb);
840 return 0;
841}
842
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843/*
844 * Shared methods and wrappers
845 */
846
847static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200848buffered_flush_and_rewind_unlocked(buffered *self)
849{
850 PyObject *res;
851
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100852 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200853 if (res == NULL)
854 return NULL;
855 Py_DECREF(res);
856
857 if (self->readable) {
858 /* Rewind the raw stream so that its position corresponds to
859 the current logical position. */
860 Py_off_t n;
861 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
862 _bufferedreader_reset_buf(self);
863 if (n == -1)
864 return NULL;
865 }
866 Py_RETURN_NONE;
867}
868
869static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000870buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871{
872 PyObject *res;
873
874 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000875 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000877 if (!ENTER_BUFFERED(self))
878 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200879 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880 LEAVE_BUFFERED(self)
881
882 return res;
883}
884
885static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000886buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887{
888 Py_ssize_t n = 0;
889 PyObject *res = NULL;
890
891 CHECK_INITIALIZED(self)
892 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
893 return NULL;
894 }
895
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000896 if (!ENTER_BUFFERED(self))
897 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000898
899 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200900 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901 if (res == NULL)
902 goto end;
903 Py_CLEAR(res);
904 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200905 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000906
907end:
908 LEAVE_BUFFERED(self)
909 return res;
910}
911
912static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000913buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000914{
915 Py_ssize_t n = -1;
916 PyObject *res;
917
918 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000919 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 return NULL;
921 }
922 if (n < -1) {
923 PyErr_SetString(PyExc_ValueError,
924 "read length must be positive or -1");
925 return NULL;
926 }
927
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000928 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000930 if (n == -1) {
931 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000932 if (!ENTER_BUFFERED(self))
933 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000934 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000935 }
936 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000937 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200938 if (res != Py_None)
939 return res;
940 Py_DECREF(res);
941 if (!ENTER_BUFFERED(self))
942 return NULL;
943 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000944 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945
Antoine Pitroue05565e2011-08-20 14:39:23 +0200946 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947 return res;
948}
949
950static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000951buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000952{
953 Py_ssize_t n, have, r;
954 PyObject *res = NULL;
955
956 CHECK_INITIALIZED(self)
957 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
958 return NULL;
959 }
960
961 if (n < 0) {
962 PyErr_SetString(PyExc_ValueError,
963 "read length must be positive");
964 return NULL;
965 }
966 if (n == 0)
967 return PyBytes_FromStringAndSize(NULL, 0);
968
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969 /* Return up to n bytes. If at least one byte is buffered, we
970 only return buffered bytes. Otherwise, we do one raw read. */
971
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
973 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100974 n = Py_MIN(have, n);
975 res = _bufferedreader_read_fast(self, n);
976 assert(res != Py_None);
977 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000978 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100979 res = PyBytes_FromStringAndSize(NULL, n);
980 if (res == NULL)
981 return NULL;
982 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200983 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100984 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200985 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000986 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100987 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
988 LEAVE_BUFFERED(self)
989 if (r == -1) {
990 Py_DECREF(res);
991 return NULL;
992 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993 if (r == -2)
994 r = 0;
995 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100996 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997 return res;
998}
999
1000static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001001buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001002{
Antoine Pitrou3486a982011-05-12 01:57:53 +02001003 Py_buffer buf;
1004 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001005 PyObject *res = NULL;
1006
1007 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +02001008
1009 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
1010 return NULL;
1011
1012 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1013 if (n > 0) {
1014 if (n >= buf.len) {
1015 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1016 self->pos += buf.len;
1017 res = PyLong_FromSsize_t(buf.len);
1018 goto end_unlocked;
1019 }
1020 memcpy(buf.buf, self->buffer + self->pos, n);
1021 self->pos += n;
1022 written = n;
1023 }
1024
1025 if (!ENTER_BUFFERED(self))
1026 goto end_unlocked;
1027
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001028 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001029 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001030 if (res == NULL)
1031 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001032 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001033 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001034
1035 _bufferedreader_reset_buf(self);
1036 self->pos = 0;
1037
1038 for (remaining = buf.len - written;
1039 remaining > 0;
1040 written += n, remaining -= n) {
1041 /* If remaining bytes is larger than internal buffer size, copy
1042 * directly into caller's buffer. */
1043 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001044 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1045 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001046 }
1047 else {
1048 n = _bufferedreader_fill_buffer(self);
1049 if (n > 0) {
1050 if (n > remaining)
1051 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001052 memcpy((char *) buf.buf + written,
1053 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001054 self->pos += n;
1055 continue; /* short circuit */
1056 }
1057 }
1058 if (n == 0 || (n == -2 && written > 0))
1059 break;
1060 if (n < 0) {
1061 if (n == -2) {
1062 Py_INCREF(Py_None);
1063 res = Py_None;
1064 }
1065 goto end;
1066 }
1067 }
1068 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001069
1070end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001071 LEAVE_BUFFERED(self);
1072end_unlocked:
1073 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001074 return res;
1075}
1076
1077static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001078_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079{
1080 PyObject *res = NULL;
1081 PyObject *chunks = NULL;
1082 Py_ssize_t n, written = 0;
1083 const char *start, *s, *end;
1084
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001085 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001086
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087 /* First, try to find a line in the buffer. This can run unlocked because
1088 the calls to the C API are simple enough that they can't trigger
1089 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1091 if (limit >= 0 && n > limit)
1092 n = limit;
1093 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001094 s = memchr(start, '\n', n);
1095 if (s != NULL) {
1096 res = PyBytes_FromStringAndSize(start, s - start + 1);
1097 if (res != NULL)
1098 self->pos += s - start + 1;
1099 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100 }
1101 if (n == limit) {
1102 res = PyBytes_FromStringAndSize(start, n);
1103 if (res != NULL)
1104 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001105 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106 }
1107
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001108 if (!ENTER_BUFFERED(self))
1109 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001110
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001111 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001112 chunks = PyList_New(0);
1113 if (chunks == NULL)
1114 goto end;
1115 if (n > 0) {
1116 res = PyBytes_FromStringAndSize(start, n);
1117 if (res == NULL)
1118 goto end;
1119 if (PyList_Append(chunks, res) < 0) {
1120 Py_CLEAR(res);
1121 goto end;
1122 }
1123 Py_CLEAR(res);
1124 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001125 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126 if (limit >= 0)
1127 limit -= n;
1128 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001129 if (self->writable) {
1130 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1131 if (r == NULL)
1132 goto end;
1133 Py_DECREF(r);
1134 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001135
1136 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001137 _bufferedreader_reset_buf(self);
1138 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001139 if (n == -1)
1140 goto end;
1141 if (n <= 0)
1142 break;
1143 if (limit >= 0 && n > limit)
1144 n = limit;
1145 start = self->buffer;
1146 end = start + n;
1147 s = start;
1148 while (s < end) {
1149 if (*s++ == '\n') {
1150 res = PyBytes_FromStringAndSize(start, s - start);
1151 if (res == NULL)
1152 goto end;
1153 self->pos = s - start;
1154 goto found;
1155 }
1156 }
1157 res = PyBytes_FromStringAndSize(start, n);
1158 if (res == NULL)
1159 goto end;
1160 if (n == limit) {
1161 self->pos = n;
1162 break;
1163 }
1164 if (PyList_Append(chunks, res) < 0) {
1165 Py_CLEAR(res);
1166 goto end;
1167 }
1168 Py_CLEAR(res);
1169 written += n;
1170 if (limit >= 0)
1171 limit -= n;
1172 }
1173found:
1174 if (res != NULL && PyList_Append(chunks, res) < 0) {
1175 Py_CLEAR(res);
1176 goto end;
1177 }
1178 Py_CLEAR(res);
1179 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1180
1181end:
1182 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001183end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001184 Py_XDECREF(chunks);
1185 return res;
1186}
1187
1188static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001189buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190{
1191 Py_ssize_t limit = -1;
1192
1193 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001194 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001195 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001196 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197}
1198
1199
1200static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001201buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202{
1203 Py_off_t pos;
1204
1205 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001206 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207 if (pos == -1)
1208 return NULL;
1209 pos -= RAW_OFFSET(self);
1210 /* TODO: sanity check (pos >= 0) */
1211 return PyLong_FromOff_t(pos);
1212}
1213
1214static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001215buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001216{
1217 Py_off_t target, n;
1218 int whence = 0;
1219 PyObject *targetobj, *res = NULL;
1220
1221 CHECK_INITIALIZED(self)
1222 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1223 return NULL;
1224 }
Jesus Cea94363612012-06-22 18:32:07 +02001225
1226 /* Do some error checking instead of trusting OS 'seek()'
1227 ** error detection, just in case.
1228 */
1229 if ((whence < 0 || whence >2)
1230#ifdef SEEK_HOLE
1231 && (whence != SEEK_HOLE)
1232#endif
1233#ifdef SEEK_DATA
1234 && (whence != SEEK_DATA)
1235#endif
1236 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001237 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001238 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239 return NULL;
1240 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001241
1242 CHECK_CLOSED(self, "seek of closed file")
1243
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001244 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1245 return NULL;
1246
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001247 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1248 if (target == -1 && PyErr_Occurred())
1249 return NULL;
1250
Jesus Cea94363612012-06-22 18:32:07 +02001251 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1252 buffer. Other whence values must be managed without this optimization.
1253 Some Operating Systems can provide additional values, like
1254 SEEK_HOLE/SEEK_DATA. */
1255 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 Py_off_t current, avail;
1257 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001258 so as to return quickly if possible. Also, we needn't take the
1259 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001261 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1262 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 current = RAW_TELL(self);
1264 avail = READAHEAD(self);
1265 if (avail > 0) {
1266 Py_off_t offset;
1267 if (whence == 0)
1268 offset = target - (current - RAW_OFFSET(self));
1269 else
1270 offset = target;
1271 if (offset >= -self->pos && offset <= avail) {
1272 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001273 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 }
1275 }
1276 }
1277
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001278 if (!ENTER_BUFFERED(self))
1279 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001280
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001281 /* Fallback: invoke raw seek() method and clear buffer */
1282 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001283 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001284 if (res == NULL)
1285 goto end;
1286 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001287 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 }
1289
1290 /* TODO: align on block boundary and read buffer if needed? */
1291 if (whence == 1)
1292 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001293 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001294 if (n == -1)
1295 goto end;
1296 self->raw_pos = -1;
1297 res = PyLong_FromOff_t(n);
1298 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001299 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300
1301end:
1302 LEAVE_BUFFERED(self)
1303 return res;
1304}
1305
1306static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001307buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308{
1309 PyObject *pos = Py_None;
1310 PyObject *res = NULL;
1311
1312 CHECK_INITIALIZED(self)
1313 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1314 return NULL;
1315 }
1316
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001317 if (!ENTER_BUFFERED(self))
1318 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319
1320 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001321 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 if (res == NULL)
1323 goto end;
1324 Py_CLEAR(res);
1325 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001326 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1327 if (res == NULL)
1328 goto end;
1329 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001330 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331 PyErr_Clear();
1332
1333end:
1334 LEAVE_BUFFERED(self)
1335 return res;
1336}
1337
1338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001339buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340{
1341 PyObject *line;
1342 PyTypeObject *tp;
1343
1344 CHECK_INITIALIZED(self);
1345
1346 tp = Py_TYPE(self);
1347 if (tp == &PyBufferedReader_Type ||
1348 tp == &PyBufferedRandom_Type) {
1349 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001350 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001351 }
1352 else {
1353 line = PyObject_CallMethodObjArgs((PyObject *)self,
1354 _PyIO_str_readline, NULL);
1355 if (line && !PyBytes_Check(line)) {
1356 PyErr_Format(PyExc_IOError,
1357 "readline() should have returned a bytes object, "
1358 "not '%.200s'", Py_TYPE(line)->tp_name);
1359 Py_DECREF(line);
1360 return NULL;
1361 }
1362 }
1363
1364 if (line == NULL)
1365 return NULL;
1366
1367 if (PyBytes_GET_SIZE(line) == 0) {
1368 /* Reached EOF or would have blocked */
1369 Py_DECREF(line);
1370 return NULL;
1371 }
1372
1373 return line;
1374}
1375
Antoine Pitrou716c4442009-05-23 19:04:03 +00001376static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001377buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001378{
1379 PyObject *nameobj, *res;
1380
Martin v. Löwis767046a2011-10-14 15:35:36 +02001381 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001382 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001383 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001384 PyErr_Clear();
1385 else
1386 return NULL;
1387 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1388 }
1389 else {
1390 res = PyUnicode_FromFormat("<%s name=%R>",
1391 Py_TYPE(self)->tp_name, nameobj);
1392 Py_DECREF(nameobj);
1393 }
1394 return res;
1395}
1396
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001397/*
1398 * class BufferedReader
1399 */
1400
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001401PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001402 "Create a new buffered reader using the given readable raw IO object.");
1403
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001404static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001405{
1406 self->read_end = -1;
1407}
1408
1409static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001410bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411{
1412 char *kwlist[] = {"raw", "buffer_size", NULL};
1413 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1414 PyObject *raw;
1415
1416 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001417 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001418
1419 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1420 &raw, &buffer_size)) {
1421 return -1;
1422 }
1423
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001424 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001425 return -1;
1426
1427 Py_CLEAR(self->raw);
1428 Py_INCREF(raw);
1429 self->raw = raw;
1430 self->buffer_size = buffer_size;
1431 self->readable = 1;
1432 self->writable = 0;
1433
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001434 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001436 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001438 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1439 Py_TYPE(raw) == &PyFileIO_Type);
1440
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441 self->ok = 1;
1442 return 0;
1443}
1444
1445static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001446_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001447{
1448 Py_buffer buf;
1449 PyObject *memobj, *res;
1450 Py_ssize_t n;
1451 /* NOTE: the buffer needn't be released as its object is NULL. */
1452 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1453 return -1;
1454 memobj = PyMemoryView_FromBuffer(&buf);
1455 if (memobj == NULL)
1456 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001457 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1458 occurs so we needn't do it ourselves.
1459 We then retry reading, ignoring the signal if no handler has
1460 raised (see issue #10956).
1461 */
1462 do {
1463 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001464 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465 Py_DECREF(memobj);
1466 if (res == NULL)
1467 return -1;
1468 if (res == Py_None) {
1469 /* Non-blocking stream would have blocked. Special return code! */
1470 Py_DECREF(res);
1471 return -2;
1472 }
1473 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1474 Py_DECREF(res);
1475 if (n < 0 || n > len) {
1476 PyErr_Format(PyExc_IOError,
1477 "raw readinto() returned invalid length %zd "
1478 "(should have been between 0 and %zd)", n, len);
1479 return -1;
1480 }
1481 if (n > 0 && self->abs_pos != -1)
1482 self->abs_pos += n;
1483 return n;
1484}
1485
1486static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001487_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001488{
1489 Py_ssize_t start, len, n;
1490 if (VALID_READ_BUFFER(self))
1491 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1492 else
1493 start = 0;
1494 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001495 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001496 if (n <= 0)
1497 return n;
1498 self->read_end = start + n;
1499 self->raw_pos = start + n;
1500 return n;
1501}
1502
1503static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001504_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001505{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001506 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001507 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001508
1509 /* First copy what we have in the current buffer. */
1510 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1511 if (current_size) {
1512 data = PyBytes_FromStringAndSize(
1513 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001514 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001515 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001516 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001517 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001518 /* We're going past the buffer's bounds, flush it */
1519 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001520 tmp = buffered_flush_and_rewind_unlocked(self);
1521 if (tmp == NULL)
1522 goto cleanup;
1523 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001524 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001525 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001526
1527 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001528 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1529 if (tmp == NULL)
1530 goto cleanup;
1531 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001532 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001533 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001534 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001535 if (tmp == Py_None) {
1536 if (current_size == 0) {
1537 res = Py_None;
1538 goto cleanup;
1539 } else {
1540 res = data;
1541 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001542 }
1543 }
1544 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001545 PyBytes_Concat(&data, tmp);
1546 res = data;
1547 goto cleanup;
1548 }
1549 else {
1550 res = tmp;
1551 goto cleanup;
1552 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001553 }
1554
1555 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 if (chunks == NULL)
1557 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001558
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001559 while (1) {
1560 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001561 if (PyList_Append(chunks, data) < 0)
1562 goto cleanup;
1563 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001564 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001565
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001566 /* Read until EOF or until read() would block. */
1567 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001568 if (data == NULL)
1569 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001570 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001571 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001572 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001573 }
1574 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1575 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001576 res = data;
1577 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578 }
1579 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001580 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1581 res = tmp;
1582 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 }
1584 }
1585 current_size += PyBytes_GET_SIZE(data);
1586 if (self->abs_pos != -1)
1587 self->abs_pos += PyBytes_GET_SIZE(data);
1588 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001589cleanup:
1590 /* res is either NULL or a borrowed ref */
1591 Py_XINCREF(res);
1592 Py_XDECREF(data);
1593 Py_XDECREF(tmp);
1594 Py_XDECREF(chunks);
1595 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001596}
1597
1598/* Read n bytes from the buffer if it can, otherwise return None.
1599 This function is simple enough that it can run unlocked. */
1600static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001601_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602{
1603 Py_ssize_t current_size;
1604
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001605 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1606 if (n <= current_size) {
1607 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1609 if (res != NULL)
1610 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001611 return res;
1612 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001613 Py_RETURN_NONE;
1614}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001615
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001616/* Generic read function: read from the stream until enough bytes are read,
1617 * or until an EOF occurs or until read() would block.
1618 */
1619static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001620_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001621{
1622 PyObject *res = NULL;
1623 Py_ssize_t current_size, remaining, written;
1624 char *out;
1625
1626 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1627 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001628 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001629
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630 res = PyBytes_FromStringAndSize(NULL, n);
1631 if (res == NULL)
1632 goto error;
1633 out = PyBytes_AS_STRING(res);
1634 remaining = n;
1635 written = 0;
1636 if (current_size > 0) {
1637 memcpy(out, self->buffer + self->pos, current_size);
1638 remaining -= current_size;
1639 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001640 self->pos += current_size;
1641 }
1642 /* Flush the write buffer if necessary */
1643 if (self->writable) {
1644 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1645 if (r == NULL)
1646 goto error;
1647 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001648 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001649 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001650 while (remaining > 0) {
1651 /* We want to read a whole block at the end into buffer.
1652 If we had readv() we could do this in one pass. */
1653 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1654 if (r == 0)
1655 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001656 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001657 if (r == -1)
1658 goto error;
1659 if (r == 0 || r == -2) {
1660 /* EOF occurred or read() would block. */
1661 if (r == 0 || written > 0) {
1662 if (_PyBytes_Resize(&res, written))
1663 goto error;
1664 return res;
1665 }
1666 Py_DECREF(res);
1667 Py_INCREF(Py_None);
1668 return Py_None;
1669 }
1670 remaining -= r;
1671 written += r;
1672 }
1673 assert(remaining <= self->buffer_size);
1674 self->pos = 0;
1675 self->raw_pos = 0;
1676 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001677 /* NOTE: when the read is satisfied, we avoid issuing any additional
1678 reads, which could block indefinitely (e.g. on a socket).
1679 See issue #9550. */
1680 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001681 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001682 if (r == -1)
1683 goto error;
1684 if (r == 0 || r == -2) {
1685 /* EOF occurred or read() would block. */
1686 if (r == 0 || written > 0) {
1687 if (_PyBytes_Resize(&res, written))
1688 goto error;
1689 return res;
1690 }
1691 Py_DECREF(res);
1692 Py_INCREF(Py_None);
1693 return Py_None;
1694 }
1695 if (remaining > r) {
1696 memcpy(out + written, self->buffer + self->pos, r);
1697 written += r;
1698 self->pos += r;
1699 remaining -= r;
1700 }
1701 else if (remaining > 0) {
1702 memcpy(out + written, self->buffer + self->pos, remaining);
1703 written += remaining;
1704 self->pos += remaining;
1705 remaining = 0;
1706 }
1707 if (remaining == 0)
1708 break;
1709 }
1710
1711 return res;
1712
1713error:
1714 Py_XDECREF(res);
1715 return NULL;
1716}
1717
1718static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001719_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001720{
1721 Py_ssize_t have, r;
1722
1723 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1724 /* Constraints:
1725 1. we don't want to advance the file position.
1726 2. we don't want to lose block alignment, so we can't shift the buffer
1727 to make some place.
1728 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1729 */
1730 if (have > 0) {
1731 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1732 }
1733
1734 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735 _bufferedreader_reset_buf(self);
1736 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 if (r == -1)
1738 return NULL;
1739 if (r == -2)
1740 r = 0;
1741 self->pos = 0;
1742 return PyBytes_FromStringAndSize(self->buffer, r);
1743}
1744
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001745static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001747 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1748 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1749 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1750 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1751 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1752 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1753 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1754 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001755 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001756 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1759 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1760 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001761 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001762 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1763 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1764 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1765 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001766 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767 {NULL, NULL}
1768};
1769
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001770static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001771 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001772 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 {NULL}
1774};
1775
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776static PyGetSetDef bufferedreader_getset[] = {
1777 {"closed", (getter)buffered_closed_get, NULL, NULL},
1778 {"name", (getter)buffered_name_get, NULL, NULL},
1779 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001780 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781};
1782
1783
1784PyTypeObject PyBufferedReader_Type = {
1785 PyVarObject_HEAD_INIT(NULL, 0)
1786 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001789 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 0, /*tp_print*/
1791 0, /*tp_getattr*/
1792 0, /*tp_setattr*/
1793 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001794 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 0, /*tp_as_number*/
1796 0, /*tp_as_sequence*/
1797 0, /*tp_as_mapping*/
1798 0, /*tp_hash */
1799 0, /*tp_call*/
1800 0, /*tp_str*/
1801 0, /*tp_getattro*/
1802 0, /*tp_setattro*/
1803 0, /*tp_as_buffer*/
1804 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001805 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001806 bufferedreader_doc, /* tp_doc */
1807 (traverseproc)buffered_traverse, /* tp_traverse */
1808 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001810 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812 (iternextfunc)buffered_iternext, /* tp_iternext */
1813 bufferedreader_methods, /* tp_methods */
1814 bufferedreader_members, /* tp_members */
1815 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816 0, /* tp_base */
1817 0, /* tp_dict */
1818 0, /* tp_descr_get */
1819 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001820 offsetof(buffered, dict), /* tp_dictoffset */
1821 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822 0, /* tp_alloc */
1823 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001824 0, /* tp_free */
1825 0, /* tp_is_gc */
1826 0, /* tp_bases */
1827 0, /* tp_mro */
1828 0, /* tp_cache */
1829 0, /* tp_subclasses */
1830 0, /* tp_weaklist */
1831 0, /* tp_del */
1832 0, /* tp_version_tag */
1833 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834};
1835
1836
Benjamin Peterson59406a92009-03-26 17:10:29 +00001837
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838/*
1839 * class BufferedWriter
1840 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001841PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001842 "A buffer for a writeable sequential RawIO object.\n"
1843 "\n"
1844 "The constructor creates a BufferedWriter for the given writeable raw\n"
1845 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001846 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847 );
1848
1849static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001850_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851{
1852 self->write_pos = 0;
1853 self->write_end = -1;
1854}
1855
1856static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001857bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858{
Florent Xicluna109d5732012-07-07 17:03:22 +02001859 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001860 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001861 PyObject *raw;
1862
1863 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001864 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001865
R David Murray9f10f562013-02-23 22:07:55 -05001866 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001867 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001868 return -1;
1869 }
1870
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001871 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872 return -1;
1873
1874 Py_CLEAR(self->raw);
1875 Py_INCREF(raw);
1876 self->raw = raw;
1877 self->readable = 0;
1878 self->writable = 1;
1879
1880 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001881 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001882 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001883 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884 self->pos = 0;
1885
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001886 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1887 Py_TYPE(raw) == &PyFileIO_Type);
1888
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 self->ok = 1;
1890 return 0;
1891}
1892
1893static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001894_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001895{
1896 Py_buffer buf;
1897 PyObject *memobj, *res;
1898 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001899 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900 /* NOTE: the buffer needn't be released as its object is NULL. */
1901 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1902 return -1;
1903 memobj = PyMemoryView_FromBuffer(&buf);
1904 if (memobj == NULL)
1905 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001906 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1907 occurs so we needn't do it ourselves.
1908 We then retry writing, ignoring the signal if no handler has
1909 raised (see issue #10956).
1910 */
1911 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001912 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001913 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001914 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001915 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916 Py_DECREF(memobj);
1917 if (res == NULL)
1918 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001919 if (res == Py_None) {
1920 /* Non-blocking stream would have blocked. Special return code!
1921 Being paranoid we reset errno in case it is changed by code
1922 triggered by a decref. errno is used by _set_BlockingIOError(). */
1923 Py_DECREF(res);
1924 errno = errnum;
1925 return -2;
1926 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001927 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1928 Py_DECREF(res);
1929 if (n < 0 || n > len) {
1930 PyErr_Format(PyExc_IOError,
1931 "raw write() returned invalid length %zd "
1932 "(should have been between 0 and %zd)", n, len);
1933 return -1;
1934 }
1935 if (n > 0 && self->abs_pos != -1)
1936 self->abs_pos += n;
1937 return n;
1938}
1939
1940/* `restore_pos` is 1 if we need to restore the raw stream position at
1941 the end, 0 otherwise. */
1942static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001943_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944{
1945 Py_ssize_t written = 0;
1946 Py_off_t n, rewind;
1947
1948 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1949 goto end;
1950 /* First, rewind */
1951 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1952 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001953 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 if (n < 0) {
1955 goto error;
1956 }
1957 self->raw_pos -= rewind;
1958 }
1959 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001960 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001961 self->buffer + self->write_pos,
1962 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1963 Py_off_t, Py_ssize_t));
1964 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001965 goto error;
1966 }
1967 else if (n == -2) {
1968 _set_BlockingIOError("write could not complete without blocking",
1969 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 goto error;
1971 }
1972 self->write_pos += n;
1973 self->raw_pos = self->write_pos;
1974 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001975 /* Partial writes can return successfully when interrupted by a
1976 signal (see write(2)). We must run signal handlers before
1977 blocking another time, possibly indefinitely. */
1978 if (PyErr_CheckSignals() < 0)
1979 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001980 }
1981
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001982 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983
1984end:
1985 Py_RETURN_NONE;
1986
1987error:
1988 return NULL;
1989}
1990
1991static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001992bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993{
1994 PyObject *res = NULL;
1995 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001996 Py_ssize_t written, avail, remaining;
1997 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998
1999 CHECK_INITIALIZED(self)
2000 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
2001 return NULL;
2002 }
2003
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002004 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002005 PyErr_SetString(PyExc_ValueError, "write to closed file");
2006 PyBuffer_Release(&buf);
2007 return NULL;
2008 }
2009
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00002010 if (!ENTER_BUFFERED(self)) {
2011 PyBuffer_Release(&buf);
2012 return NULL;
2013 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014
2015 /* Fast path: the data to write can be fully buffered. */
2016 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2017 self->pos = 0;
2018 self->raw_pos = 0;
2019 }
2020 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2021 if (buf.len <= avail) {
2022 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002023 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 self->write_pos = self->pos;
2025 }
2026 ADJUST_POSITION(self, self->pos + buf.len);
2027 if (self->pos > self->write_end)
2028 self->write_end = self->pos;
2029 written = buf.len;
2030 goto end;
2031 }
2032
2033 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002034 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002036 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 if (w == NULL)
2038 goto error;
2039 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002040 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 /* Make some place by shifting the buffer. */
2042 assert(VALID_WRITE_BUFFER(self));
2043 memmove(self->buffer, self->buffer + self->write_pos,
2044 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2045 Py_off_t, Py_ssize_t));
2046 self->write_end -= self->write_pos;
2047 self->raw_pos -= self->write_pos;
2048 self->pos -= self->write_pos;
2049 self->write_pos = 0;
2050 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2051 Py_off_t, Py_ssize_t);
2052 if (buf.len <= avail) {
2053 /* Everything can be buffered */
2054 PyErr_Clear();
2055 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2056 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002057 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002058 written = buf.len;
2059 goto end;
2060 }
2061 /* Buffer as much as possible. */
2062 memcpy(self->buffer + self->write_end, buf.buf, avail);
2063 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002064 self->pos += avail;
2065 /* XXX Modifying the existing exception e using the pointer w
2066 will change e.characters_written but not e.args[2].
2067 Therefore we just replace with a new error. */
2068 _set_BlockingIOError("write could not complete without blocking",
2069 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002070 goto error;
2071 }
2072 Py_CLEAR(res);
2073
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002074 /* Adjust the raw stream position if it is away from the logical stream
2075 position. This happens if the read buffer has been filled but not
2076 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2077 the raw stream by itself).
2078 Fixes issue #6629.
2079 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002080 offset = RAW_OFFSET(self);
2081 if (offset != 0) {
2082 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002083 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002084 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002085 }
2086
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002087 /* Then write buf itself. At this point the buffer has been emptied. */
2088 remaining = buf.len;
2089 written = 0;
2090 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002091 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002092 self, (char *) buf.buf + written, buf.len - written);
2093 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002094 goto error;
2095 } else if (n == -2) {
2096 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097 if (remaining > self->buffer_size) {
2098 /* Can't buffer everything, still buffer as much as possible */
2099 memcpy(self->buffer,
2100 (char *) buf.buf + written, self->buffer_size);
2101 self->raw_pos = 0;
2102 ADJUST_POSITION(self, self->buffer_size);
2103 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002104 written += self->buffer_size;
2105 _set_BlockingIOError("write could not complete without "
2106 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107 goto error;
2108 }
2109 PyErr_Clear();
2110 break;
2111 }
2112 written += n;
2113 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002114 /* Partial writes can return successfully when interrupted by a
2115 signal (see write(2)). We must run signal handlers before
2116 blocking another time, possibly indefinitely. */
2117 if (PyErr_CheckSignals() < 0)
2118 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002119 }
2120 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002122 if (remaining > 0) {
2123 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2124 written += remaining;
2125 }
2126 self->write_pos = 0;
2127 /* TODO: sanity check (remaining >= 0) */
2128 self->write_end = remaining;
2129 ADJUST_POSITION(self, remaining);
2130 self->raw_pos = 0;
2131
2132end:
2133 res = PyLong_FromSsize_t(written);
2134
2135error:
2136 LEAVE_BUFFERED(self)
2137 PyBuffer_Release(&buf);
2138 return res;
2139}
2140
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002141static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002142 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002143 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2144 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2145 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2146 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2147 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2148 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2149 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002150 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002151 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002153 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2154 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2155 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2156 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2157 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002158 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 {NULL, NULL}
2160};
2161
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002162static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002163 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002164 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165 {NULL}
2166};
2167
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168static PyGetSetDef bufferedwriter_getset[] = {
2169 {"closed", (getter)buffered_closed_get, NULL, NULL},
2170 {"name", (getter)buffered_name_get, NULL, NULL},
2171 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002172 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173};
2174
2175
2176PyTypeObject PyBufferedWriter_Type = {
2177 PyVarObject_HEAD_INIT(NULL, 0)
2178 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002179 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002181 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182 0, /*tp_print*/
2183 0, /*tp_getattr*/
2184 0, /*tp_setattr*/
2185 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187 0, /*tp_as_number*/
2188 0, /*tp_as_sequence*/
2189 0, /*tp_as_mapping*/
2190 0, /*tp_hash */
2191 0, /*tp_call*/
2192 0, /*tp_str*/
2193 0, /*tp_getattro*/
2194 0, /*tp_setattro*/
2195 0, /*tp_as_buffer*/
2196 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002197 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002198 bufferedwriter_doc, /* tp_doc */
2199 (traverseproc)buffered_traverse, /* tp_traverse */
2200 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002202 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203 0, /* tp_iter */
2204 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002205 bufferedwriter_methods, /* tp_methods */
2206 bufferedwriter_members, /* tp_members */
2207 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208 0, /* tp_base */
2209 0, /* tp_dict */
2210 0, /* tp_descr_get */
2211 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002212 offsetof(buffered, dict), /* tp_dictoffset */
2213 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214 0, /* tp_alloc */
2215 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002216 0, /* tp_free */
2217 0, /* tp_is_gc */
2218 0, /* tp_bases */
2219 0, /* tp_mro */
2220 0, /* tp_cache */
2221 0, /* tp_subclasses */
2222 0, /* tp_weaklist */
2223 0, /* tp_del */
2224 0, /* tp_version_tag */
2225 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226};
2227
2228
2229
2230/*
2231 * BufferedRWPair
2232 */
2233
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002234PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235 "A buffered reader and writer object together.\n"
2236 "\n"
2237 "A buffered reader object and buffered writer object put together to\n"
2238 "form a sequential IO object that can read and write. This is typically\n"
2239 "used with a socket or two-way pipe.\n"
2240 "\n"
2241 "reader and writer are RawIOBase objects that are readable and\n"
2242 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002243 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244 );
2245
2246/* XXX The usefulness of this (compared to having two separate IO objects) is
2247 * questionable.
2248 */
2249
2250typedef struct {
2251 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002252 buffered *reader;
2253 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254 PyObject *dict;
2255 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002256} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002257
2258static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260{
2261 PyObject *reader, *writer;
2262 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263
Florent Xicluna109d5732012-07-07 17:03:22 +02002264 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2265 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 return -1;
2267 }
2268
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002269 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002271 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002272 return -1;
2273
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002274 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002275 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276 if (self->reader == NULL)
2277 return -1;
2278
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002279 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002280 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281 if (self->writer == NULL) {
2282 Py_CLEAR(self->reader);
2283 return -1;
2284 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002285
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286 return 0;
2287}
2288
2289static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002290bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291{
2292 Py_VISIT(self->dict);
2293 return 0;
2294}
2295
2296static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002297bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002298{
2299 Py_CLEAR(self->reader);
2300 Py_CLEAR(self->writer);
2301 Py_CLEAR(self->dict);
2302 return 0;
2303}
2304
2305static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002306bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307{
2308 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002309 if (self->weakreflist != NULL)
2310 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002311 Py_CLEAR(self->reader);
2312 Py_CLEAR(self->writer);
2313 Py_CLEAR(self->dict);
2314 Py_TYPE(self)->tp_free((PyObject *) self);
2315}
2316
2317static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002318_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002320 PyObject *func, *ret;
2321 if (self == NULL) {
2322 PyErr_SetString(PyExc_ValueError,
2323 "I/O operation on uninitialized object");
2324 return NULL;
2325 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002326
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002327 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002329 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002330 return NULL;
2331 }
2332
2333 ret = PyObject_CallObject(func, args);
2334 Py_DECREF(func);
2335 return ret;
2336}
2337
2338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002340{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002341 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002342}
2343
2344static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002345bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002346{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002347 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002348}
2349
2350static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002351bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002352{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002353 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002354}
2355
2356static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002357bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002358{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002359 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002360}
2361
2362static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002363bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002364{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002365 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002366}
2367
2368static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002369bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002370{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002371 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002372}
2373
2374static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002375bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002376{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002377 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002378}
2379
2380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002381bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002382{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002383 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002384}
2385
2386static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002387bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002389 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002390 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002391 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002392 PyErr_Fetch(&exc, &val, &tb);
2393 else
2394 Py_DECREF(ret);
2395 ret = _forward_call(self->reader, &PyId_close, args);
2396 if (exc != NULL) {
2397 _PyErr_ChainExceptions(exc, val, tb);
2398 Py_CLEAR(ret);
2399 }
2400 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002401}
2402
2403static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002404bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002405{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002406 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002407
2408 if (ret != Py_False) {
2409 /* either True or exception */
2410 return ret;
2411 }
2412 Py_DECREF(ret);
2413
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002414 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002415}
2416
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002417static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002418bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002419{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002420 if (self->writer == NULL) {
2421 PyErr_SetString(PyExc_RuntimeError,
2422 "the BufferedRWPair object is being garbage-collected");
2423 return NULL;
2424 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002425 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2426}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002427
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002428static PyMethodDef bufferedrwpair_methods[] = {
2429 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2430 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2431 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2432 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002433
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002434 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2435 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002437 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2438 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002439
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002440 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2441 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442
Antoine Pitrou243757e2010-11-05 21:15:39 +00002443 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2444
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002445 {NULL, NULL}
2446};
2447
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002448static PyGetSetDef bufferedrwpair_getset[] = {
2449 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002450 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002451};
2452
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453PyTypeObject PyBufferedRWPair_Type = {
2454 PyVarObject_HEAD_INIT(NULL, 0)
2455 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002456 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002457 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002458 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459 0, /*tp_print*/
2460 0, /*tp_getattr*/
2461 0, /*tp_setattr*/
2462 0, /*tp_compare */
2463 0, /*tp_repr*/
2464 0, /*tp_as_number*/
2465 0, /*tp_as_sequence*/
2466 0, /*tp_as_mapping*/
2467 0, /*tp_hash */
2468 0, /*tp_call*/
2469 0, /*tp_str*/
2470 0, /*tp_getattro*/
2471 0, /*tp_setattro*/
2472 0, /*tp_as_buffer*/
2473 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002474 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002475 bufferedrwpair_doc, /* tp_doc */
2476 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2477 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002478 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002479 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002480 0, /* tp_iter */
2481 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002482 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002483 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002484 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485 0, /* tp_base */
2486 0, /* tp_dict */
2487 0, /* tp_descr_get */
2488 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002489 offsetof(rwpair, dict), /* tp_dictoffset */
2490 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002491 0, /* tp_alloc */
2492 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002493 0, /* tp_free */
2494 0, /* tp_is_gc */
2495 0, /* tp_bases */
2496 0, /* tp_mro */
2497 0, /* tp_cache */
2498 0, /* tp_subclasses */
2499 0, /* tp_weaklist */
2500 0, /* tp_del */
2501 0, /* tp_version_tag */
2502 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002503};
2504
2505
2506
2507/*
2508 * BufferedRandom
2509 */
2510
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002511PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002512 "A buffered interface to random access streams.\n"
2513 "\n"
2514 "The constructor creates a reader and writer for a seekable stream,\n"
2515 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002516 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002517 );
2518
2519static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002520bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002521{
Florent Xicluna109d5732012-07-07 17:03:22 +02002522 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002523 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002524 PyObject *raw;
2525
2526 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002527 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002528
R David Murray9f10f562013-02-23 22:07:55 -05002529 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002530 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002531 return -1;
2532 }
2533
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002534 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002535 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002538 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002539 return -1;
2540
2541 Py_CLEAR(self->raw);
2542 Py_INCREF(raw);
2543 self->raw = raw;
2544 self->buffer_size = buffer_size;
2545 self->readable = 1;
2546 self->writable = 1;
2547
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002548 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002549 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002550 _bufferedreader_reset_buf(self);
2551 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002552 self->pos = 0;
2553
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002554 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2555 Py_TYPE(raw) == &PyFileIO_Type);
2556
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002557 self->ok = 1;
2558 return 0;
2559}
2560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002561static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002562 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002563 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2564 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2565 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2566 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2567 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2568 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2569 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002570 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002571 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002574
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002575 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2576 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2577 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2578 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2579 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2580 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2581 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2582 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2583 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002584 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585 {NULL, NULL}
2586};
2587
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002588static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002589 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002590 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002591 {NULL}
2592};
2593
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002594static PyGetSetDef bufferedrandom_getset[] = {
2595 {"closed", (getter)buffered_closed_get, NULL, NULL},
2596 {"name", (getter)buffered_name_get, NULL, NULL},
2597 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002598 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002599};
2600
2601
2602PyTypeObject PyBufferedRandom_Type = {
2603 PyVarObject_HEAD_INIT(NULL, 0)
2604 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002605 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002606 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002607 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002608 0, /*tp_print*/
2609 0, /*tp_getattr*/
2610 0, /*tp_setattr*/
2611 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002612 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613 0, /*tp_as_number*/
2614 0, /*tp_as_sequence*/
2615 0, /*tp_as_mapping*/
2616 0, /*tp_hash */
2617 0, /*tp_call*/
2618 0, /*tp_str*/
2619 0, /*tp_getattro*/
2620 0, /*tp_setattro*/
2621 0, /*tp_as_buffer*/
2622 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002623 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002624 bufferedrandom_doc, /* tp_doc */
2625 (traverseproc)buffered_traverse, /* tp_traverse */
2626 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002627 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002628 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002630 (iternextfunc)buffered_iternext, /* tp_iternext */
2631 bufferedrandom_methods, /* tp_methods */
2632 bufferedrandom_members, /* tp_members */
2633 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002634 0, /* tp_base */
2635 0, /*tp_dict*/
2636 0, /* tp_descr_get */
2637 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002638 offsetof(buffered, dict), /*tp_dictoffset*/
2639 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002640 0, /* tp_alloc */
2641 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002642 0, /* tp_free */
2643 0, /* tp_is_gc */
2644 0, /* tp_bases */
2645 0, /* tp_mro */
2646 0, /* tp_cache */
2647 0, /* tp_subclasses */
2648 0, /* tp_weaklist */
2649 0, /* tp_del */
2650 0, /* tp_version_tag */
2651 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002652};