blob: 7cf5ddaf00501c3717d8bb2744679adfb014452d [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);
Benjamin Petersona96fea02014-06-22 14:17:44 -070027_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020028_Py_IDENTIFIER(writable);
29_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020030
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000031/*
32 * BufferedIOBase class, inherits from IOBase.
33 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000034PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000035 "Base class for buffered IO objects.\n"
36 "\n"
37 "The main difference with RawIOBase is that the read() method\n"
38 "supports omitting the size argument, and does not have a default\n"
39 "implementation that defers to readinto().\n"
40 "\n"
41 "In addition, read(), readinto() and write() may raise\n"
42 "BlockingIOError if the underlying raw stream is in non-blocking\n"
43 "mode and not ready; unlike their raw counterparts, they will never\n"
44 "return None.\n"
45 "\n"
46 "A typical implementation should not inherit from a RawIOBase\n"
47 "implementation, but wrap one.\n"
48 );
49
50static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -070051_bufferediobase_readinto_generic(PyObject *self, PyObject *args, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000052{
53 Py_buffer buf;
54 Py_ssize_t len;
55 PyObject *data;
56
Benjamin Petersona96fea02014-06-22 14:17:44 -070057 if (!PyArg_ParseTuple(args,
58 readinto1 ? "w*:readinto1" : "w*:readinto",
59 &buf)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000060 return NULL;
61 }
62
Benjamin Petersona96fea02014-06-22 14:17:44 -070063 data = _PyObject_CallMethodId(self,
64 readinto1 ? &PyId_read1 : &PyId_read,
65 "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000066 if (data == NULL)
67 goto error;
68
69 if (!PyBytes_Check(data)) {
70 Py_DECREF(data);
71 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
72 goto error;
73 }
74
75 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030076 if (len > buf.len) {
77 PyErr_Format(PyExc_ValueError,
78 "read() returned too much data: "
79 "%zd bytes requested, %zd returned",
80 buf.len, len);
81 Py_DECREF(data);
82 goto error;
83 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000084 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
85
86 PyBuffer_Release(&buf);
87 Py_DECREF(data);
88
89 return PyLong_FromSsize_t(len);
90
91 error:
92 PyBuffer_Release(&buf);
93 return NULL;
94}
95
96static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -070097bufferediobase_readinto(PyObject *self, PyObject *args)
98{
99 return _bufferediobase_readinto_generic(self, args, 0);
100}
101
102static PyObject *
103bufferediobase_readinto1(PyObject *self, PyObject *args)
104{
105 return _bufferediobase_readinto_generic(self, args, 1);
106}
107
108static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000109bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000110{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100111 _PyIO_State *state = IO_STATE();
112 if (state != NULL)
113 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000114 return NULL;
115}
116
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000117PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000118 "Disconnect this buffer from its underlying raw stream and return it.\n"
119 "\n"
120 "After the raw stream has been detached, the buffer is in an unusable\n"
121 "state.\n");
122
123static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000124bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000125{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000126 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000127}
128
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000129PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000130 "Read and return up to n bytes.\n"
131 "\n"
132 "If the argument is omitted, None, or negative, reads and\n"
133 "returns all data until EOF.\n"
134 "\n"
135 "If the argument is positive, and the underlying raw stream is\n"
136 "not 'interactive', multiple raw reads may be issued to satisfy\n"
137 "the byte count (unless EOF is reached first). But for\n"
138 "interactive raw streams (as well as sockets and pipes), at most\n"
139 "one raw read will be issued, and a short result does not imply\n"
140 "that EOF is imminent.\n"
141 "\n"
142 "Returns an empty bytes object on EOF.\n"
143 "\n"
144 "Returns None if the underlying raw stream was open in non-blocking\n"
145 "mode and no data is available at the moment.\n");
146
147static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000151}
152
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000153PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000154 "Read and return up to n bytes, with at most one read() call\n"
155 "to the underlying raw stream. A short result does not imply\n"
156 "that EOF is imminent.\n"
157 "\n"
158 "Returns an empty bytes object on EOF.\n");
159
160static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000161bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000162{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000163 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000164}
165
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000166PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000167 "Write the given buffer to the IO stream.\n"
168 "\n"
169 "Returns the number of bytes written, which is never less than\n"
170 "len(b).\n"
171 "\n"
172 "Raises BlockingIOError if the buffer is full and the\n"
173 "underlying raw stream cannot accept more data at the moment.\n");
174
175static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000176bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000177{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000178 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000179}
180
181
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000182static PyMethodDef bufferediobase_methods[] = {
183 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
184 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
185 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
186 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
Benjamin Petersona96fea02014-06-22 14:17:44 -0700187 {"readinto1", bufferediobase_readinto1, METH_VARARGS, NULL},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000188 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000189 {NULL, NULL}
190};
191
192PyTypeObject PyBufferedIOBase_Type = {
193 PyVarObject_HEAD_INIT(NULL, 0)
194 "_io._BufferedIOBase", /*tp_name*/
195 0, /*tp_basicsize*/
196 0, /*tp_itemsize*/
197 0, /*tp_dealloc*/
198 0, /*tp_print*/
199 0, /*tp_getattr*/
200 0, /*tp_setattr*/
201 0, /*tp_compare */
202 0, /*tp_repr*/
203 0, /*tp_as_number*/
204 0, /*tp_as_sequence*/
205 0, /*tp_as_mapping*/
206 0, /*tp_hash */
207 0, /*tp_call*/
208 0, /*tp_str*/
209 0, /*tp_getattro*/
210 0, /*tp_setattro*/
211 0, /*tp_as_buffer*/
Antoine Pitrou796564c2013-07-30 19:59:21 +0200212 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
213 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000214 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000215 0, /* tp_traverse */
216 0, /* tp_clear */
217 0, /* tp_richcompare */
218 0, /* tp_weaklistoffset */
219 0, /* tp_iter */
220 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000221 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000222 0, /* tp_members */
223 0, /* tp_getset */
224 &PyIOBase_Type, /* tp_base */
225 0, /* tp_dict */
226 0, /* tp_descr_get */
227 0, /* tp_descr_set */
228 0, /* tp_dictoffset */
229 0, /* tp_init */
230 0, /* tp_alloc */
231 0, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200232 0, /* tp_free */
233 0, /* tp_is_gc */
234 0, /* tp_bases */
235 0, /* tp_mro */
236 0, /* tp_cache */
237 0, /* tp_subclasses */
238 0, /* tp_weaklist */
239 0, /* tp_del */
240 0, /* tp_version_tag */
241 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000242};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000243
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000244
245typedef struct {
246 PyObject_HEAD
247
248 PyObject *raw;
249 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000250 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251 int readable;
252 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200253 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200254
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000255 /* True if this is a vanilla Buffered object (rather than a user derived
256 class) *and* the raw stream is a vanilla FileIO object. */
257 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000258
259 /* Absolute position inside the raw stream (-1 if unknown). */
260 Py_off_t abs_pos;
261
262 /* A static buffer of size `buffer_size` */
263 char *buffer;
264 /* Current logical position in the buffer. */
265 Py_off_t pos;
266 /* Position of the raw stream in the buffer. */
267 Py_off_t raw_pos;
268
269 /* Just after the last buffered byte in the buffer, or -1 if the buffer
270 isn't ready for reading. */
271 Py_off_t read_end;
272
273 /* Just after the last byte actually written */
274 Py_off_t write_pos;
275 /* Just after the last byte waiting to be written, or -1 if the buffer
276 isn't ready for writing. */
277 Py_off_t write_end;
278
Georg Brandldfd73442009-04-05 11:47:34 +0000279#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000280 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000281 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000282#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000283
284 Py_ssize_t buffer_size;
285 Py_ssize_t buffer_mask;
286
287 PyObject *dict;
288 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000289} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000290
291/*
292 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200293
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000294 * BufferedReader, BufferedWriter and BufferedRandom try to share most
295 methods (this is helped by the members `readable` and `writable`, which
296 are initialized in the respective constructors)
297 * They also share a single buffer for reading and writing. This enables
298 interleaved reads and writes without flushing. It also makes the logic
299 a bit trickier to get right.
300 * The absolute position of the raw stream is cached, if possible, in the
301 `abs_pos` member. It must be updated every time an operation is done
302 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000303 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000304 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000305 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
306 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000307
308 NOTE: we should try to maintain block alignment of reads and writes to the
309 raw stream (according to the buffer size), but for now it is only done
310 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200311
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000312*/
313
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000314/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000315
Georg Brandldfd73442009-04-05 11:47:34 +0000316#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000317
318static int
319_enter_buffered_busy(buffered *self)
320{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200321 int relax_locking;
322 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000323 if (self->owner == PyThread_get_thread_ident()) {
324 PyErr_Format(PyExc_RuntimeError,
325 "reentrant call inside %R", self);
326 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000327 }
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200328 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000329 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200330 if (!relax_locking)
331 st = PyThread_acquire_lock(self->lock, 1);
332 else {
333 /* When finalizing, we don't want a deadlock to happen with daemon
334 * threads abruptly shut down while they owned the lock.
335 * Therefore, only wait for a grace period (1 s.).
336 * Note that non-daemon threads have already exited here, so this
337 * shouldn't affect carefully written threaded I/O code.
338 */
339 st = PyThread_acquire_lock_timed(self->lock, 1e6, 0);
340 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000341 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200342 if (relax_locking && st != PY_LOCK_ACQUIRED) {
343 PyObject *msgobj = PyUnicode_FromFormat(
344 "could not acquire lock for %A at interpreter "
345 "shutdown, possibly due to daemon threads",
346 (PyObject *) self);
347 char *msg = PyUnicode_AsUTF8(msgobj);
348 Py_FatalError(msg);
349 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000350 return 1;
351}
352
353#define ENTER_BUFFERED(self) \
354 ( (PyThread_acquire_lock(self->lock, 0) ? \
355 1 : _enter_buffered_busy(self)) \
356 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000357
358#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000359 do { \
360 self->owner = 0; \
361 PyThread_release_lock(self->lock); \
362 } while(0);
363
Georg Brandldfd73442009-04-05 11:47:34 +0000364#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000365#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000366#define LEAVE_BUFFERED(self)
367#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000368
369#define CHECK_INITIALIZED(self) \
370 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000371 if (self->detached) { \
372 PyErr_SetString(PyExc_ValueError, \
373 "raw stream has been detached"); \
374 } else { \
375 PyErr_SetString(PyExc_ValueError, \
376 "I/O operation on uninitialized object"); \
377 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000378 return NULL; \
379 }
380
381#define CHECK_INITIALIZED_INT(self) \
382 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000383 if (self->detached) { \
384 PyErr_SetString(PyExc_ValueError, \
385 "raw stream has been detached"); \
386 } else { \
387 PyErr_SetString(PyExc_ValueError, \
388 "I/O operation on uninitialized object"); \
389 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000390 return -1; \
391 }
392
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000393#define IS_CLOSED(self) \
394 (self->fast_closed_checks \
395 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000396 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000397
398#define CHECK_CLOSED(self, error_msg) \
399 if (IS_CLOSED(self)) { \
400 PyErr_SetString(PyExc_ValueError, error_msg); \
401 return NULL; \
402 }
403
404
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000405#define VALID_READ_BUFFER(self) \
406 (self->readable && self->read_end != -1)
407
408#define VALID_WRITE_BUFFER(self) \
409 (self->writable && self->write_end != -1)
410
411#define ADJUST_POSITION(self, _new_pos) \
412 do { \
413 self->pos = _new_pos; \
414 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
415 self->read_end = self->pos; \
416 } while(0)
417
418#define READAHEAD(self) \
419 ((self->readable && VALID_READ_BUFFER(self)) \
420 ? (self->read_end - self->pos) : 0)
421
422#define RAW_OFFSET(self) \
423 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
424 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
425
426#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000427 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000428
429#define MINUS_LAST_BLOCK(self, size) \
430 (self->buffer_mask ? \
431 (size & ~self->buffer_mask) : \
432 (self->buffer_size * (size / self->buffer_size)))
433
434
435static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000436buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000437{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200438 self->finalizing = 1;
439 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000440 return;
441 _PyObject_GC_UNTRACK(self);
442 self->ok = 0;
443 if (self->weakreflist != NULL)
444 PyObject_ClearWeakRefs((PyObject *)self);
445 Py_CLEAR(self->raw);
446 if (self->buffer) {
447 PyMem_Free(self->buffer);
448 self->buffer = NULL;
449 }
Georg Brandldfd73442009-04-05 11:47:34 +0000450#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000451 if (self->lock) {
452 PyThread_free_lock(self->lock);
453 self->lock = NULL;
454 }
Georg Brandldfd73442009-04-05 11:47:34 +0000455#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456 Py_CLEAR(self->dict);
457 Py_TYPE(self)->tp_free((PyObject *)self);
458}
459
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200460static PyObject *
461buffered_sizeof(buffered *self, void *unused)
462{
463 Py_ssize_t res;
464
465 res = sizeof(buffered);
466 if (self->buffer)
467 res += self->buffer_size;
468 return PyLong_FromSsize_t(res);
469}
470
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000471static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000472buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000473{
474 Py_VISIT(self->raw);
475 Py_VISIT(self->dict);
476 return 0;
477}
478
479static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000480buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482 self->ok = 0;
483 Py_CLEAR(self->raw);
484 Py_CLEAR(self->dict);
485 return 0;
486}
487
Antoine Pitroue033e062010-10-29 10:38:18 +0000488/* Because this can call arbitrary code, it shouldn't be called when
489 the refcount is 0 (that is, not directly from tp_dealloc unless
490 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000491static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000492buffered_dealloc_warn(buffered *self, PyObject *source)
493{
494 if (self->ok && self->raw) {
495 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200496 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000497 if (r)
498 Py_DECREF(r);
499 else
500 PyErr_Clear();
501 }
502 Py_RETURN_NONE;
503}
504
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505/*
506 * _BufferedIOMixin methods
507 * This is not a class, just a collection of methods that will be reused
508 * by BufferedReader and BufferedWriter
509 */
510
511/* Flush and close */
512
513static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000514buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515{
516 CHECK_INITIALIZED(self)
517 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
518}
519
520static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000521buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522{
523 int closed;
524 PyObject *res;
525 CHECK_INITIALIZED_INT(self)
526 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
527 if (res == NULL)
528 return -1;
529 closed = PyObject_IsTrue(res);
530 Py_DECREF(res);
531 return closed;
532}
533
534static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000535buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000536{
537 CHECK_INITIALIZED(self)
538 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
539}
540
541static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000542buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543{
Benjamin Peterson68623612012-12-20 11:53:11 -0600544 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000545 int r;
546
547 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000548 if (!ENTER_BUFFERED(self))
549 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000550
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000551 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000552 if (r < 0)
553 goto end;
554 if (r > 0) {
555 res = Py_None;
556 Py_INCREF(res);
557 goto end;
558 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000559
Antoine Pitrou796564c2013-07-30 19:59:21 +0200560 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000561 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
562 if (r)
563 Py_DECREF(r);
564 else
565 PyErr_Clear();
566 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000567 /* flush() will most probably re-take the lock, so drop it first */
568 LEAVE_BUFFERED(self)
569 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000570 if (!ENTER_BUFFERED(self))
571 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600572 if (res == NULL)
573 PyErr_Fetch(&exc, &val, &tb);
574 else
575 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576
577 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
578
Jesus Ceadc469452012-10-04 12:37:56 +0200579 if (self->buffer) {
580 PyMem_Free(self->buffer);
581 self->buffer = NULL;
582 }
583
Benjamin Peterson68623612012-12-20 11:53:11 -0600584 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300585 _PyErr_ChainExceptions(exc, val, tb);
586 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600587 }
588
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589end:
590 LEAVE_BUFFERED(self)
591 return res;
592}
593
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000594/* detach */
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000598{
599 PyObject *raw, *res;
600 CHECK_INITIALIZED(self)
601 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
602 if (res == NULL)
603 return NULL;
604 Py_DECREF(res);
605 raw = self->raw;
606 self->raw = NULL;
607 self->detached = 1;
608 self->ok = 0;
609 return raw;
610}
611
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000612/* Inquiries */
613
614static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616{
617 CHECK_INITIALIZED(self)
618 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
619}
620
621static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000622buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623{
624 CHECK_INITIALIZED(self)
625 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
626}
627
628static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000629buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630{
631 CHECK_INITIALIZED(self)
632 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
633}
634
635static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637{
638 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200639 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640}
641
642static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644{
645 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200646 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647}
648
649/* Lower-level APIs */
650
651static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653{
654 CHECK_INITIALIZED(self)
655 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
656}
657
658static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000659buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660{
661 CHECK_INITIALIZED(self)
662 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
663}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000664
Antoine Pitrou243757e2010-11-05 21:15:39 +0000665/* Serialization */
666
667static PyObject *
668buffered_getstate(buffered *self, PyObject *args)
669{
670 PyErr_Format(PyExc_TypeError,
671 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
672 return NULL;
673}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000674
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675/* Forward decls */
676static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100677_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000679_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000681_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000683_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200685_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000686static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000687_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000688static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000689_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000690static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000691_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200692static Py_ssize_t
693_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000694
695/*
696 * Helpers
697 */
698
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100699/* Sets the current error to BlockingIOError */
700static void
701_set_BlockingIOError(char *msg, Py_ssize_t written)
702{
703 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200704 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100705 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
706 errno, msg, written);
707 if (err)
708 PyErr_SetObject(PyExc_BlockingIOError, err);
709 Py_XDECREF(err);
710}
711
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712/* Returns the address of the `written` member if a BlockingIOError was
713 raised, NULL otherwise. The error is always re-raised. */
714static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000715_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716{
717 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200718 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000719
720 PyErr_Fetch(&t, &v, &tb);
721 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
722 PyErr_Restore(t, v, tb);
723 return NULL;
724 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200725 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000726 /* TODO: sanity check (err->written >= 0) */
727 PyErr_Restore(t, v, tb);
728 return &err->written;
729}
730
731static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000732_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000733{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000734 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000735 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000736 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
737 if (res == NULL)
738 return -1;
739 n = PyNumber_AsOff_t(res, PyExc_ValueError);
740 Py_DECREF(res);
741 if (n < 0) {
742 if (!PyErr_Occurred())
743 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000744 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200745 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000746 return -1;
747 }
748 self->abs_pos = n;
749 return n;
750}
751
752static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000753_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754{
755 PyObject *res, *posobj, *whenceobj;
756 Py_off_t n;
757
758 posobj = PyLong_FromOff_t(target);
759 if (posobj == NULL)
760 return -1;
761 whenceobj = PyLong_FromLong(whence);
762 if (whenceobj == NULL) {
763 Py_DECREF(posobj);
764 return -1;
765 }
766 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
767 posobj, whenceobj, NULL);
768 Py_DECREF(posobj);
769 Py_DECREF(whenceobj);
770 if (res == NULL)
771 return -1;
772 n = PyNumber_AsOff_t(res, PyExc_ValueError);
773 Py_DECREF(res);
774 if (n < 0) {
775 if (!PyErr_Occurred())
776 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000777 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200778 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000779 return -1;
780 }
781 self->abs_pos = n;
782 return n;
783}
784
785static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000786_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000787{
788 Py_ssize_t n;
789 if (self->buffer_size <= 0) {
790 PyErr_SetString(PyExc_ValueError,
791 "buffer size must be strictly positive");
792 return -1;
793 }
794 if (self->buffer)
795 PyMem_Free(self->buffer);
796 self->buffer = PyMem_Malloc(self->buffer_size);
797 if (self->buffer == NULL) {
798 PyErr_NoMemory();
799 return -1;
800 }
Georg Brandldfd73442009-04-05 11:47:34 +0000801#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000802 if (self->lock)
803 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000804 self->lock = PyThread_allocate_lock();
805 if (self->lock == NULL) {
806 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
807 return -1;
808 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000809 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000810#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000811 /* Find out whether buffer_size is a power of 2 */
812 /* XXX is this optimization useful? */
813 for (n = self->buffer_size - 1; n & 1; n >>= 1)
814 ;
815 if (n == 0)
816 self->buffer_mask = self->buffer_size - 1;
817 else
818 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000819 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000820 PyErr_Clear();
821 return 0;
822}
823
Antoine Pitrou707ce822011-02-25 21:24:11 +0000824/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
825 clears the error indicator), 0 otherwise.
826 Should only be called when PyErr_Occurred() is true.
827*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700828int
829_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000830{
831 static PyObject *eintr_int = NULL;
832 PyObject *typ, *val, *tb;
833 PyEnvironmentErrorObject *env_err;
834
835 if (eintr_int == NULL) {
836 eintr_int = PyLong_FromLong(EINTR);
837 assert(eintr_int != NULL);
838 }
839 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
840 return 0;
841 PyErr_Fetch(&typ, &val, &tb);
842 PyErr_NormalizeException(&typ, &val, &tb);
843 env_err = (PyEnvironmentErrorObject *) val;
844 assert(env_err != NULL);
845 if (env_err->myerrno != NULL &&
846 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
847 Py_DECREF(typ);
848 Py_DECREF(val);
849 Py_XDECREF(tb);
850 return 1;
851 }
852 /* This silences any error set by PyObject_RichCompareBool() */
853 PyErr_Restore(typ, val, tb);
854 return 0;
855}
856
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000857/*
858 * Shared methods and wrappers
859 */
860
861static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200862buffered_flush_and_rewind_unlocked(buffered *self)
863{
864 PyObject *res;
865
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100866 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200867 if (res == NULL)
868 return NULL;
869 Py_DECREF(res);
870
871 if (self->readable) {
872 /* Rewind the raw stream so that its position corresponds to
873 the current logical position. */
874 Py_off_t n;
875 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
876 _bufferedreader_reset_buf(self);
877 if (n == -1)
878 return NULL;
879 }
880 Py_RETURN_NONE;
881}
882
883static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000884buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885{
886 PyObject *res;
887
888 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000889 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000891 if (!ENTER_BUFFERED(self))
892 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200893 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000894 LEAVE_BUFFERED(self)
895
896 return res;
897}
898
899static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000900buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901{
902 Py_ssize_t n = 0;
903 PyObject *res = NULL;
904
905 CHECK_INITIALIZED(self)
906 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
907 return NULL;
908 }
909
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000910 if (!ENTER_BUFFERED(self))
911 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912
913 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200914 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915 if (res == NULL)
916 goto end;
917 Py_CLEAR(res);
918 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200919 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920
921end:
922 LEAVE_BUFFERED(self)
923 return res;
924}
925
926static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000927buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000928{
929 Py_ssize_t n = -1;
930 PyObject *res;
931
932 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000933 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000934 return NULL;
935 }
936 if (n < -1) {
937 PyErr_SetString(PyExc_ValueError,
938 "read length must be positive or -1");
939 return NULL;
940 }
941
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000942 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000944 if (n == -1) {
945 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000946 if (!ENTER_BUFFERED(self))
947 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000948 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000949 }
950 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000951 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200952 if (res != Py_None)
953 return res;
954 Py_DECREF(res);
955 if (!ENTER_BUFFERED(self))
956 return NULL;
957 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000958 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959
Antoine Pitroue05565e2011-08-20 14:39:23 +0200960 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961 return res;
962}
963
964static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000965buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000966{
967 Py_ssize_t n, have, r;
968 PyObject *res = NULL;
969
970 CHECK_INITIALIZED(self)
971 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
972 return NULL;
973 }
974
975 if (n < 0) {
976 PyErr_SetString(PyExc_ValueError,
977 "read length must be positive");
978 return NULL;
979 }
980 if (n == 0)
981 return PyBytes_FromStringAndSize(NULL, 0);
982
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983 /* Return up to n bytes. If at least one byte is buffered, we
984 only return buffered bytes. Otherwise, we do one raw read. */
985
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
987 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100988 n = Py_MIN(have, n);
989 res = _bufferedreader_read_fast(self, n);
990 assert(res != Py_None);
991 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100993 res = PyBytes_FromStringAndSize(NULL, n);
994 if (res == NULL)
995 return NULL;
996 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200997 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100998 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200999 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001000 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +01001001 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
1002 LEAVE_BUFFERED(self)
1003 if (r == -1) {
1004 Py_DECREF(res);
1005 return NULL;
1006 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001007 if (r == -2)
1008 r = 0;
1009 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +01001010 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001011 return res;
1012}
1013
1014static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07001015_buffered_readinto_generic(buffered *self, PyObject *args, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001016{
Antoine Pitrou3486a982011-05-12 01:57:53 +02001017 Py_buffer buf;
1018 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001019 PyObject *res = NULL;
1020
1021 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022
Benjamin Petersona96fea02014-06-22 14:17:44 -07001023 if (!PyArg_ParseTuple(args,
1024 readinto1 ? "w*:readinto1" : "w*:readinto",
1025 &buf))
Antoine Pitrou3486a982011-05-12 01:57:53 +02001026 return NULL;
1027
1028 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1029 if (n > 0) {
1030 if (n >= buf.len) {
1031 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1032 self->pos += buf.len;
1033 res = PyLong_FromSsize_t(buf.len);
1034 goto end_unlocked;
1035 }
1036 memcpy(buf.buf, self->buffer + self->pos, n);
1037 self->pos += n;
1038 written = n;
1039 }
1040
1041 if (!ENTER_BUFFERED(self))
1042 goto end_unlocked;
1043
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001045 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046 if (res == NULL)
1047 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001048 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001050
1051 _bufferedreader_reset_buf(self);
1052 self->pos = 0;
1053
1054 for (remaining = buf.len - written;
1055 remaining > 0;
1056 written += n, remaining -= n) {
1057 /* If remaining bytes is larger than internal buffer size, copy
1058 * directly into caller's buffer. */
1059 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001060 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1061 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001062 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001063
1064 /* In readinto1 mode, we do not want to fill the internal
1065 buffer if we already have some data to return */
1066 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001067 n = _bufferedreader_fill_buffer(self);
1068 if (n > 0) {
1069 if (n > remaining)
1070 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001071 memcpy((char *) buf.buf + written,
1072 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001073 self->pos += n;
1074 continue; /* short circuit */
1075 }
1076 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001077 else
1078 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001079
Antoine Pitrou3486a982011-05-12 01:57:53 +02001080 if (n == 0 || (n == -2 && written > 0))
1081 break;
1082 if (n < 0) {
1083 if (n == -2) {
1084 Py_INCREF(Py_None);
1085 res = Py_None;
1086 }
1087 goto end;
1088 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001089
Benjamin Petersona96fea02014-06-22 14:17:44 -07001090 /* At most one read in readinto1 mode */
1091 if (readinto1) {
1092 written += n;
1093 break;
1094 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001095 }
1096 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001097
1098end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001099 LEAVE_BUFFERED(self);
1100end_unlocked:
1101 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102 return res;
1103}
1104
1105static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07001106buffered_readinto(buffered *self, PyObject *args)
1107{
1108 return _buffered_readinto_generic(self, args, 0);
1109}
1110
1111static PyObject *
1112buffered_readinto1(buffered *self, PyObject *args)
1113{
1114 return _buffered_readinto_generic(self, args, 1);
1115}
1116
1117
1118static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001119_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001120{
1121 PyObject *res = NULL;
1122 PyObject *chunks = NULL;
1123 Py_ssize_t n, written = 0;
1124 const char *start, *s, *end;
1125
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001126 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001128 /* First, try to find a line in the buffer. This can run unlocked because
1129 the calls to the C API are simple enough that they can't trigger
1130 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001131 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1132 if (limit >= 0 && n > limit)
1133 n = limit;
1134 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001135 s = memchr(start, '\n', n);
1136 if (s != NULL) {
1137 res = PyBytes_FromStringAndSize(start, s - start + 1);
1138 if (res != NULL)
1139 self->pos += s - start + 1;
1140 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001141 }
1142 if (n == limit) {
1143 res = PyBytes_FromStringAndSize(start, n);
1144 if (res != NULL)
1145 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001146 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147 }
1148
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001149 if (!ENTER_BUFFERED(self))
1150 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001151
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001152 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001153 chunks = PyList_New(0);
1154 if (chunks == NULL)
1155 goto end;
1156 if (n > 0) {
1157 res = PyBytes_FromStringAndSize(start, n);
1158 if (res == NULL)
1159 goto end;
1160 if (PyList_Append(chunks, res) < 0) {
1161 Py_CLEAR(res);
1162 goto end;
1163 }
1164 Py_CLEAR(res);
1165 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001166 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001167 if (limit >= 0)
1168 limit -= n;
1169 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001170 if (self->writable) {
1171 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1172 if (r == NULL)
1173 goto end;
1174 Py_DECREF(r);
1175 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176
1177 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001178 _bufferedreader_reset_buf(self);
1179 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001180 if (n == -1)
1181 goto end;
1182 if (n <= 0)
1183 break;
1184 if (limit >= 0 && n > limit)
1185 n = limit;
1186 start = self->buffer;
1187 end = start + n;
1188 s = start;
1189 while (s < end) {
1190 if (*s++ == '\n') {
1191 res = PyBytes_FromStringAndSize(start, s - start);
1192 if (res == NULL)
1193 goto end;
1194 self->pos = s - start;
1195 goto found;
1196 }
1197 }
1198 res = PyBytes_FromStringAndSize(start, n);
1199 if (res == NULL)
1200 goto end;
1201 if (n == limit) {
1202 self->pos = n;
1203 break;
1204 }
1205 if (PyList_Append(chunks, res) < 0) {
1206 Py_CLEAR(res);
1207 goto end;
1208 }
1209 Py_CLEAR(res);
1210 written += n;
1211 if (limit >= 0)
1212 limit -= n;
1213 }
1214found:
1215 if (res != NULL && PyList_Append(chunks, res) < 0) {
1216 Py_CLEAR(res);
1217 goto end;
1218 }
1219 Py_CLEAR(res);
1220 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1221
1222end:
1223 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001224end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225 Py_XDECREF(chunks);
1226 return res;
1227}
1228
1229static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001230buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231{
1232 Py_ssize_t limit = -1;
1233
1234 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001235 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001237 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238}
1239
1240
1241static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001242buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243{
1244 Py_off_t pos;
1245
1246 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001247 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001248 if (pos == -1)
1249 return NULL;
1250 pos -= RAW_OFFSET(self);
1251 /* TODO: sanity check (pos >= 0) */
1252 return PyLong_FromOff_t(pos);
1253}
1254
1255static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001256buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001257{
1258 Py_off_t target, n;
1259 int whence = 0;
1260 PyObject *targetobj, *res = NULL;
1261
1262 CHECK_INITIALIZED(self)
1263 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1264 return NULL;
1265 }
Jesus Cea94363612012-06-22 18:32:07 +02001266
1267 /* Do some error checking instead of trusting OS 'seek()'
1268 ** error detection, just in case.
1269 */
1270 if ((whence < 0 || whence >2)
1271#ifdef SEEK_HOLE
1272 && (whence != SEEK_HOLE)
1273#endif
1274#ifdef SEEK_DATA
1275 && (whence != SEEK_DATA)
1276#endif
1277 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001279 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001280 return NULL;
1281 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001282
1283 CHECK_CLOSED(self, "seek of closed file")
1284
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001285 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1286 return NULL;
1287
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1289 if (target == -1 && PyErr_Occurred())
1290 return NULL;
1291
Jesus Cea94363612012-06-22 18:32:07 +02001292 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1293 buffer. Other whence values must be managed without this optimization.
1294 Some Operating Systems can provide additional values, like
1295 SEEK_HOLE/SEEK_DATA. */
1296 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001297 Py_off_t current, avail;
1298 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001299 so as to return quickly if possible. Also, we needn't take the
1300 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001302 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1303 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001304 current = RAW_TELL(self);
1305 avail = READAHEAD(self);
1306 if (avail > 0) {
1307 Py_off_t offset;
1308 if (whence == 0)
1309 offset = target - (current - RAW_OFFSET(self));
1310 else
1311 offset = target;
1312 if (offset >= -self->pos && offset <= avail) {
1313 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001314 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001315 }
1316 }
1317 }
1318
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001319 if (!ENTER_BUFFERED(self))
1320 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001321
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 /* Fallback: invoke raw seek() method and clear buffer */
1323 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001324 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001325 if (res == NULL)
1326 goto end;
1327 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001328 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001329 }
1330
1331 /* TODO: align on block boundary and read buffer if needed? */
1332 if (whence == 1)
1333 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001334 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 if (n == -1)
1336 goto end;
1337 self->raw_pos = -1;
1338 res = PyLong_FromOff_t(n);
1339 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001340 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341
1342end:
1343 LEAVE_BUFFERED(self)
1344 return res;
1345}
1346
1347static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001348buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349{
1350 PyObject *pos = Py_None;
1351 PyObject *res = NULL;
1352
1353 CHECK_INITIALIZED(self)
1354 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1355 return NULL;
1356 }
1357
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001358 if (!ENTER_BUFFERED(self))
1359 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360
1361 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001362 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001363 if (res == NULL)
1364 goto end;
1365 Py_CLEAR(res);
1366 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1368 if (res == NULL)
1369 goto end;
1370 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372 PyErr_Clear();
1373
1374end:
1375 LEAVE_BUFFERED(self)
1376 return res;
1377}
1378
1379static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001380buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381{
1382 PyObject *line;
1383 PyTypeObject *tp;
1384
1385 CHECK_INITIALIZED(self);
1386
1387 tp = Py_TYPE(self);
1388 if (tp == &PyBufferedReader_Type ||
1389 tp == &PyBufferedRandom_Type) {
1390 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001391 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001392 }
1393 else {
1394 line = PyObject_CallMethodObjArgs((PyObject *)self,
1395 _PyIO_str_readline, NULL);
1396 if (line && !PyBytes_Check(line)) {
1397 PyErr_Format(PyExc_IOError,
1398 "readline() should have returned a bytes object, "
1399 "not '%.200s'", Py_TYPE(line)->tp_name);
1400 Py_DECREF(line);
1401 return NULL;
1402 }
1403 }
1404
1405 if (line == NULL)
1406 return NULL;
1407
1408 if (PyBytes_GET_SIZE(line) == 0) {
1409 /* Reached EOF or would have blocked */
1410 Py_DECREF(line);
1411 return NULL;
1412 }
1413
1414 return line;
1415}
1416
Antoine Pitrou716c4442009-05-23 19:04:03 +00001417static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001418buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001419{
1420 PyObject *nameobj, *res;
1421
Martin v. Löwis767046a2011-10-14 15:35:36 +02001422 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001423 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001424 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001425 PyErr_Clear();
1426 else
1427 return NULL;
1428 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1429 }
1430 else {
1431 res = PyUnicode_FromFormat("<%s name=%R>",
1432 Py_TYPE(self)->tp_name, nameobj);
1433 Py_DECREF(nameobj);
1434 }
1435 return res;
1436}
1437
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438/*
1439 * class BufferedReader
1440 */
1441
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001442PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443 "Create a new buffered reader using the given readable raw IO object.");
1444
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001445static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001446{
1447 self->read_end = -1;
1448}
1449
1450static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001451bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001452{
1453 char *kwlist[] = {"raw", "buffer_size", NULL};
1454 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1455 PyObject *raw;
1456
1457 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001458 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001459
1460 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1461 &raw, &buffer_size)) {
1462 return -1;
1463 }
1464
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001465 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 return -1;
1467
1468 Py_CLEAR(self->raw);
1469 Py_INCREF(raw);
1470 self->raw = raw;
1471 self->buffer_size = buffer_size;
1472 self->readable = 1;
1473 self->writable = 0;
1474
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001475 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001476 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001477 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001478
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001479 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1480 Py_TYPE(raw) == &PyFileIO_Type);
1481
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001482 self->ok = 1;
1483 return 0;
1484}
1485
1486static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001487_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001488{
1489 Py_buffer buf;
1490 PyObject *memobj, *res;
1491 Py_ssize_t n;
1492 /* NOTE: the buffer needn't be released as its object is NULL. */
1493 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1494 return -1;
1495 memobj = PyMemoryView_FromBuffer(&buf);
1496 if (memobj == NULL)
1497 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001498 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1499 occurs so we needn't do it ourselves.
1500 We then retry reading, ignoring the signal if no handler has
1501 raised (see issue #10956).
1502 */
1503 do {
1504 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001505 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001506 Py_DECREF(memobj);
1507 if (res == NULL)
1508 return -1;
1509 if (res == Py_None) {
1510 /* Non-blocking stream would have blocked. Special return code! */
1511 Py_DECREF(res);
1512 return -2;
1513 }
1514 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1515 Py_DECREF(res);
1516 if (n < 0 || n > len) {
1517 PyErr_Format(PyExc_IOError,
1518 "raw readinto() returned invalid length %zd "
1519 "(should have been between 0 and %zd)", n, len);
1520 return -1;
1521 }
1522 if (n > 0 && self->abs_pos != -1)
1523 self->abs_pos += n;
1524 return n;
1525}
1526
1527static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001528_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001529{
1530 Py_ssize_t start, len, n;
1531 if (VALID_READ_BUFFER(self))
1532 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1533 else
1534 start = 0;
1535 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001536 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 if (n <= 0)
1538 return n;
1539 self->read_end = start + n;
1540 self->raw_pos = start + n;
1541 return n;
1542}
1543
1544static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001545_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001546{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001547 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001548 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001549
1550 /* First copy what we have in the current buffer. */
1551 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1552 if (current_size) {
1553 data = PyBytes_FromStringAndSize(
1554 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001555 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001556 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001557 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001558 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001559 /* We're going past the buffer's bounds, flush it */
1560 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001561 tmp = buffered_flush_and_rewind_unlocked(self);
1562 if (tmp == NULL)
1563 goto cleanup;
1564 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001565 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001566 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001567
1568 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1570 if (tmp == NULL)
1571 goto cleanup;
1572 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001573 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001574 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001575 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001576 if (tmp == Py_None) {
1577 if (current_size == 0) {
1578 res = Py_None;
1579 goto cleanup;
1580 } else {
1581 res = data;
1582 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001583 }
1584 }
1585 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001586 PyBytes_Concat(&data, tmp);
1587 res = data;
1588 goto cleanup;
1589 }
1590 else {
1591 res = tmp;
1592 goto cleanup;
1593 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001594 }
1595
1596 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001597 if (chunks == NULL)
1598 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001599
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001600 while (1) {
1601 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001602 if (PyList_Append(chunks, data) < 0)
1603 goto cleanup;
1604 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001605 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607 /* Read until EOF or until read() would block. */
1608 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001609 if (data == NULL)
1610 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001612 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001613 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001614 }
1615 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1616 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001617 res = data;
1618 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001619 }
1620 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001621 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1622 res = tmp;
1623 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001624 }
1625 }
1626 current_size += PyBytes_GET_SIZE(data);
1627 if (self->abs_pos != -1)
1628 self->abs_pos += PyBytes_GET_SIZE(data);
1629 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001630cleanup:
1631 /* res is either NULL or a borrowed ref */
1632 Py_XINCREF(res);
1633 Py_XDECREF(data);
1634 Py_XDECREF(tmp);
1635 Py_XDECREF(chunks);
1636 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001637}
1638
1639/* Read n bytes from the buffer if it can, otherwise return None.
1640 This function is simple enough that it can run unlocked. */
1641static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001642_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001643{
1644 Py_ssize_t current_size;
1645
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001646 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1647 if (n <= current_size) {
1648 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001649 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1650 if (res != NULL)
1651 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001652 return res;
1653 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001654 Py_RETURN_NONE;
1655}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001656
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001657/* Generic read function: read from the stream until enough bytes are read,
1658 * or until an EOF occurs or until read() would block.
1659 */
1660static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001661_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001662{
1663 PyObject *res = NULL;
1664 Py_ssize_t current_size, remaining, written;
1665 char *out;
1666
1667 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1668 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001669 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001670
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001671 res = PyBytes_FromStringAndSize(NULL, n);
1672 if (res == NULL)
1673 goto error;
1674 out = PyBytes_AS_STRING(res);
1675 remaining = n;
1676 written = 0;
1677 if (current_size > 0) {
1678 memcpy(out, self->buffer + self->pos, current_size);
1679 remaining -= current_size;
1680 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001681 self->pos += current_size;
1682 }
1683 /* Flush the write buffer if necessary */
1684 if (self->writable) {
1685 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1686 if (r == NULL)
1687 goto error;
1688 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001689 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001690 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001691 while (remaining > 0) {
1692 /* We want to read a whole block at the end into buffer.
1693 If we had readv() we could do this in one pass. */
1694 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1695 if (r == 0)
1696 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001697 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001698 if (r == -1)
1699 goto error;
1700 if (r == 0 || r == -2) {
1701 /* EOF occurred or read() would block. */
1702 if (r == 0 || written > 0) {
1703 if (_PyBytes_Resize(&res, written))
1704 goto error;
1705 return res;
1706 }
1707 Py_DECREF(res);
1708 Py_INCREF(Py_None);
1709 return Py_None;
1710 }
1711 remaining -= r;
1712 written += r;
1713 }
1714 assert(remaining <= self->buffer_size);
1715 self->pos = 0;
1716 self->raw_pos = 0;
1717 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001718 /* NOTE: when the read is satisfied, we avoid issuing any additional
1719 reads, which could block indefinitely (e.g. on a socket).
1720 See issue #9550. */
1721 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001722 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001723 if (r == -1)
1724 goto error;
1725 if (r == 0 || r == -2) {
1726 /* EOF occurred or read() would block. */
1727 if (r == 0 || written > 0) {
1728 if (_PyBytes_Resize(&res, written))
1729 goto error;
1730 return res;
1731 }
1732 Py_DECREF(res);
1733 Py_INCREF(Py_None);
1734 return Py_None;
1735 }
1736 if (remaining > r) {
1737 memcpy(out + written, self->buffer + self->pos, r);
1738 written += r;
1739 self->pos += r;
1740 remaining -= r;
1741 }
1742 else if (remaining > 0) {
1743 memcpy(out + written, self->buffer + self->pos, remaining);
1744 written += remaining;
1745 self->pos += remaining;
1746 remaining = 0;
1747 }
1748 if (remaining == 0)
1749 break;
1750 }
1751
1752 return res;
1753
1754error:
1755 Py_XDECREF(res);
1756 return NULL;
1757}
1758
1759static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001760_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761{
1762 Py_ssize_t have, r;
1763
1764 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1765 /* Constraints:
1766 1. we don't want to advance the file position.
1767 2. we don't want to lose block alignment, so we can't shift the buffer
1768 to make some place.
1769 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1770 */
1771 if (have > 0) {
1772 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1773 }
1774
1775 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776 _bufferedreader_reset_buf(self);
1777 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 if (r == -1)
1779 return NULL;
1780 if (r == -2)
1781 r = 0;
1782 self->pos = 0;
1783 return PyBytes_FromStringAndSize(self->buffer, r);
1784}
1785
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001786static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001788 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1789 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1790 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1791 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1792 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1793 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1794 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1795 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001796 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001797 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001798
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1800 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1801 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001802 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07001803 {"readinto1", (PyCFunction)buffered_readinto1, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001804 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1805 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1806 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1807 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001808 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 {NULL, NULL}
1810};
1811
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001813 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001814 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 {NULL}
1816};
1817
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001818static PyGetSetDef bufferedreader_getset[] = {
1819 {"closed", (getter)buffered_closed_get, NULL, NULL},
1820 {"name", (getter)buffered_name_get, NULL, NULL},
1821 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001822 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823};
1824
1825
1826PyTypeObject PyBufferedReader_Type = {
1827 PyVarObject_HEAD_INIT(NULL, 0)
1828 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001829 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001831 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832 0, /*tp_print*/
1833 0, /*tp_getattr*/
1834 0, /*tp_setattr*/
1835 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001836 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001837 0, /*tp_as_number*/
1838 0, /*tp_as_sequence*/
1839 0, /*tp_as_mapping*/
1840 0, /*tp_hash */
1841 0, /*tp_call*/
1842 0, /*tp_str*/
1843 0, /*tp_getattro*/
1844 0, /*tp_setattro*/
1845 0, /*tp_as_buffer*/
1846 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001847 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001848 bufferedreader_doc, /* tp_doc */
1849 (traverseproc)buffered_traverse, /* tp_traverse */
1850 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001852 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001854 (iternextfunc)buffered_iternext, /* tp_iternext */
1855 bufferedreader_methods, /* tp_methods */
1856 bufferedreader_members, /* tp_members */
1857 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858 0, /* tp_base */
1859 0, /* tp_dict */
1860 0, /* tp_descr_get */
1861 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001862 offsetof(buffered, dict), /* tp_dictoffset */
1863 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864 0, /* tp_alloc */
1865 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001866 0, /* tp_free */
1867 0, /* tp_is_gc */
1868 0, /* tp_bases */
1869 0, /* tp_mro */
1870 0, /* tp_cache */
1871 0, /* tp_subclasses */
1872 0, /* tp_weaklist */
1873 0, /* tp_del */
1874 0, /* tp_version_tag */
1875 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001876};
1877
1878
Benjamin Peterson59406a92009-03-26 17:10:29 +00001879
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880/*
1881 * class BufferedWriter
1882 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001883PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884 "A buffer for a writeable sequential RawIO object.\n"
1885 "\n"
1886 "The constructor creates a BufferedWriter for the given writeable raw\n"
1887 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001888 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 );
1890
1891static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001892_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001893{
1894 self->write_pos = 0;
1895 self->write_end = -1;
1896}
1897
1898static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001899bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900{
Florent Xicluna109d5732012-07-07 17:03:22 +02001901 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001902 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001903 PyObject *raw;
1904
1905 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001906 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001907
R David Murray9f10f562013-02-23 22:07:55 -05001908 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001909 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001910 return -1;
1911 }
1912
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001913 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001914 return -1;
1915
1916 Py_CLEAR(self->raw);
1917 Py_INCREF(raw);
1918 self->raw = raw;
1919 self->readable = 0;
1920 self->writable = 1;
1921
1922 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001923 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001925 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926 self->pos = 0;
1927
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001928 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1929 Py_TYPE(raw) == &PyFileIO_Type);
1930
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001931 self->ok = 1;
1932 return 0;
1933}
1934
1935static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001936_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937{
1938 Py_buffer buf;
1939 PyObject *memobj, *res;
1940 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001941 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942 /* NOTE: the buffer needn't be released as its object is NULL. */
1943 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1944 return -1;
1945 memobj = PyMemoryView_FromBuffer(&buf);
1946 if (memobj == NULL)
1947 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001948 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1949 occurs so we needn't do it ourselves.
1950 We then retry writing, ignoring the signal if no handler has
1951 raised (see issue #10956).
1952 */
1953 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001954 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001955 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001956 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001957 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 Py_DECREF(memobj);
1959 if (res == NULL)
1960 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001961 if (res == Py_None) {
1962 /* Non-blocking stream would have blocked. Special return code!
1963 Being paranoid we reset errno in case it is changed by code
1964 triggered by a decref. errno is used by _set_BlockingIOError(). */
1965 Py_DECREF(res);
1966 errno = errnum;
1967 return -2;
1968 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1970 Py_DECREF(res);
1971 if (n < 0 || n > len) {
1972 PyErr_Format(PyExc_IOError,
1973 "raw write() returned invalid length %zd "
1974 "(should have been between 0 and %zd)", n, len);
1975 return -1;
1976 }
1977 if (n > 0 && self->abs_pos != -1)
1978 self->abs_pos += n;
1979 return n;
1980}
1981
1982/* `restore_pos` is 1 if we need to restore the raw stream position at
1983 the end, 0 otherwise. */
1984static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001985_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001986{
1987 Py_ssize_t written = 0;
1988 Py_off_t n, rewind;
1989
1990 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1991 goto end;
1992 /* First, rewind */
1993 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1994 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001995 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 if (n < 0) {
1997 goto error;
1998 }
1999 self->raw_pos -= rewind;
2000 }
2001 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002002 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003 self->buffer + self->write_pos,
2004 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2005 Py_off_t, Py_ssize_t));
2006 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002007 goto error;
2008 }
2009 else if (n == -2) {
2010 _set_BlockingIOError("write could not complete without blocking",
2011 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 goto error;
2013 }
2014 self->write_pos += n;
2015 self->raw_pos = self->write_pos;
2016 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002017 /* Partial writes can return successfully when interrupted by a
2018 signal (see write(2)). We must run signal handlers before
2019 blocking another time, possibly indefinitely. */
2020 if (PyErr_CheckSignals() < 0)
2021 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022 }
2023
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002024 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025
2026end:
2027 Py_RETURN_NONE;
2028
2029error:
2030 return NULL;
2031}
2032
2033static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002034bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035{
2036 PyObject *res = NULL;
2037 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002038 Py_ssize_t written, avail, remaining;
2039 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002040
2041 CHECK_INITIALIZED(self)
2042 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
2043 return NULL;
2044 }
2045
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002046 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002047 PyErr_SetString(PyExc_ValueError, "write to closed file");
2048 PyBuffer_Release(&buf);
2049 return NULL;
2050 }
2051
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00002052 if (!ENTER_BUFFERED(self)) {
2053 PyBuffer_Release(&buf);
2054 return NULL;
2055 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056
2057 /* Fast path: the data to write can be fully buffered. */
2058 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2059 self->pos = 0;
2060 self->raw_pos = 0;
2061 }
2062 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2063 if (buf.len <= avail) {
2064 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002065 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 self->write_pos = self->pos;
2067 }
2068 ADJUST_POSITION(self, self->pos + buf.len);
2069 if (self->pos > self->write_end)
2070 self->write_end = self->pos;
2071 written = buf.len;
2072 goto end;
2073 }
2074
2075 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002076 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002077 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002078 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002079 if (w == NULL)
2080 goto error;
2081 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002082 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083 /* Make some place by shifting the buffer. */
2084 assert(VALID_WRITE_BUFFER(self));
2085 memmove(self->buffer, self->buffer + self->write_pos,
2086 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2087 Py_off_t, Py_ssize_t));
2088 self->write_end -= self->write_pos;
2089 self->raw_pos -= self->write_pos;
2090 self->pos -= self->write_pos;
2091 self->write_pos = 0;
2092 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2093 Py_off_t, Py_ssize_t);
2094 if (buf.len <= avail) {
2095 /* Everything can be buffered */
2096 PyErr_Clear();
2097 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2098 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002099 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002100 written = buf.len;
2101 goto end;
2102 }
2103 /* Buffer as much as possible. */
2104 memcpy(self->buffer + self->write_end, buf.buf, avail);
2105 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002106 self->pos += avail;
2107 /* XXX Modifying the existing exception e using the pointer w
2108 will change e.characters_written but not e.args[2].
2109 Therefore we just replace with a new error. */
2110 _set_BlockingIOError("write could not complete without blocking",
2111 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002112 goto error;
2113 }
2114 Py_CLEAR(res);
2115
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002116 /* Adjust the raw stream position if it is away from the logical stream
2117 position. This happens if the read buffer has been filled but not
2118 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2119 the raw stream by itself).
2120 Fixes issue #6629.
2121 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002122 offset = RAW_OFFSET(self);
2123 if (offset != 0) {
2124 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002125 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002126 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002127 }
2128
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002129 /* Then write buf itself. At this point the buffer has been emptied. */
2130 remaining = buf.len;
2131 written = 0;
2132 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002133 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002134 self, (char *) buf.buf + written, buf.len - written);
2135 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002136 goto error;
2137 } else if (n == -2) {
2138 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139 if (remaining > self->buffer_size) {
2140 /* Can't buffer everything, still buffer as much as possible */
2141 memcpy(self->buffer,
2142 (char *) buf.buf + written, self->buffer_size);
2143 self->raw_pos = 0;
2144 ADJUST_POSITION(self, self->buffer_size);
2145 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002146 written += self->buffer_size;
2147 _set_BlockingIOError("write could not complete without "
2148 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149 goto error;
2150 }
2151 PyErr_Clear();
2152 break;
2153 }
2154 written += n;
2155 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002156 /* Partial writes can return successfully when interrupted by a
2157 signal (see write(2)). We must run signal handlers before
2158 blocking another time, possibly indefinitely. */
2159 if (PyErr_CheckSignals() < 0)
2160 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161 }
2162 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002163 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002164 if (remaining > 0) {
2165 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2166 written += remaining;
2167 }
2168 self->write_pos = 0;
2169 /* TODO: sanity check (remaining >= 0) */
2170 self->write_end = remaining;
2171 ADJUST_POSITION(self, remaining);
2172 self->raw_pos = 0;
2173
2174end:
2175 res = PyLong_FromSsize_t(written);
2176
2177error:
2178 LEAVE_BUFFERED(self)
2179 PyBuffer_Release(&buf);
2180 return res;
2181}
2182
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002183static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002185 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2186 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2187 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2188 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2189 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2190 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2191 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002192 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002193 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002195 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2196 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2197 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2198 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2199 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002200 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201 {NULL, NULL}
2202};
2203
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002204static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002205 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002206 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207 {NULL}
2208};
2209
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210static PyGetSetDef bufferedwriter_getset[] = {
2211 {"closed", (getter)buffered_closed_get, NULL, NULL},
2212 {"name", (getter)buffered_name_get, NULL, NULL},
2213 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002214 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215};
2216
2217
2218PyTypeObject PyBufferedWriter_Type = {
2219 PyVarObject_HEAD_INIT(NULL, 0)
2220 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002221 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 0, /*tp_print*/
2225 0, /*tp_getattr*/
2226 0, /*tp_setattr*/
2227 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002228 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 0, /*tp_as_number*/
2230 0, /*tp_as_sequence*/
2231 0, /*tp_as_mapping*/
2232 0, /*tp_hash */
2233 0, /*tp_call*/
2234 0, /*tp_str*/
2235 0, /*tp_getattro*/
2236 0, /*tp_setattro*/
2237 0, /*tp_as_buffer*/
2238 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002239 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002240 bufferedwriter_doc, /* tp_doc */
2241 (traverseproc)buffered_traverse, /* tp_traverse */
2242 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002243 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002244 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245 0, /* tp_iter */
2246 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002247 bufferedwriter_methods, /* tp_methods */
2248 bufferedwriter_members, /* tp_members */
2249 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250 0, /* tp_base */
2251 0, /* tp_dict */
2252 0, /* tp_descr_get */
2253 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002254 offsetof(buffered, dict), /* tp_dictoffset */
2255 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002256 0, /* tp_alloc */
2257 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002258 0, /* tp_free */
2259 0, /* tp_is_gc */
2260 0, /* tp_bases */
2261 0, /* tp_mro */
2262 0, /* tp_cache */
2263 0, /* tp_subclasses */
2264 0, /* tp_weaklist */
2265 0, /* tp_del */
2266 0, /* tp_version_tag */
2267 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002268};
2269
2270
2271
2272/*
2273 * BufferedRWPair
2274 */
2275
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002276PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277 "A buffered reader and writer object together.\n"
2278 "\n"
2279 "A buffered reader object and buffered writer object put together to\n"
2280 "form a sequential IO object that can read and write. This is typically\n"
2281 "used with a socket or two-way pipe.\n"
2282 "\n"
2283 "reader and writer are RawIOBase objects that are readable and\n"
2284 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002285 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286 );
2287
2288/* XXX The usefulness of this (compared to having two separate IO objects) is
2289 * questionable.
2290 */
2291
2292typedef struct {
2293 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002294 buffered *reader;
2295 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296 PyObject *dict;
2297 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002298} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299
2300static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002301bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002302{
2303 PyObject *reader, *writer;
2304 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305
Florent Xicluna109d5732012-07-07 17:03:22 +02002306 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2307 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002308 return -1;
2309 }
2310
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002311 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002313 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002314 return -1;
2315
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002316 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002317 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002318 if (self->reader == NULL)
2319 return -1;
2320
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002321 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002322 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323 if (self->writer == NULL) {
2324 Py_CLEAR(self->reader);
2325 return -1;
2326 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002327
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328 return 0;
2329}
2330
2331static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002332bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002333{
2334 Py_VISIT(self->dict);
2335 return 0;
2336}
2337
2338static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002339bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002340{
2341 Py_CLEAR(self->reader);
2342 Py_CLEAR(self->writer);
2343 Py_CLEAR(self->dict);
2344 return 0;
2345}
2346
2347static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002348bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002349{
2350 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002351 if (self->weakreflist != NULL)
2352 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002353 Py_CLEAR(self->reader);
2354 Py_CLEAR(self->writer);
2355 Py_CLEAR(self->dict);
2356 Py_TYPE(self)->tp_free((PyObject *) self);
2357}
2358
2359static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002360_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002362 PyObject *func, *ret;
2363 if (self == NULL) {
2364 PyErr_SetString(PyExc_ValueError,
2365 "I/O operation on uninitialized object");
2366 return NULL;
2367 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002368
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002369 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002370 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002371 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002372 return NULL;
2373 }
2374
2375 ret = PyObject_CallObject(func, args);
2376 Py_DECREF(func);
2377 return ret;
2378}
2379
2380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002381bufferedrwpair_read(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->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002384}
2385
2386static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002387bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002388{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002389 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002390}
2391
2392static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002393bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002395 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002396}
2397
2398static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002399bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002400{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002401 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002402}
2403
2404static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002405bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2406{
2407 return _forward_call(self->reader, &PyId_readinto1, args);
2408}
2409
2410static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002411bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002412{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002413 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002414}
2415
2416static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002417bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002419 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420}
2421
2422static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002423bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002424{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002425 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426}
2427
2428static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002431 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432}
2433
2434static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002435bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002437 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002438 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002439 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002440 PyErr_Fetch(&exc, &val, &tb);
2441 else
2442 Py_DECREF(ret);
2443 ret = _forward_call(self->reader, &PyId_close, args);
2444 if (exc != NULL) {
2445 _PyErr_ChainExceptions(exc, val, tb);
2446 Py_CLEAR(ret);
2447 }
2448 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002449}
2450
2451static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002452bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002454 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002455
2456 if (ret != Py_False) {
2457 /* either True or exception */
2458 return ret;
2459 }
2460 Py_DECREF(ret);
2461
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002462 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002463}
2464
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002465static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002466bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002467{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002468 if (self->writer == NULL) {
2469 PyErr_SetString(PyExc_RuntimeError,
2470 "the BufferedRWPair object is being garbage-collected");
2471 return NULL;
2472 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002473 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2474}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002475
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002476static PyMethodDef bufferedrwpair_methods[] = {
2477 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2478 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2479 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2480 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002481 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002482
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002483 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2484 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002486 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2487 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002488
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002489 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2490 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002491
Antoine Pitrou243757e2010-11-05 21:15:39 +00002492 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2493
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002494 {NULL, NULL}
2495};
2496
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002497static PyGetSetDef bufferedrwpair_getset[] = {
2498 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002499 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002500};
2501
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002502PyTypeObject PyBufferedRWPair_Type = {
2503 PyVarObject_HEAD_INIT(NULL, 0)
2504 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002505 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002506 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002507 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002508 0, /*tp_print*/
2509 0, /*tp_getattr*/
2510 0, /*tp_setattr*/
2511 0, /*tp_compare */
2512 0, /*tp_repr*/
2513 0, /*tp_as_number*/
2514 0, /*tp_as_sequence*/
2515 0, /*tp_as_mapping*/
2516 0, /*tp_hash */
2517 0, /*tp_call*/
2518 0, /*tp_str*/
2519 0, /*tp_getattro*/
2520 0, /*tp_setattro*/
2521 0, /*tp_as_buffer*/
2522 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002523 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002524 bufferedrwpair_doc, /* tp_doc */
2525 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2526 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002527 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002528 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002529 0, /* tp_iter */
2530 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002531 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002533 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002534 0, /* tp_base */
2535 0, /* tp_dict */
2536 0, /* tp_descr_get */
2537 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002538 offsetof(rwpair, dict), /* tp_dictoffset */
2539 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002540 0, /* tp_alloc */
2541 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002542 0, /* tp_free */
2543 0, /* tp_is_gc */
2544 0, /* tp_bases */
2545 0, /* tp_mro */
2546 0, /* tp_cache */
2547 0, /* tp_subclasses */
2548 0, /* tp_weaklist */
2549 0, /* tp_del */
2550 0, /* tp_version_tag */
2551 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002552};
2553
2554
2555
2556/*
2557 * BufferedRandom
2558 */
2559
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002560PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002561 "A buffered interface to random access streams.\n"
2562 "\n"
2563 "The constructor creates a reader and writer for a seekable stream,\n"
2564 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002565 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566 );
2567
2568static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002569bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002570{
Florent Xicluna109d5732012-07-07 17:03:22 +02002571 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002573 PyObject *raw;
2574
2575 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002576 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002577
R David Murray9f10f562013-02-23 22:07:55 -05002578 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002579 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002580 return -1;
2581 }
2582
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002583 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002584 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002585 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002587 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002588 return -1;
2589
2590 Py_CLEAR(self->raw);
2591 Py_INCREF(raw);
2592 self->raw = raw;
2593 self->buffer_size = buffer_size;
2594 self->readable = 1;
2595 self->writable = 1;
2596
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002597 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002598 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002599 _bufferedreader_reset_buf(self);
2600 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002601 self->pos = 0;
2602
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002603 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2604 Py_TYPE(raw) == &PyFileIO_Type);
2605
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002606 self->ok = 1;
2607 return 0;
2608}
2609
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002610static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002611 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002612 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2613 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2614 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2615 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2616 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2617 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2618 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002619 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002620 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002621
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002624 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2625 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2626 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2627 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2628 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2629 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002630 {"readinto1", (PyCFunction)buffered_readinto1, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002631 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2632 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2633 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002634 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635 {NULL, NULL}
2636};
2637
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002638static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002639 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002640 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002641 {NULL}
2642};
2643
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002644static PyGetSetDef bufferedrandom_getset[] = {
2645 {"closed", (getter)buffered_closed_get, NULL, NULL},
2646 {"name", (getter)buffered_name_get, NULL, NULL},
2647 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002648 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002649};
2650
2651
2652PyTypeObject PyBufferedRandom_Type = {
2653 PyVarObject_HEAD_INIT(NULL, 0)
2654 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002655 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002656 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002657 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002658 0, /*tp_print*/
2659 0, /*tp_getattr*/
2660 0, /*tp_setattr*/
2661 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002662 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663 0, /*tp_as_number*/
2664 0, /*tp_as_sequence*/
2665 0, /*tp_as_mapping*/
2666 0, /*tp_hash */
2667 0, /*tp_call*/
2668 0, /*tp_str*/
2669 0, /*tp_getattro*/
2670 0, /*tp_setattro*/
2671 0, /*tp_as_buffer*/
2672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002673 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002674 bufferedrandom_doc, /* tp_doc */
2675 (traverseproc)buffered_traverse, /* tp_traverse */
2676 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002677 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002678 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002679 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002680 (iternextfunc)buffered_iternext, /* tp_iternext */
2681 bufferedrandom_methods, /* tp_methods */
2682 bufferedrandom_members, /* tp_members */
2683 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002684 0, /* tp_base */
2685 0, /*tp_dict*/
2686 0, /* tp_descr_get */
2687 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002688 offsetof(buffered, dict), /*tp_dictoffset*/
2689 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690 0, /* tp_alloc */
2691 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002692 0, /* tp_free */
2693 0, /* tp_is_gc */
2694 0, /* tp_bases */
2695 0, /* tp_mro */
2696 0, /* tp_cache */
2697 0, /* tp_subclasses */
2698 0, /* tp_weaklist */
2699 0, /* tp_del */
2700 0, /* tp_version_tag */
2701 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002702};