blob: 2feda5a350ac0fa0deeb124659b653b239e5ac41 [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{
321 if (self->owner == PyThread_get_thread_ident()) {
322 PyErr_Format(PyExc_RuntimeError,
323 "reentrant call inside %R", self);
324 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000325 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000326 Py_BEGIN_ALLOW_THREADS
327 PyThread_acquire_lock(self->lock, 1);
328 Py_END_ALLOW_THREADS
329 return 1;
330}
331
332#define ENTER_BUFFERED(self) \
333 ( (PyThread_acquire_lock(self->lock, 0) ? \
334 1 : _enter_buffered_busy(self)) \
335 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336
337#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000338 do { \
339 self->owner = 0; \
340 PyThread_release_lock(self->lock); \
341 } while(0);
342
Georg Brandldfd73442009-04-05 11:47:34 +0000343#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000344#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000345#define LEAVE_BUFFERED(self)
346#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000347
348#define CHECK_INITIALIZED(self) \
349 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000350 if (self->detached) { \
351 PyErr_SetString(PyExc_ValueError, \
352 "raw stream has been detached"); \
353 } else { \
354 PyErr_SetString(PyExc_ValueError, \
355 "I/O operation on uninitialized object"); \
356 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000357 return NULL; \
358 }
359
360#define CHECK_INITIALIZED_INT(self) \
361 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000362 if (self->detached) { \
363 PyErr_SetString(PyExc_ValueError, \
364 "raw stream has been detached"); \
365 } else { \
366 PyErr_SetString(PyExc_ValueError, \
367 "I/O operation on uninitialized object"); \
368 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000369 return -1; \
370 }
371
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000372#define IS_CLOSED(self) \
373 (self->fast_closed_checks \
374 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000375 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000376
377#define CHECK_CLOSED(self, error_msg) \
378 if (IS_CLOSED(self)) { \
379 PyErr_SetString(PyExc_ValueError, error_msg); \
380 return NULL; \
381 }
382
383
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000384#define VALID_READ_BUFFER(self) \
385 (self->readable && self->read_end != -1)
386
387#define VALID_WRITE_BUFFER(self) \
388 (self->writable && self->write_end != -1)
389
390#define ADJUST_POSITION(self, _new_pos) \
391 do { \
392 self->pos = _new_pos; \
393 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
394 self->read_end = self->pos; \
395 } while(0)
396
397#define READAHEAD(self) \
398 ((self->readable && VALID_READ_BUFFER(self)) \
399 ? (self->read_end - self->pos) : 0)
400
401#define RAW_OFFSET(self) \
402 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
403 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
404
405#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000406 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000407
408#define MINUS_LAST_BLOCK(self, size) \
409 (self->buffer_mask ? \
410 (size & ~self->buffer_mask) : \
411 (self->buffer_size * (size / self->buffer_size)))
412
413
414static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000415buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200417 self->finalizing = 1;
418 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000419 return;
420 _PyObject_GC_UNTRACK(self);
421 self->ok = 0;
422 if (self->weakreflist != NULL)
423 PyObject_ClearWeakRefs((PyObject *)self);
424 Py_CLEAR(self->raw);
425 if (self->buffer) {
426 PyMem_Free(self->buffer);
427 self->buffer = NULL;
428 }
Georg Brandldfd73442009-04-05 11:47:34 +0000429#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000430 if (self->lock) {
431 PyThread_free_lock(self->lock);
432 self->lock = NULL;
433 }
Georg Brandldfd73442009-04-05 11:47:34 +0000434#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435 Py_CLEAR(self->dict);
436 Py_TYPE(self)->tp_free((PyObject *)self);
437}
438
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200439static PyObject *
440buffered_sizeof(buffered *self, void *unused)
441{
442 Py_ssize_t res;
443
444 res = sizeof(buffered);
445 if (self->buffer)
446 res += self->buffer_size;
447 return PyLong_FromSsize_t(res);
448}
449
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000450static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000451buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000452{
453 Py_VISIT(self->raw);
454 Py_VISIT(self->dict);
455 return 0;
456}
457
458static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000459buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000460{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461 self->ok = 0;
462 Py_CLEAR(self->raw);
463 Py_CLEAR(self->dict);
464 return 0;
465}
466
Antoine Pitroue033e062010-10-29 10:38:18 +0000467/* Because this can call arbitrary code, it shouldn't be called when
468 the refcount is 0 (that is, not directly from tp_dealloc unless
469 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000470static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000471buffered_dealloc_warn(buffered *self, PyObject *source)
472{
473 if (self->ok && self->raw) {
474 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200475 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000476 if (r)
477 Py_DECREF(r);
478 else
479 PyErr_Clear();
480 }
481 Py_RETURN_NONE;
482}
483
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000484/*
485 * _BufferedIOMixin methods
486 * This is not a class, just a collection of methods that will be reused
487 * by BufferedReader and BufferedWriter
488 */
489
490/* Flush and close */
491
492static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000493buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000494{
495 CHECK_INITIALIZED(self)
496 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
497}
498
499static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000500buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000501{
502 int closed;
503 PyObject *res;
504 CHECK_INITIALIZED_INT(self)
505 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
506 if (res == NULL)
507 return -1;
508 closed = PyObject_IsTrue(res);
509 Py_DECREF(res);
510 return closed;
511}
512
513static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000514buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515{
516 CHECK_INITIALIZED(self)
517 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
518}
519
520static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000521buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522{
Benjamin Peterson68623612012-12-20 11:53:11 -0600523 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000524 int r;
525
526 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000527 if (!ENTER_BUFFERED(self))
528 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000529
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000530 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000531 if (r < 0)
532 goto end;
533 if (r > 0) {
534 res = Py_None;
535 Py_INCREF(res);
536 goto end;
537 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000538
Antoine Pitrou796564c2013-07-30 19:59:21 +0200539 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000540 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
541 if (r)
542 Py_DECREF(r);
543 else
544 PyErr_Clear();
545 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000546 /* flush() will most probably re-take the lock, so drop it first */
547 LEAVE_BUFFERED(self)
548 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000549 if (!ENTER_BUFFERED(self))
550 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600551 if (res == NULL)
552 PyErr_Fetch(&exc, &val, &tb);
553 else
554 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000555
556 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
557
Jesus Ceadc469452012-10-04 12:37:56 +0200558 if (self->buffer) {
559 PyMem_Free(self->buffer);
560 self->buffer = NULL;
561 }
562
Benjamin Peterson68623612012-12-20 11:53:11 -0600563 if (exc != NULL) {
564 if (res != NULL) {
565 Py_CLEAR(res);
566 PyErr_Restore(exc, val, tb);
567 }
568 else {
Serhiy Storchaka76d3f142014-06-11 07:18:53 +0300569 PyObject *exc2, *val2, *tb2;
570 PyErr_Fetch(&exc2, &val2, &tb2);
Serhiy Storchaka8a8f7f92014-06-09 09:13:04 +0300571 PyErr_NormalizeException(&exc, &val, &tb);
Benjamin Peterson68623612012-12-20 11:53:11 -0600572 Py_DECREF(exc);
573 Py_XDECREF(tb);
Serhiy Storchaka76d3f142014-06-11 07:18:53 +0300574 PyErr_NormalizeException(&exc2, &val2, &tb2);
Benjamin Peterson68623612012-12-20 11:53:11 -0600575 PyException_SetContext(val2, val);
Serhiy Storchaka76d3f142014-06-11 07:18:53 +0300576 PyErr_Restore(exc2, val2, tb2);
Benjamin Peterson68623612012-12-20 11:53:11 -0600577 }
578 }
579
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580end:
581 LEAVE_BUFFERED(self)
582 return res;
583}
584
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000585/* detach */
586
587static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000589{
590 PyObject *raw, *res;
591 CHECK_INITIALIZED(self)
592 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
593 if (res == NULL)
594 return NULL;
595 Py_DECREF(res);
596 raw = self->raw;
597 self->raw = NULL;
598 self->detached = 1;
599 self->ok = 0;
600 return raw;
601}
602
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000603/* Inquiries */
604
605static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000606buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607{
608 CHECK_INITIALIZED(self)
609 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
610}
611
612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614{
615 CHECK_INITIALIZED(self)
616 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
617}
618
619static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000621{
622 CHECK_INITIALIZED(self)
623 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
624}
625
626static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000628{
629 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200630 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000631}
632
633static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000634buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635{
636 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200637 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000638}
639
640/* Lower-level APIs */
641
642static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644{
645 CHECK_INITIALIZED(self)
646 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
647}
648
649static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000650buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651{
652 CHECK_INITIALIZED(self)
653 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
654}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000655
Antoine Pitrou243757e2010-11-05 21:15:39 +0000656/* Serialization */
657
658static PyObject *
659buffered_getstate(buffered *self, PyObject *args)
660{
661 PyErr_Format(PyExc_TypeError,
662 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
663 return NULL;
664}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000665
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000666/* Forward decls */
667static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100668_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000670_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000672_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000674_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200676_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000678_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000679static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000680_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000681static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000682_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200683static Py_ssize_t
684_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000685
686/*
687 * Helpers
688 */
689
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100690/* Sets the current error to BlockingIOError */
691static void
692_set_BlockingIOError(char *msg, Py_ssize_t written)
693{
694 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200695#ifdef Py_DEBUG
696 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
697 if an exception is set when it is called */
698 PyErr_Clear();
699#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100700 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
701 errno, msg, written);
702 if (err)
703 PyErr_SetObject(PyExc_BlockingIOError, err);
704 Py_XDECREF(err);
705}
706
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707/* Returns the address of the `written` member if a BlockingIOError was
708 raised, NULL otherwise. The error is always re-raised. */
709static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000710_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711{
712 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200713 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000714
715 PyErr_Fetch(&t, &v, &tb);
716 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
717 PyErr_Restore(t, v, tb);
718 return NULL;
719 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200720 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000721 /* TODO: sanity check (err->written >= 0) */
722 PyErr_Restore(t, v, tb);
723 return &err->written;
724}
725
726static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000727_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000728{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000729 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000730 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
732 if (res == NULL)
733 return -1;
734 n = PyNumber_AsOff_t(res, PyExc_ValueError);
735 Py_DECREF(res);
736 if (n < 0) {
737 if (!PyErr_Occurred())
738 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000739 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200740 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 return -1;
742 }
743 self->abs_pos = n;
744 return n;
745}
746
747static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000748_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000749{
750 PyObject *res, *posobj, *whenceobj;
751 Py_off_t n;
752
753 posobj = PyLong_FromOff_t(target);
754 if (posobj == NULL)
755 return -1;
756 whenceobj = PyLong_FromLong(whence);
757 if (whenceobj == NULL) {
758 Py_DECREF(posobj);
759 return -1;
760 }
761 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
762 posobj, whenceobj, NULL);
763 Py_DECREF(posobj);
764 Py_DECREF(whenceobj);
765 if (res == NULL)
766 return -1;
767 n = PyNumber_AsOff_t(res, PyExc_ValueError);
768 Py_DECREF(res);
769 if (n < 0) {
770 if (!PyErr_Occurred())
771 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000772 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200773 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000774 return -1;
775 }
776 self->abs_pos = n;
777 return n;
778}
779
780static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000781_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000782{
783 Py_ssize_t n;
784 if (self->buffer_size <= 0) {
785 PyErr_SetString(PyExc_ValueError,
786 "buffer size must be strictly positive");
787 return -1;
788 }
789 if (self->buffer)
790 PyMem_Free(self->buffer);
791 self->buffer = PyMem_Malloc(self->buffer_size);
792 if (self->buffer == NULL) {
793 PyErr_NoMemory();
794 return -1;
795 }
Georg Brandldfd73442009-04-05 11:47:34 +0000796#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000797 if (self->lock)
798 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000799 self->lock = PyThread_allocate_lock();
800 if (self->lock == NULL) {
801 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
802 return -1;
803 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000804 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000805#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000806 /* Find out whether buffer_size is a power of 2 */
807 /* XXX is this optimization useful? */
808 for (n = self->buffer_size - 1; n & 1; n >>= 1)
809 ;
810 if (n == 0)
811 self->buffer_mask = self->buffer_size - 1;
812 else
813 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000814 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000815 PyErr_Clear();
816 return 0;
817}
818
Antoine Pitrou707ce822011-02-25 21:24:11 +0000819/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
820 clears the error indicator), 0 otherwise.
821 Should only be called when PyErr_Occurred() is true.
822*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700823int
824_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000825{
826 static PyObject *eintr_int = NULL;
827 PyObject *typ, *val, *tb;
828 PyEnvironmentErrorObject *env_err;
829
830 if (eintr_int == NULL) {
831 eintr_int = PyLong_FromLong(EINTR);
832 assert(eintr_int != NULL);
833 }
834 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
835 return 0;
836 PyErr_Fetch(&typ, &val, &tb);
837 PyErr_NormalizeException(&typ, &val, &tb);
838 env_err = (PyEnvironmentErrorObject *) val;
839 assert(env_err != NULL);
840 if (env_err->myerrno != NULL &&
841 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
842 Py_DECREF(typ);
843 Py_DECREF(val);
844 Py_XDECREF(tb);
845 return 1;
846 }
847 /* This silences any error set by PyObject_RichCompareBool() */
848 PyErr_Restore(typ, val, tb);
849 return 0;
850}
851
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852/*
853 * Shared methods and wrappers
854 */
855
856static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200857buffered_flush_and_rewind_unlocked(buffered *self)
858{
859 PyObject *res;
860
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100861 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200862 if (res == NULL)
863 return NULL;
864 Py_DECREF(res);
865
866 if (self->readable) {
867 /* Rewind the raw stream so that its position corresponds to
868 the current logical position. */
869 Py_off_t n;
870 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
871 _bufferedreader_reset_buf(self);
872 if (n == -1)
873 return NULL;
874 }
875 Py_RETURN_NONE;
876}
877
878static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000879buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880{
881 PyObject *res;
882
883 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000884 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000886 if (!ENTER_BUFFERED(self))
887 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200888 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889 LEAVE_BUFFERED(self)
890
891 return res;
892}
893
894static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000895buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896{
897 Py_ssize_t n = 0;
898 PyObject *res = NULL;
899
900 CHECK_INITIALIZED(self)
901 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
902 return NULL;
903 }
904
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000905 if (!ENTER_BUFFERED(self))
906 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000907
908 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200909 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000910 if (res == NULL)
911 goto end;
912 Py_CLEAR(res);
913 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200914 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915
916end:
917 LEAVE_BUFFERED(self)
918 return res;
919}
920
921static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000922buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923{
924 Py_ssize_t n = -1;
925 PyObject *res;
926
927 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000928 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929 return NULL;
930 }
931 if (n < -1) {
932 PyErr_SetString(PyExc_ValueError,
933 "read length must be positive or -1");
934 return NULL;
935 }
936
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000937 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000939 if (n == -1) {
940 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000941 if (!ENTER_BUFFERED(self))
942 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000943 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000944 }
945 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000946 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200947 if (res != Py_None)
948 return res;
949 Py_DECREF(res);
950 if (!ENTER_BUFFERED(self))
951 return NULL;
952 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000953 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954
Antoine Pitroue05565e2011-08-20 14:39:23 +0200955 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000956 return res;
957}
958
959static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000960buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961{
962 Py_ssize_t n, have, r;
963 PyObject *res = NULL;
964
965 CHECK_INITIALIZED(self)
966 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
967 return NULL;
968 }
969
970 if (n < 0) {
971 PyErr_SetString(PyExc_ValueError,
972 "read length must be positive");
973 return NULL;
974 }
975 if (n == 0)
976 return PyBytes_FromStringAndSize(NULL, 0);
977
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000978 /* Return up to n bytes. If at least one byte is buffered, we
979 only return buffered bytes. Otherwise, we do one raw read. */
980
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
982 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100983 n = Py_MIN(have, n);
984 res = _bufferedreader_read_fast(self, n);
985 assert(res != Py_None);
986 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100988 res = PyBytes_FromStringAndSize(NULL, n);
989 if (res == NULL)
990 return NULL;
991 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200992 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100993 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200994 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000995 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100996 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
997 LEAVE_BUFFERED(self)
998 if (r == -1) {
999 Py_DECREF(res);
1000 return NULL;
1001 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001002 if (r == -2)
1003 r = 0;
1004 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +01001005 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001006 return res;
1007}
1008
1009static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07001010_buffered_readinto_generic(buffered *self, PyObject *args, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001011{
Antoine Pitrou3486a982011-05-12 01:57:53 +02001012 Py_buffer buf;
1013 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014 PyObject *res = NULL;
1015
1016 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +02001017
Benjamin Petersona96fea02014-06-22 14:17:44 -07001018 if (!PyArg_ParseTuple(args,
1019 readinto1 ? "w*:readinto1" : "w*:readinto",
1020 &buf))
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 return NULL;
1022
1023 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1024 if (n > 0) {
1025 if (n >= buf.len) {
1026 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1027 self->pos += buf.len;
1028 res = PyLong_FromSsize_t(buf.len);
1029 goto end_unlocked;
1030 }
1031 memcpy(buf.buf, self->buffer + self->pos, n);
1032 self->pos += n;
1033 written = n;
1034 }
1035
1036 if (!ENTER_BUFFERED(self))
1037 goto end_unlocked;
1038
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001039 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001040 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 if (res == NULL)
1042 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001043 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001045
1046 _bufferedreader_reset_buf(self);
1047 self->pos = 0;
1048
1049 for (remaining = buf.len - written;
1050 remaining > 0;
1051 written += n, remaining -= n) {
1052 /* If remaining bytes is larger than internal buffer size, copy
1053 * directly into caller's buffer. */
1054 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001055 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1056 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001057 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001058
1059 /* In readinto1 mode, we do not want to fill the internal
1060 buffer if we already have some data to return */
1061 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001062 n = _bufferedreader_fill_buffer(self);
1063 if (n > 0) {
1064 if (n > remaining)
1065 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001066 memcpy((char *) buf.buf + written,
1067 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001068 self->pos += n;
1069 continue; /* short circuit */
1070 }
1071 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001072 else
1073 n = 0;
1074
Antoine Pitrou3486a982011-05-12 01:57:53 +02001075 if (n == 0 || (n == -2 && written > 0))
1076 break;
1077 if (n < 0) {
1078 if (n == -2) {
1079 Py_INCREF(Py_None);
1080 res = Py_None;
1081 }
1082 goto end;
1083 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001084
1085 /* At most one read in readinto1 mode */
1086 if (readinto1) {
1087 written += n;
1088 break;
1089 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001090 }
1091 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001092
1093end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001094 LEAVE_BUFFERED(self);
1095end_unlocked:
1096 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001097 return res;
1098}
1099
1100static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07001101buffered_readinto(buffered *self, PyObject *args)
1102{
1103 return _buffered_readinto_generic(self, args, 0);
1104}
1105
1106static PyObject *
1107buffered_readinto1(buffered *self, PyObject *args)
1108{
1109 return _buffered_readinto_generic(self, args, 1);
1110}
1111
1112
1113static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001114_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001115{
1116 PyObject *res = NULL;
1117 PyObject *chunks = NULL;
1118 Py_ssize_t n, written = 0;
1119 const char *start, *s, *end;
1120
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001121 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001122
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001123 /* First, try to find a line in the buffer. This can run unlocked because
1124 the calls to the C API are simple enough that they can't trigger
1125 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1127 if (limit >= 0 && n > limit)
1128 n = limit;
1129 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001130 s = memchr(start, '\n', n);
1131 if (s != NULL) {
1132 res = PyBytes_FromStringAndSize(start, s - start + 1);
1133 if (res != NULL)
1134 self->pos += s - start + 1;
1135 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001136 }
1137 if (n == limit) {
1138 res = PyBytes_FromStringAndSize(start, n);
1139 if (res != NULL)
1140 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001141 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001142 }
1143
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001144 if (!ENTER_BUFFERED(self))
1145 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001146
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001148 chunks = PyList_New(0);
1149 if (chunks == NULL)
1150 goto end;
1151 if (n > 0) {
1152 res = PyBytes_FromStringAndSize(start, n);
1153 if (res == NULL)
1154 goto end;
1155 if (PyList_Append(chunks, res) < 0) {
1156 Py_CLEAR(res);
1157 goto end;
1158 }
1159 Py_CLEAR(res);
1160 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001161 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001162 if (limit >= 0)
1163 limit -= n;
1164 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001165 if (self->writable) {
1166 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1167 if (r == NULL)
1168 goto end;
1169 Py_DECREF(r);
1170 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001171
1172 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001173 _bufferedreader_reset_buf(self);
1174 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001175 if (n == -1)
1176 goto end;
1177 if (n <= 0)
1178 break;
1179 if (limit >= 0 && n > limit)
1180 n = limit;
1181 start = self->buffer;
1182 end = start + n;
1183 s = start;
1184 while (s < end) {
1185 if (*s++ == '\n') {
1186 res = PyBytes_FromStringAndSize(start, s - start);
1187 if (res == NULL)
1188 goto end;
1189 self->pos = s - start;
1190 goto found;
1191 }
1192 }
1193 res = PyBytes_FromStringAndSize(start, n);
1194 if (res == NULL)
1195 goto end;
1196 if (n == limit) {
1197 self->pos = n;
1198 break;
1199 }
1200 if (PyList_Append(chunks, res) < 0) {
1201 Py_CLEAR(res);
1202 goto end;
1203 }
1204 Py_CLEAR(res);
1205 written += n;
1206 if (limit >= 0)
1207 limit -= n;
1208 }
1209found:
1210 if (res != NULL && PyList_Append(chunks, res) < 0) {
1211 Py_CLEAR(res);
1212 goto end;
1213 }
1214 Py_CLEAR(res);
1215 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1216
1217end:
1218 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001219end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220 Py_XDECREF(chunks);
1221 return res;
1222}
1223
1224static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001225buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226{
1227 Py_ssize_t limit = -1;
1228
1229 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001230 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001232 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001233}
1234
1235
1236static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001237buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238{
1239 Py_off_t pos;
1240
1241 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001242 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 if (pos == -1)
1244 return NULL;
1245 pos -= RAW_OFFSET(self);
1246 /* TODO: sanity check (pos >= 0) */
1247 return PyLong_FromOff_t(pos);
1248}
1249
1250static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001251buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001252{
1253 Py_off_t target, n;
1254 int whence = 0;
1255 PyObject *targetobj, *res = NULL;
1256
1257 CHECK_INITIALIZED(self)
1258 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1259 return NULL;
1260 }
Jesus Cea94363612012-06-22 18:32:07 +02001261
1262 /* Do some error checking instead of trusting OS 'seek()'
1263 ** error detection, just in case.
1264 */
1265 if ((whence < 0 || whence >2)
1266#ifdef SEEK_HOLE
1267 && (whence != SEEK_HOLE)
1268#endif
1269#ifdef SEEK_DATA
1270 && (whence != SEEK_DATA)
1271#endif
1272 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001274 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275 return NULL;
1276 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001277
1278 CHECK_CLOSED(self, "seek of closed file")
1279
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001280 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1281 return NULL;
1282
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1284 if (target == -1 && PyErr_Occurred())
1285 return NULL;
1286
Jesus Cea94363612012-06-22 18:32:07 +02001287 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1288 buffer. Other whence values must be managed without this optimization.
1289 Some Operating Systems can provide additional values, like
1290 SEEK_HOLE/SEEK_DATA. */
1291 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 Py_off_t current, avail;
1293 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001294 so as to return quickly if possible. Also, we needn't take the
1295 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001297 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1298 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001299 current = RAW_TELL(self);
1300 avail = READAHEAD(self);
1301 if (avail > 0) {
1302 Py_off_t offset;
1303 if (whence == 0)
1304 offset = target - (current - RAW_OFFSET(self));
1305 else
1306 offset = target;
1307 if (offset >= -self->pos && offset <= avail) {
1308 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001309 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 }
1311 }
1312 }
1313
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001314 if (!ENTER_BUFFERED(self))
1315 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001316
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001317 /* Fallback: invoke raw seek() method and clear buffer */
1318 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001319 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320 if (res == NULL)
1321 goto end;
1322 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001323 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001324 }
1325
1326 /* TODO: align on block boundary and read buffer if needed? */
1327 if (whence == 1)
1328 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001329 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330 if (n == -1)
1331 goto end;
1332 self->raw_pos = -1;
1333 res = PyLong_FromOff_t(n);
1334 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001335 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336
1337end:
1338 LEAVE_BUFFERED(self)
1339 return res;
1340}
1341
1342static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001343buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001344{
1345 PyObject *pos = Py_None;
1346 PyObject *res = NULL;
1347
1348 CHECK_INITIALIZED(self)
1349 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1350 return NULL;
1351 }
1352
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001353 if (!ENTER_BUFFERED(self))
1354 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355
1356 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001357 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001358 if (res == NULL)
1359 goto end;
1360 Py_CLEAR(res);
1361 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1363 if (res == NULL)
1364 goto end;
1365 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001366 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367 PyErr_Clear();
1368
1369end:
1370 LEAVE_BUFFERED(self)
1371 return res;
1372}
1373
1374static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001375buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001376{
1377 PyObject *line;
1378 PyTypeObject *tp;
1379
1380 CHECK_INITIALIZED(self);
1381
1382 tp = Py_TYPE(self);
1383 if (tp == &PyBufferedReader_Type ||
1384 tp == &PyBufferedRandom_Type) {
1385 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001386 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001387 }
1388 else {
1389 line = PyObject_CallMethodObjArgs((PyObject *)self,
1390 _PyIO_str_readline, NULL);
1391 if (line && !PyBytes_Check(line)) {
1392 PyErr_Format(PyExc_IOError,
1393 "readline() should have returned a bytes object, "
1394 "not '%.200s'", Py_TYPE(line)->tp_name);
1395 Py_DECREF(line);
1396 return NULL;
1397 }
1398 }
1399
1400 if (line == NULL)
1401 return NULL;
1402
1403 if (PyBytes_GET_SIZE(line) == 0) {
1404 /* Reached EOF or would have blocked */
1405 Py_DECREF(line);
1406 return NULL;
1407 }
1408
1409 return line;
1410}
1411
Antoine Pitrou716c4442009-05-23 19:04:03 +00001412static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001413buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001414{
1415 PyObject *nameobj, *res;
1416
Martin v. Löwis767046a2011-10-14 15:35:36 +02001417 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001418 if (nameobj == NULL) {
1419 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1420 PyErr_Clear();
1421 else
1422 return NULL;
1423 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1424 }
1425 else {
1426 res = PyUnicode_FromFormat("<%s name=%R>",
1427 Py_TYPE(self)->tp_name, nameobj);
1428 Py_DECREF(nameobj);
1429 }
1430 return res;
1431}
1432
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001433/*
1434 * class BufferedReader
1435 */
1436
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001437PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438 "Create a new buffered reader using the given readable raw IO object.");
1439
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001440static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441{
1442 self->read_end = -1;
1443}
1444
1445static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001446bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001447{
1448 char *kwlist[] = {"raw", "buffer_size", NULL};
1449 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1450 PyObject *raw;
1451
1452 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001453 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454
1455 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1456 &raw, &buffer_size)) {
1457 return -1;
1458 }
1459
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001460 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001461 return -1;
1462
1463 Py_CLEAR(self->raw);
1464 Py_INCREF(raw);
1465 self->raw = raw;
1466 self->buffer_size = buffer_size;
1467 self->readable = 1;
1468 self->writable = 0;
1469
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001470 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001472 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001473
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001474 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1475 Py_TYPE(raw) == &PyFileIO_Type);
1476
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001477 self->ok = 1;
1478 return 0;
1479}
1480
1481static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001482_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001483{
1484 Py_buffer buf;
1485 PyObject *memobj, *res;
1486 Py_ssize_t n;
1487 /* NOTE: the buffer needn't be released as its object is NULL. */
1488 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1489 return -1;
1490 memobj = PyMemoryView_FromBuffer(&buf);
1491 if (memobj == NULL)
1492 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001493 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1494 occurs so we needn't do it ourselves.
1495 We then retry reading, ignoring the signal if no handler has
1496 raised (see issue #10956).
1497 */
1498 do {
1499 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001500 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001501 Py_DECREF(memobj);
1502 if (res == NULL)
1503 return -1;
1504 if (res == Py_None) {
1505 /* Non-blocking stream would have blocked. Special return code! */
1506 Py_DECREF(res);
1507 return -2;
1508 }
1509 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1510 Py_DECREF(res);
1511 if (n < 0 || n > len) {
1512 PyErr_Format(PyExc_IOError,
1513 "raw readinto() returned invalid length %zd "
1514 "(should have been between 0 and %zd)", n, len);
1515 return -1;
1516 }
1517 if (n > 0 && self->abs_pos != -1)
1518 self->abs_pos += n;
1519 return n;
1520}
1521
1522static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001523_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001524{
1525 Py_ssize_t start, len, n;
1526 if (VALID_READ_BUFFER(self))
1527 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1528 else
1529 start = 0;
1530 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001531 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532 if (n <= 0)
1533 return n;
1534 self->read_end = start + n;
1535 self->raw_pos = start + n;
1536 return n;
1537}
1538
1539static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001540_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001541{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001542 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001543 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001544
1545 /* First copy what we have in the current buffer. */
1546 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1547 if (current_size) {
1548 data = PyBytes_FromStringAndSize(
1549 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001550 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001551 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001552 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001554 /* We're going past the buffer's bounds, flush it */
1555 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 tmp = buffered_flush_and_rewind_unlocked(self);
1557 if (tmp == NULL)
1558 goto cleanup;
1559 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001560 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001561 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001562
1563 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001564 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1565 if (tmp == NULL)
1566 goto cleanup;
1567 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001568 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001570 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001571 if (tmp == Py_None) {
1572 if (current_size == 0) {
1573 res = Py_None;
1574 goto cleanup;
1575 } else {
1576 res = data;
1577 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001578 }
1579 }
1580 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001581 PyBytes_Concat(&data, tmp);
1582 res = data;
1583 goto cleanup;
1584 }
1585 else {
1586 res = tmp;
1587 goto cleanup;
1588 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001589 }
1590
1591 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001592 if (chunks == NULL)
1593 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001594
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595 while (1) {
1596 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001597 if (PyList_Append(chunks, data) < 0)
1598 goto cleanup;
1599 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001600 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001601
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602 /* Read until EOF or until read() would block. */
1603 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001604 if (data == NULL)
1605 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001606 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001608 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609 }
1610 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1611 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001612 res = data;
1613 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001614 }
1615 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001616 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1617 res = tmp;
1618 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001619 }
1620 }
1621 current_size += PyBytes_GET_SIZE(data);
1622 if (self->abs_pos != -1)
1623 self->abs_pos += PyBytes_GET_SIZE(data);
1624 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001625cleanup:
1626 /* res is either NULL or a borrowed ref */
1627 Py_XINCREF(res);
1628 Py_XDECREF(data);
1629 Py_XDECREF(tmp);
1630 Py_XDECREF(chunks);
1631 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001632}
1633
1634/* Read n bytes from the buffer if it can, otherwise return None.
1635 This function is simple enough that it can run unlocked. */
1636static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001637_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001638{
1639 Py_ssize_t current_size;
1640
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001641 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1642 if (n <= current_size) {
1643 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001644 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1645 if (res != NULL)
1646 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001647 return res;
1648 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001649 Py_RETURN_NONE;
1650}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001651
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001652/* Generic read function: read from the stream until enough bytes are read,
1653 * or until an EOF occurs or until read() would block.
1654 */
1655static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001656_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001657{
1658 PyObject *res = NULL;
1659 Py_ssize_t current_size, remaining, written;
1660 char *out;
1661
1662 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1663 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001664 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001665
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001666 res = PyBytes_FromStringAndSize(NULL, n);
1667 if (res == NULL)
1668 goto error;
1669 out = PyBytes_AS_STRING(res);
1670 remaining = n;
1671 written = 0;
1672 if (current_size > 0) {
1673 memcpy(out, self->buffer + self->pos, current_size);
1674 remaining -= current_size;
1675 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001676 self->pos += current_size;
1677 }
1678 /* Flush the write buffer if necessary */
1679 if (self->writable) {
1680 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1681 if (r == NULL)
1682 goto error;
1683 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001684 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001685 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001686 while (remaining > 0) {
1687 /* We want to read a whole block at the end into buffer.
1688 If we had readv() we could do this in one pass. */
1689 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1690 if (r == 0)
1691 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001692 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693 if (r == -1)
1694 goto error;
1695 if (r == 0 || r == -2) {
1696 /* EOF occurred or read() would block. */
1697 if (r == 0 || written > 0) {
1698 if (_PyBytes_Resize(&res, written))
1699 goto error;
1700 return res;
1701 }
1702 Py_DECREF(res);
1703 Py_INCREF(Py_None);
1704 return Py_None;
1705 }
1706 remaining -= r;
1707 written += r;
1708 }
1709 assert(remaining <= self->buffer_size);
1710 self->pos = 0;
1711 self->raw_pos = 0;
1712 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001713 /* NOTE: when the read is satisfied, we avoid issuing any additional
1714 reads, which could block indefinitely (e.g. on a socket).
1715 See issue #9550. */
1716 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001717 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001718 if (r == -1)
1719 goto error;
1720 if (r == 0 || r == -2) {
1721 /* EOF occurred or read() would block. */
1722 if (r == 0 || written > 0) {
1723 if (_PyBytes_Resize(&res, written))
1724 goto error;
1725 return res;
1726 }
1727 Py_DECREF(res);
1728 Py_INCREF(Py_None);
1729 return Py_None;
1730 }
1731 if (remaining > r) {
1732 memcpy(out + written, self->buffer + self->pos, r);
1733 written += r;
1734 self->pos += r;
1735 remaining -= r;
1736 }
1737 else if (remaining > 0) {
1738 memcpy(out + written, self->buffer + self->pos, remaining);
1739 written += remaining;
1740 self->pos += remaining;
1741 remaining = 0;
1742 }
1743 if (remaining == 0)
1744 break;
1745 }
1746
1747 return res;
1748
1749error:
1750 Py_XDECREF(res);
1751 return NULL;
1752}
1753
1754static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001755_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001756{
1757 Py_ssize_t have, r;
1758
1759 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1760 /* Constraints:
1761 1. we don't want to advance the file position.
1762 2. we don't want to lose block alignment, so we can't shift the buffer
1763 to make some place.
1764 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1765 */
1766 if (have > 0) {
1767 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1768 }
1769
1770 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001771 _bufferedreader_reset_buf(self);
1772 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 if (r == -1)
1774 return NULL;
1775 if (r == -2)
1776 r = 0;
1777 self->pos = 0;
1778 return PyBytes_FromStringAndSize(self->buffer, r);
1779}
1780
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001781static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001782 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001783 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1784 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1785 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1786 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1787 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1788 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1789 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1790 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001791 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001792 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001794 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1795 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1796 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001797 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07001798 {"readinto1", (PyCFunction)buffered_readinto1, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1800 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1801 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1802 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001803 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 {NULL, NULL}
1805};
1806
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001807static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001808 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001809 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 {NULL}
1811};
1812
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001813static PyGetSetDef bufferedreader_getset[] = {
1814 {"closed", (getter)buffered_closed_get, NULL, NULL},
1815 {"name", (getter)buffered_name_get, NULL, NULL},
1816 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001817 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818};
1819
1820
1821PyTypeObject PyBufferedReader_Type = {
1822 PyVarObject_HEAD_INIT(NULL, 0)
1823 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001826 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 0, /*tp_print*/
1828 0, /*tp_getattr*/
1829 0, /*tp_setattr*/
1830 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001831 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832 0, /*tp_as_number*/
1833 0, /*tp_as_sequence*/
1834 0, /*tp_as_mapping*/
1835 0, /*tp_hash */
1836 0, /*tp_call*/
1837 0, /*tp_str*/
1838 0, /*tp_getattro*/
1839 0, /*tp_setattro*/
1840 0, /*tp_as_buffer*/
1841 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001842 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001843 bufferedreader_doc, /* tp_doc */
1844 (traverseproc)buffered_traverse, /* tp_traverse */
1845 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001847 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001849 (iternextfunc)buffered_iternext, /* tp_iternext */
1850 bufferedreader_methods, /* tp_methods */
1851 bufferedreader_members, /* tp_members */
1852 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853 0, /* tp_base */
1854 0, /* tp_dict */
1855 0, /* tp_descr_get */
1856 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001857 offsetof(buffered, dict), /* tp_dictoffset */
1858 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859 0, /* tp_alloc */
1860 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001861 0, /* tp_free */
1862 0, /* tp_is_gc */
1863 0, /* tp_bases */
1864 0, /* tp_mro */
1865 0, /* tp_cache */
1866 0, /* tp_subclasses */
1867 0, /* tp_weaklist */
1868 0, /* tp_del */
1869 0, /* tp_version_tag */
1870 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001871};
1872
1873
Benjamin Peterson59406a92009-03-26 17:10:29 +00001874
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875/*
1876 * class BufferedWriter
1877 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001878PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001879 "A buffer for a writeable sequential RawIO object.\n"
1880 "\n"
1881 "The constructor creates a BufferedWriter for the given writeable raw\n"
1882 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001883 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884 );
1885
1886static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001887_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001888{
1889 self->write_pos = 0;
1890 self->write_end = -1;
1891}
1892
1893static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001894bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001895{
Florent Xicluna109d5732012-07-07 17:03:22 +02001896 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001897 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898 PyObject *raw;
1899
1900 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001901 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001902
R David Murray9f10f562013-02-23 22:07:55 -05001903 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001904 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001905 return -1;
1906 }
1907
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001908 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001909 return -1;
1910
1911 Py_CLEAR(self->raw);
1912 Py_INCREF(raw);
1913 self->raw = raw;
1914 self->readable = 0;
1915 self->writable = 1;
1916
1917 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001918 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001919 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001920 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921 self->pos = 0;
1922
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001923 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1924 Py_TYPE(raw) == &PyFileIO_Type);
1925
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926 self->ok = 1;
1927 return 0;
1928}
1929
1930static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001931_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001932{
1933 Py_buffer buf;
1934 PyObject *memobj, *res;
1935 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001936 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937 /* NOTE: the buffer needn't be released as its object is NULL. */
1938 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1939 return -1;
1940 memobj = PyMemoryView_FromBuffer(&buf);
1941 if (memobj == NULL)
1942 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001943 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1944 occurs so we needn't do it ourselves.
1945 We then retry writing, ignoring the signal if no handler has
1946 raised (see issue #10956).
1947 */
1948 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001949 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001950 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001951 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001952 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001953 Py_DECREF(memobj);
1954 if (res == NULL)
1955 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001956 if (res == Py_None) {
1957 /* Non-blocking stream would have blocked. Special return code!
1958 Being paranoid we reset errno in case it is changed by code
1959 triggered by a decref. errno is used by _set_BlockingIOError(). */
1960 Py_DECREF(res);
1961 errno = errnum;
1962 return -2;
1963 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1965 Py_DECREF(res);
1966 if (n < 0 || n > len) {
1967 PyErr_Format(PyExc_IOError,
1968 "raw write() returned invalid length %zd "
1969 "(should have been between 0 and %zd)", n, len);
1970 return -1;
1971 }
1972 if (n > 0 && self->abs_pos != -1)
1973 self->abs_pos += n;
1974 return n;
1975}
1976
1977/* `restore_pos` is 1 if we need to restore the raw stream position at
1978 the end, 0 otherwise. */
1979static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001980_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981{
1982 Py_ssize_t written = 0;
1983 Py_off_t n, rewind;
1984
1985 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1986 goto end;
1987 /* First, rewind */
1988 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1989 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001990 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 if (n < 0) {
1992 goto error;
1993 }
1994 self->raw_pos -= rewind;
1995 }
1996 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001997 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998 self->buffer + self->write_pos,
1999 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2000 Py_off_t, Py_ssize_t));
2001 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002002 goto error;
2003 }
2004 else if (n == -2) {
2005 _set_BlockingIOError("write could not complete without blocking",
2006 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 goto error;
2008 }
2009 self->write_pos += n;
2010 self->raw_pos = self->write_pos;
2011 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002012 /* Partial writes can return successfully when interrupted by a
2013 signal (see write(2)). We must run signal handlers before
2014 blocking another time, possibly indefinitely. */
2015 if (PyErr_CheckSignals() < 0)
2016 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 }
2018
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002019 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020
2021end:
2022 Py_RETURN_NONE;
2023
2024error:
2025 return NULL;
2026}
2027
2028static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002029bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030{
2031 PyObject *res = NULL;
2032 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002033 Py_ssize_t written, avail, remaining;
2034 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035
2036 CHECK_INITIALIZED(self)
2037 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
2038 return NULL;
2039 }
2040
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002041 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002042 PyErr_SetString(PyExc_ValueError, "write to closed file");
2043 PyBuffer_Release(&buf);
2044 return NULL;
2045 }
2046
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00002047 if (!ENTER_BUFFERED(self)) {
2048 PyBuffer_Release(&buf);
2049 return NULL;
2050 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051
2052 /* Fast path: the data to write can be fully buffered. */
2053 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2054 self->pos = 0;
2055 self->raw_pos = 0;
2056 }
2057 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2058 if (buf.len <= avail) {
2059 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002060 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 self->write_pos = self->pos;
2062 }
2063 ADJUST_POSITION(self, self->pos + buf.len);
2064 if (self->pos > self->write_end)
2065 self->write_end = self->pos;
2066 written = buf.len;
2067 goto end;
2068 }
2069
2070 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002071 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002072 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002073 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074 if (w == NULL)
2075 goto error;
2076 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002077 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078 /* Make some place by shifting the buffer. */
2079 assert(VALID_WRITE_BUFFER(self));
2080 memmove(self->buffer, self->buffer + self->write_pos,
2081 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2082 Py_off_t, Py_ssize_t));
2083 self->write_end -= self->write_pos;
2084 self->raw_pos -= self->write_pos;
2085 self->pos -= self->write_pos;
2086 self->write_pos = 0;
2087 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2088 Py_off_t, Py_ssize_t);
2089 if (buf.len <= avail) {
2090 /* Everything can be buffered */
2091 PyErr_Clear();
2092 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2093 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002094 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095 written = buf.len;
2096 goto end;
2097 }
2098 /* Buffer as much as possible. */
2099 memcpy(self->buffer + self->write_end, buf.buf, avail);
2100 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002101 self->pos += avail;
2102 /* XXX Modifying the existing exception e using the pointer w
2103 will change e.characters_written but not e.args[2].
2104 Therefore we just replace with a new error. */
2105 _set_BlockingIOError("write could not complete without blocking",
2106 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107 goto error;
2108 }
2109 Py_CLEAR(res);
2110
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002111 /* Adjust the raw stream position if it is away from the logical stream
2112 position. This happens if the read buffer has been filled but not
2113 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2114 the raw stream by itself).
2115 Fixes issue #6629.
2116 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002117 offset = RAW_OFFSET(self);
2118 if (offset != 0) {
2119 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002120 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002121 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002122 }
2123
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124 /* Then write buf itself. At this point the buffer has been emptied. */
2125 remaining = buf.len;
2126 written = 0;
2127 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002128 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002129 self, (char *) buf.buf + written, buf.len - written);
2130 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002131 goto error;
2132 } else if (n == -2) {
2133 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002134 if (remaining > self->buffer_size) {
2135 /* Can't buffer everything, still buffer as much as possible */
2136 memcpy(self->buffer,
2137 (char *) buf.buf + written, self->buffer_size);
2138 self->raw_pos = 0;
2139 ADJUST_POSITION(self, self->buffer_size);
2140 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002141 written += self->buffer_size;
2142 _set_BlockingIOError("write could not complete without "
2143 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002144 goto error;
2145 }
2146 PyErr_Clear();
2147 break;
2148 }
2149 written += n;
2150 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002151 /* Partial writes can return successfully when interrupted by a
2152 signal (see write(2)). We must run signal handlers before
2153 blocking another time, possibly indefinitely. */
2154 if (PyErr_CheckSignals() < 0)
2155 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 }
2157 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002158 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 if (remaining > 0) {
2160 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2161 written += remaining;
2162 }
2163 self->write_pos = 0;
2164 /* TODO: sanity check (remaining >= 0) */
2165 self->write_end = remaining;
2166 ADJUST_POSITION(self, remaining);
2167 self->raw_pos = 0;
2168
2169end:
2170 res = PyLong_FromSsize_t(written);
2171
2172error:
2173 LEAVE_BUFFERED(self)
2174 PyBuffer_Release(&buf);
2175 return res;
2176}
2177
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002178static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2181 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2182 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2183 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2184 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2185 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2186 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002187 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002188 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2191 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2192 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2193 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2194 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002195 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002196 {NULL, NULL}
2197};
2198
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002199static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002200 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002201 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 {NULL}
2203};
2204
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002205static PyGetSetDef bufferedwriter_getset[] = {
2206 {"closed", (getter)buffered_closed_get, NULL, NULL},
2207 {"name", (getter)buffered_name_get, NULL, NULL},
2208 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002209 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210};
2211
2212
2213PyTypeObject PyBufferedWriter_Type = {
2214 PyVarObject_HEAD_INIT(NULL, 0)
2215 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002216 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002218 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219 0, /*tp_print*/
2220 0, /*tp_getattr*/
2221 0, /*tp_setattr*/
2222 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 0, /*tp_as_number*/
2225 0, /*tp_as_sequence*/
2226 0, /*tp_as_mapping*/
2227 0, /*tp_hash */
2228 0, /*tp_call*/
2229 0, /*tp_str*/
2230 0, /*tp_getattro*/
2231 0, /*tp_setattro*/
2232 0, /*tp_as_buffer*/
2233 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002234 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002235 bufferedwriter_doc, /* tp_doc */
2236 (traverseproc)buffered_traverse, /* tp_traverse */
2237 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002239 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240 0, /* tp_iter */
2241 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002242 bufferedwriter_methods, /* tp_methods */
2243 bufferedwriter_members, /* tp_members */
2244 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245 0, /* tp_base */
2246 0, /* tp_dict */
2247 0, /* tp_descr_get */
2248 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002249 offsetof(buffered, dict), /* tp_dictoffset */
2250 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251 0, /* tp_alloc */
2252 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002253 0, /* tp_free */
2254 0, /* tp_is_gc */
2255 0, /* tp_bases */
2256 0, /* tp_mro */
2257 0, /* tp_cache */
2258 0, /* tp_subclasses */
2259 0, /* tp_weaklist */
2260 0, /* tp_del */
2261 0, /* tp_version_tag */
2262 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263};
2264
2265
2266
2267/*
2268 * BufferedRWPair
2269 */
2270
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002271PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002272 "A buffered reader and writer object together.\n"
2273 "\n"
2274 "A buffered reader object and buffered writer object put together to\n"
2275 "form a sequential IO object that can read and write. This is typically\n"
2276 "used with a socket or two-way pipe.\n"
2277 "\n"
2278 "reader and writer are RawIOBase objects that are readable and\n"
2279 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002280 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002281 );
2282
2283/* XXX The usefulness of this (compared to having two separate IO objects) is
2284 * questionable.
2285 */
2286
2287typedef struct {
2288 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289 buffered *reader;
2290 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002291 PyObject *dict;
2292 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002293} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002294
2295static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002296bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297{
2298 PyObject *reader, *writer;
2299 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300
Florent Xicluna109d5732012-07-07 17:03:22 +02002301 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2302 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303 return -1;
2304 }
2305
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002306 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002308 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002309 return -1;
2310
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002311 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002312 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313 if (self->reader == NULL)
2314 return -1;
2315
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002316 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002317 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002318 if (self->writer == NULL) {
2319 Py_CLEAR(self->reader);
2320 return -1;
2321 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002322
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323 return 0;
2324}
2325
2326static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002327bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002328{
2329 Py_VISIT(self->dict);
2330 return 0;
2331}
2332
2333static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002334bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002335{
2336 Py_CLEAR(self->reader);
2337 Py_CLEAR(self->writer);
2338 Py_CLEAR(self->dict);
2339 return 0;
2340}
2341
2342static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002343bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002344{
2345 _PyObject_GC_UNTRACK(self);
2346 Py_CLEAR(self->reader);
2347 Py_CLEAR(self->writer);
2348 Py_CLEAR(self->dict);
2349 Py_TYPE(self)->tp_free((PyObject *) self);
2350}
2351
2352static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002353_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002354{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002355 PyObject *func, *ret;
2356 if (self == NULL) {
2357 PyErr_SetString(PyExc_ValueError,
2358 "I/O operation on uninitialized object");
2359 return NULL;
2360 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002361
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002362 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002363 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002364 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002365 return NULL;
2366 }
2367
2368 ret = PyObject_CallObject(func, args);
2369 Py_DECREF(func);
2370 return ret;
2371}
2372
2373static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002374bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002375{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002376 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002377}
2378
2379static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002380bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002381{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002382 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002383}
2384
2385static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002386bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002387{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002388 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002389}
2390
2391static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002392bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002393{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002394 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002395}
2396
2397static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002398bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2399{
2400 return _forward_call(self->reader, &PyId_readinto1, args);
2401}
2402
2403static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002404bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002405{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002406 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002407}
2408
2409static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002410bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002411{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002412 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002413}
2414
2415static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002416bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002417{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002418 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002419}
2420
2421static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002422bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002423{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002424 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002425}
2426
2427static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002428bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002429{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002430 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002431 if (ret == NULL)
2432 return NULL;
2433 Py_DECREF(ret);
2434
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002435 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002436}
2437
2438static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002439bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002440{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002441 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442
2443 if (ret != Py_False) {
2444 /* either True or exception */
2445 return ret;
2446 }
2447 Py_DECREF(ret);
2448
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002449 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002450}
2451
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002452static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002453bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002454{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002455 if (self->writer == NULL) {
2456 PyErr_SetString(PyExc_RuntimeError,
2457 "the BufferedRWPair object is being garbage-collected");
2458 return NULL;
2459 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002460 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2461}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002462
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002463static PyMethodDef bufferedrwpair_methods[] = {
2464 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2465 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2466 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2467 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002468 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002469
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002470 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2471 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002472
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002473 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2474 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002475
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002476 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2477 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002478
Antoine Pitrou243757e2010-11-05 21:15:39 +00002479 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2480
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002481 {NULL, NULL}
2482};
2483
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002484static PyGetSetDef bufferedrwpair_getset[] = {
2485 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002486 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002487};
2488
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002489PyTypeObject PyBufferedRWPair_Type = {
2490 PyVarObject_HEAD_INIT(NULL, 0)
2491 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002492 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002493 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002494 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002495 0, /*tp_print*/
2496 0, /*tp_getattr*/
2497 0, /*tp_setattr*/
2498 0, /*tp_compare */
2499 0, /*tp_repr*/
2500 0, /*tp_as_number*/
2501 0, /*tp_as_sequence*/
2502 0, /*tp_as_mapping*/
2503 0, /*tp_hash */
2504 0, /*tp_call*/
2505 0, /*tp_str*/
2506 0, /*tp_getattro*/
2507 0, /*tp_setattro*/
2508 0, /*tp_as_buffer*/
2509 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002510 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002511 bufferedrwpair_doc, /* tp_doc */
2512 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2513 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002514 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002515 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002516 0, /* tp_iter */
2517 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002518 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002519 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002520 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002521 0, /* tp_base */
2522 0, /* tp_dict */
2523 0, /* tp_descr_get */
2524 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002525 offsetof(rwpair, dict), /* tp_dictoffset */
2526 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002527 0, /* tp_alloc */
2528 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002529 0, /* tp_free */
2530 0, /* tp_is_gc */
2531 0, /* tp_bases */
2532 0, /* tp_mro */
2533 0, /* tp_cache */
2534 0, /* tp_subclasses */
2535 0, /* tp_weaklist */
2536 0, /* tp_del */
2537 0, /* tp_version_tag */
2538 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002539};
2540
2541
2542
2543/*
2544 * BufferedRandom
2545 */
2546
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002547PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002548 "A buffered interface to random access streams.\n"
2549 "\n"
2550 "The constructor creates a reader and writer for a seekable stream,\n"
2551 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002552 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002553 );
2554
2555static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002556bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002557{
Florent Xicluna109d5732012-07-07 17:03:22 +02002558 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560 PyObject *raw;
2561
2562 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002563 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002564
R David Murray9f10f562013-02-23 22:07:55 -05002565 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002566 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002567 return -1;
2568 }
2569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002571 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002572 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002573 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002574 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575 return -1;
2576
2577 Py_CLEAR(self->raw);
2578 Py_INCREF(raw);
2579 self->raw = raw;
2580 self->buffer_size = buffer_size;
2581 self->readable = 1;
2582 self->writable = 1;
2583
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002584 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002586 _bufferedreader_reset_buf(self);
2587 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002588 self->pos = 0;
2589
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002590 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2591 Py_TYPE(raw) == &PyFileIO_Type);
2592
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002593 self->ok = 1;
2594 return 0;
2595}
2596
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002597static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002598 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002599 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2600 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2601 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2602 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2603 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2604 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2605 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002606 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002607 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002608
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002609 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002610
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002611 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2612 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2613 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2614 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2615 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2616 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002617 {"readinto1", (PyCFunction)buffered_readinto1, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002618 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2619 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2620 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002621 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002622 {NULL, NULL}
2623};
2624
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002625static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002626 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002627 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002628 {NULL}
2629};
2630
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002631static PyGetSetDef bufferedrandom_getset[] = {
2632 {"closed", (getter)buffered_closed_get, NULL, NULL},
2633 {"name", (getter)buffered_name_get, NULL, NULL},
2634 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002635 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636};
2637
2638
2639PyTypeObject PyBufferedRandom_Type = {
2640 PyVarObject_HEAD_INIT(NULL, 0)
2641 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002642 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002643 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002644 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002645 0, /*tp_print*/
2646 0, /*tp_getattr*/
2647 0, /*tp_setattr*/
2648 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002649 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650 0, /*tp_as_number*/
2651 0, /*tp_as_sequence*/
2652 0, /*tp_as_mapping*/
2653 0, /*tp_hash */
2654 0, /*tp_call*/
2655 0, /*tp_str*/
2656 0, /*tp_getattro*/
2657 0, /*tp_setattro*/
2658 0, /*tp_as_buffer*/
2659 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002660 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002661 bufferedrandom_doc, /* tp_doc */
2662 (traverseproc)buffered_traverse, /* tp_traverse */
2663 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002664 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002665 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002666 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002667 (iternextfunc)buffered_iternext, /* tp_iternext */
2668 bufferedrandom_methods, /* tp_methods */
2669 bufferedrandom_members, /* tp_members */
2670 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002671 0, /* tp_base */
2672 0, /*tp_dict*/
2673 0, /* tp_descr_get */
2674 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002675 offsetof(buffered, dict), /*tp_dictoffset*/
2676 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002677 0, /* tp_alloc */
2678 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002679 0, /* tp_free */
2680 0, /* tp_is_gc */
2681 0, /* tp_bases */
2682 0, /* tp_mro */
2683 0, /* tp_cache */
2684 0, /* tp_subclasses */
2685 0, /* tp_weaklist */
2686 0, /* tp_del */
2687 0, /* tp_version_tag */
2688 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002689};