blob: a04b48dd3a98be781973901f8f791deba130969c [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020016_Py_IDENTIFIER(close);
17_Py_IDENTIFIER(_dealloc_warn);
18_Py_IDENTIFIER(flush);
19_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020020_Py_IDENTIFIER(mode);
21_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020022_Py_IDENTIFIER(peek);
23_Py_IDENTIFIER(read);
24_Py_IDENTIFIER(read1);
25_Py_IDENTIFIER(readable);
26_Py_IDENTIFIER(readinto);
27_Py_IDENTIFIER(writable);
28_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020029
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000030/*
31 * BufferedIOBase class, inherits from IOBase.
32 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000033PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034 "Base class for buffered IO objects.\n"
35 "\n"
36 "The main difference with RawIOBase is that the read() method\n"
37 "supports omitting the size argument, and does not have a default\n"
38 "implementation that defers to readinto().\n"
39 "\n"
40 "In addition, read(), readinto() and write() may raise\n"
41 "BlockingIOError if the underlying raw stream is in non-blocking\n"
42 "mode and not ready; unlike their raw counterparts, they will never\n"
43 "return None.\n"
44 "\n"
45 "A typical implementation should not inherit from a RawIOBase\n"
46 "implementation, but wrap one.\n"
47 );
48
49static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000050bufferediobase_readinto(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000051{
52 Py_buffer buf;
53 Py_ssize_t len;
54 PyObject *data;
55
56 if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
57 return NULL;
58 }
59
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020060 data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000061 if (data == NULL)
62 goto error;
63
64 if (!PyBytes_Check(data)) {
65 Py_DECREF(data);
66 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
67 goto error;
68 }
69
70 len = Py_SIZE(data);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030071 if (len > buf.len) {
72 PyErr_Format(PyExc_ValueError,
73 "read() returned too much data: "
74 "%zd bytes requested, %zd returned",
75 buf.len, len);
76 Py_DECREF(data);
77 goto error;
78 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000079 memcpy(buf.buf, PyBytes_AS_STRING(data), len);
80
81 PyBuffer_Release(&buf);
82 Py_DECREF(data);
83
84 return PyLong_FromSsize_t(len);
85
86 error:
87 PyBuffer_Release(&buf);
88 return NULL;
89}
90
91static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000092bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000093{
94 PyErr_SetString(IO_STATE->unsupported_operation, message);
95 return NULL;
96}
97
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000098PyDoc_STRVAR(bufferediobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000099 "Disconnect this buffer from its underlying raw stream and return it.\n"
100 "\n"
101 "After the raw stream has been detached, the buffer is in an unusable\n"
102 "state.\n");
103
104static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000105bufferediobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000106{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000107 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000108}
109
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000110PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000111 "Read and return up to n bytes.\n"
112 "\n"
113 "If the argument is omitted, None, or negative, reads and\n"
114 "returns all data until EOF.\n"
115 "\n"
116 "If the argument is positive, and the underlying raw stream is\n"
117 "not 'interactive', multiple raw reads may be issued to satisfy\n"
118 "the byte count (unless EOF is reached first). But for\n"
119 "interactive raw streams (as well as sockets and pipes), at most\n"
120 "one raw read will be issued, and a short result does not imply\n"
121 "that EOF is imminent.\n"
122 "\n"
123 "Returns an empty bytes object on EOF.\n"
124 "\n"
125 "Returns None if the underlying raw stream was open in non-blocking\n"
126 "mode and no data is available at the moment.\n");
127
128static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000129bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000130{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000131 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000132}
133
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000134PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000135 "Read and return up to n bytes, with at most one read() call\n"
136 "to the underlying raw stream. A short result does not imply\n"
137 "that EOF is imminent.\n"
138 "\n"
139 "Returns an empty bytes object on EOF.\n");
140
141static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000142bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000143{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000145}
146
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000147PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000148 "Write the given buffer to the IO stream.\n"
149 "\n"
150 "Returns the number of bytes written, which is never less than\n"
151 "len(b).\n"
152 "\n"
153 "Raises BlockingIOError if the buffer is full and the\n"
154 "underlying raw stream cannot accept more data at the moment.\n");
155
156static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000157bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000158{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000159 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000160}
161
162
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000163static PyMethodDef bufferediobase_methods[] = {
164 {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc},
165 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
166 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
167 {"readinto", bufferediobase_readinto, METH_VARARGS, NULL},
168 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000169 {NULL, NULL}
170};
171
172PyTypeObject PyBufferedIOBase_Type = {
173 PyVarObject_HEAD_INIT(NULL, 0)
174 "_io._BufferedIOBase", /*tp_name*/
175 0, /*tp_basicsize*/
176 0, /*tp_itemsize*/
177 0, /*tp_dealloc*/
178 0, /*tp_print*/
179 0, /*tp_getattr*/
180 0, /*tp_setattr*/
181 0, /*tp_compare */
182 0, /*tp_repr*/
183 0, /*tp_as_number*/
184 0, /*tp_as_sequence*/
185 0, /*tp_as_mapping*/
186 0, /*tp_hash */
187 0, /*tp_call*/
188 0, /*tp_str*/
189 0, /*tp_getattro*/
190 0, /*tp_setattro*/
191 0, /*tp_as_buffer*/
Antoine Pitrou796564c2013-07-30 19:59:21 +0200192 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
193 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194 bufferediobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 0, /* tp_traverse */
196 0, /* tp_clear */
197 0, /* tp_richcompare */
198 0, /* tp_weaklistoffset */
199 0, /* tp_iter */
200 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000201 bufferediobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000202 0, /* tp_members */
203 0, /* tp_getset */
204 &PyIOBase_Type, /* tp_base */
205 0, /* tp_dict */
206 0, /* tp_descr_get */
207 0, /* tp_descr_set */
208 0, /* tp_dictoffset */
209 0, /* tp_init */
210 0, /* tp_alloc */
211 0, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200212 0, /* tp_free */
213 0, /* tp_is_gc */
214 0, /* tp_bases */
215 0, /* tp_mro */
216 0, /* tp_cache */
217 0, /* tp_subclasses */
218 0, /* tp_weaklist */
219 0, /* tp_del */
220 0, /* tp_version_tag */
221 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000222};
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000223
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000224
225typedef struct {
226 PyObject_HEAD
227
228 PyObject *raw;
229 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000230 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000231 int readable;
232 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200233 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200234
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000235 /* True if this is a vanilla Buffered object (rather than a user derived
236 class) *and* the raw stream is a vanilla FileIO object. */
237 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000238
239 /* Absolute position inside the raw stream (-1 if unknown). */
240 Py_off_t abs_pos;
241
242 /* A static buffer of size `buffer_size` */
243 char *buffer;
244 /* Current logical position in the buffer. */
245 Py_off_t pos;
246 /* Position of the raw stream in the buffer. */
247 Py_off_t raw_pos;
248
249 /* Just after the last buffered byte in the buffer, or -1 if the buffer
250 isn't ready for reading. */
251 Py_off_t read_end;
252
253 /* Just after the last byte actually written */
254 Py_off_t write_pos;
255 /* Just after the last byte waiting to be written, or -1 if the buffer
256 isn't ready for writing. */
257 Py_off_t write_end;
258
Georg Brandldfd73442009-04-05 11:47:34 +0000259#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000261 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000262#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000263
264 Py_ssize_t buffer_size;
265 Py_ssize_t buffer_mask;
266
267 PyObject *dict;
268 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000269} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000270
271/*
272 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200273
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000274 * BufferedReader, BufferedWriter and BufferedRandom try to share most
275 methods (this is helped by the members `readable` and `writable`, which
276 are initialized in the respective constructors)
277 * They also share a single buffer for reading and writing. This enables
278 interleaved reads and writes without flushing. It also makes the logic
279 a bit trickier to get right.
280 * The absolute position of the raw stream is cached, if possible, in the
281 `abs_pos` member. It must be updated every time an operation is done
282 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000283 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000284 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000285 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
286 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000287
288 NOTE: we should try to maintain block alignment of reads and writes to the
289 raw stream (according to the buffer size), but for now it is only done
290 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200291
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000292*/
293
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000294/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000295
Georg Brandldfd73442009-04-05 11:47:34 +0000296#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000297
298static int
299_enter_buffered_busy(buffered *self)
300{
301 if (self->owner == PyThread_get_thread_ident()) {
302 PyErr_Format(PyExc_RuntimeError,
303 "reentrant call inside %R", self);
304 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000305 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000306 Py_BEGIN_ALLOW_THREADS
307 PyThread_acquire_lock(self->lock, 1);
308 Py_END_ALLOW_THREADS
309 return 1;
310}
311
312#define ENTER_BUFFERED(self) \
313 ( (PyThread_acquire_lock(self->lock, 0) ? \
314 1 : _enter_buffered_busy(self)) \
315 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000316
317#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000318 do { \
319 self->owner = 0; \
320 PyThread_release_lock(self->lock); \
321 } while(0);
322
Georg Brandldfd73442009-04-05 11:47:34 +0000323#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000324#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000325#define LEAVE_BUFFERED(self)
326#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000327
328#define CHECK_INITIALIZED(self) \
329 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000330 if (self->detached) { \
331 PyErr_SetString(PyExc_ValueError, \
332 "raw stream has been detached"); \
333 } else { \
334 PyErr_SetString(PyExc_ValueError, \
335 "I/O operation on uninitialized object"); \
336 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000337 return NULL; \
338 }
339
340#define CHECK_INITIALIZED_INT(self) \
341 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000342 if (self->detached) { \
343 PyErr_SetString(PyExc_ValueError, \
344 "raw stream has been detached"); \
345 } else { \
346 PyErr_SetString(PyExc_ValueError, \
347 "I/O operation on uninitialized object"); \
348 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000349 return -1; \
350 }
351
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000352#define IS_CLOSED(self) \
353 (self->fast_closed_checks \
354 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000355 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000356
357#define CHECK_CLOSED(self, error_msg) \
358 if (IS_CLOSED(self)) { \
359 PyErr_SetString(PyExc_ValueError, error_msg); \
360 return NULL; \
361 }
362
363
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000364#define VALID_READ_BUFFER(self) \
365 (self->readable && self->read_end != -1)
366
367#define VALID_WRITE_BUFFER(self) \
368 (self->writable && self->write_end != -1)
369
370#define ADJUST_POSITION(self, _new_pos) \
371 do { \
372 self->pos = _new_pos; \
373 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
374 self->read_end = self->pos; \
375 } while(0)
376
377#define READAHEAD(self) \
378 ((self->readable && VALID_READ_BUFFER(self)) \
379 ? (self->read_end - self->pos) : 0)
380
381#define RAW_OFFSET(self) \
382 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
383 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
384
385#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000386 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387
388#define MINUS_LAST_BLOCK(self, size) \
389 (self->buffer_mask ? \
390 (size & ~self->buffer_mask) : \
391 (self->buffer_size * (size / self->buffer_size)))
392
393
394static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000395buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000396{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200397 self->finalizing = 1;
398 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000399 return;
400 _PyObject_GC_UNTRACK(self);
401 self->ok = 0;
402 if (self->weakreflist != NULL)
403 PyObject_ClearWeakRefs((PyObject *)self);
404 Py_CLEAR(self->raw);
405 if (self->buffer) {
406 PyMem_Free(self->buffer);
407 self->buffer = NULL;
408 }
Georg Brandldfd73442009-04-05 11:47:34 +0000409#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000410 if (self->lock) {
411 PyThread_free_lock(self->lock);
412 self->lock = NULL;
413 }
Georg Brandldfd73442009-04-05 11:47:34 +0000414#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000415 Py_CLEAR(self->dict);
416 Py_TYPE(self)->tp_free((PyObject *)self);
417}
418
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200419static PyObject *
420buffered_sizeof(buffered *self, void *unused)
421{
422 Py_ssize_t res;
423
424 res = sizeof(buffered);
425 if (self->buffer)
426 res += self->buffer_size;
427 return PyLong_FromSsize_t(res);
428}
429
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000430static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000431buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000432{
433 Py_VISIT(self->raw);
434 Py_VISIT(self->dict);
435 return 0;
436}
437
438static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000439buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000440{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000441 self->ok = 0;
442 Py_CLEAR(self->raw);
443 Py_CLEAR(self->dict);
444 return 0;
445}
446
Antoine Pitroue033e062010-10-29 10:38:18 +0000447/* Because this can call arbitrary code, it shouldn't be called when
448 the refcount is 0 (that is, not directly from tp_dealloc unless
449 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000450static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000451buffered_dealloc_warn(buffered *self, PyObject *source)
452{
453 if (self->ok && self->raw) {
454 PyObject *r;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200455 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000456 if (r)
457 Py_DECREF(r);
458 else
459 PyErr_Clear();
460 }
461 Py_RETURN_NONE;
462}
463
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464/*
465 * _BufferedIOMixin methods
466 * This is not a class, just a collection of methods that will be reused
467 * by BufferedReader and BufferedWriter
468 */
469
470/* Flush and close */
471
472static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000473buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000474{
475 CHECK_INITIALIZED(self)
476 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
477}
478
479static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000480buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481{
482 int closed;
483 PyObject *res;
484 CHECK_INITIALIZED_INT(self)
485 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
486 if (res == NULL)
487 return -1;
488 closed = PyObject_IsTrue(res);
489 Py_DECREF(res);
490 return closed;
491}
492
493static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000494buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000495{
496 CHECK_INITIALIZED(self)
497 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
498}
499
500static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000501buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000502{
Benjamin Peterson68623612012-12-20 11:53:11 -0600503 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504 int r;
505
506 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000507 if (!ENTER_BUFFERED(self))
508 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000510 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511 if (r < 0)
512 goto end;
513 if (r > 0) {
514 res = Py_None;
515 Py_INCREF(res);
516 goto end;
517 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000518
Antoine Pitrou796564c2013-07-30 19:59:21 +0200519 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000520 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
521 if (r)
522 Py_DECREF(r);
523 else
524 PyErr_Clear();
525 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000526 /* flush() will most probably re-take the lock, so drop it first */
527 LEAVE_BUFFERED(self)
528 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000529 if (!ENTER_BUFFERED(self))
530 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600531 if (res == NULL)
532 PyErr_Fetch(&exc, &val, &tb);
533 else
534 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000535
536 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
537
Jesus Ceadc469452012-10-04 12:37:56 +0200538 if (self->buffer) {
539 PyMem_Free(self->buffer);
540 self->buffer = NULL;
541 }
542
Benjamin Peterson68623612012-12-20 11:53:11 -0600543 if (exc != NULL) {
544 if (res != NULL) {
545 Py_CLEAR(res);
546 PyErr_Restore(exc, val, tb);
547 }
548 else {
549 PyObject *val2;
550 Py_DECREF(exc);
551 Py_XDECREF(tb);
552 PyErr_Fetch(&exc, &val2, &tb);
553 PyErr_NormalizeException(&exc, &val2, &tb);
554 PyException_SetContext(val2, val);
555 PyErr_Restore(exc, val2, tb);
556 }
557 }
558
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000559end:
560 LEAVE_BUFFERED(self)
561 return res;
562}
563
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000564/* detach */
565
566static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000567buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000568{
569 PyObject *raw, *res;
570 CHECK_INITIALIZED(self)
571 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
572 if (res == NULL)
573 return NULL;
574 Py_DECREF(res);
575 raw = self->raw;
576 self->raw = NULL;
577 self->detached = 1;
578 self->ok = 0;
579 return raw;
580}
581
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582/* Inquiries */
583
584static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000585buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586{
587 CHECK_INITIALIZED(self)
588 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
589}
590
591static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000592buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593{
594 CHECK_INITIALIZED(self)
595 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
596}
597
598static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000599buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600{
601 CHECK_INITIALIZED(self)
602 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
603}
604
605static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000606buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607{
608 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200609 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000610}
611
612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614{
615 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200616 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617}
618
619/* Lower-level APIs */
620
621static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000622buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623{
624 CHECK_INITIALIZED(self)
625 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
626}
627
628static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000629buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630{
631 CHECK_INITIALIZED(self)
632 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
633}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000634
Antoine Pitrou243757e2010-11-05 21:15:39 +0000635/* Serialization */
636
637static PyObject *
638buffered_getstate(buffered *self, PyObject *args)
639{
640 PyErr_Format(PyExc_TypeError,
641 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
642 return NULL;
643}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000644
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000645/* Forward decls */
646static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100647_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000650static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200655_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000657_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000658static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000659_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000660static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000661_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200662static Py_ssize_t
663_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664
665/*
666 * Helpers
667 */
668
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100669/* Sets the current error to BlockingIOError */
670static void
671_set_BlockingIOError(char *msg, Py_ssize_t written)
672{
673 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200674#ifdef Py_DEBUG
675 /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error
676 if an exception is set when it is called */
677 PyErr_Clear();
678#endif
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100679 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
680 errno, msg, written);
681 if (err)
682 PyErr_SetObject(PyExc_BlockingIOError, err);
683 Py_XDECREF(err);
684}
685
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000686/* Returns the address of the `written` member if a BlockingIOError was
687 raised, NULL otherwise. The error is always re-raised. */
688static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000689_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690{
691 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200692 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000693
694 PyErr_Fetch(&t, &v, &tb);
695 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
696 PyErr_Restore(t, v, tb);
697 return NULL;
698 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200699 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700 /* TODO: sanity check (err->written >= 0) */
701 PyErr_Restore(t, v, tb);
702 return &err->written;
703}
704
705static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000706_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000709 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
711 if (res == NULL)
712 return -1;
713 n = PyNumber_AsOff_t(res, PyExc_ValueError);
714 Py_DECREF(res);
715 if (n < 0) {
716 if (!PyErr_Occurred())
717 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000718 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200719 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000720 return -1;
721 }
722 self->abs_pos = n;
723 return n;
724}
725
726static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000727_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000728{
729 PyObject *res, *posobj, *whenceobj;
730 Py_off_t n;
731
732 posobj = PyLong_FromOff_t(target);
733 if (posobj == NULL)
734 return -1;
735 whenceobj = PyLong_FromLong(whence);
736 if (whenceobj == NULL) {
737 Py_DECREF(posobj);
738 return -1;
739 }
740 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
741 posobj, whenceobj, NULL);
742 Py_DECREF(posobj);
743 Py_DECREF(whenceobj);
744 if (res == NULL)
745 return -1;
746 n = PyNumber_AsOff_t(res, PyExc_ValueError);
747 Py_DECREF(res);
748 if (n < 0) {
749 if (!PyErr_Occurred())
750 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000751 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200752 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000753 return -1;
754 }
755 self->abs_pos = n;
756 return n;
757}
758
759static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000760_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000761{
762 Py_ssize_t n;
763 if (self->buffer_size <= 0) {
764 PyErr_SetString(PyExc_ValueError,
765 "buffer size must be strictly positive");
766 return -1;
767 }
768 if (self->buffer)
769 PyMem_Free(self->buffer);
770 self->buffer = PyMem_Malloc(self->buffer_size);
771 if (self->buffer == NULL) {
772 PyErr_NoMemory();
773 return -1;
774 }
Georg Brandldfd73442009-04-05 11:47:34 +0000775#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000776 if (self->lock)
777 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778 self->lock = PyThread_allocate_lock();
779 if (self->lock == NULL) {
780 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
781 return -1;
782 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000783 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000784#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000785 /* Find out whether buffer_size is a power of 2 */
786 /* XXX is this optimization useful? */
787 for (n = self->buffer_size - 1; n & 1; n >>= 1)
788 ;
789 if (n == 0)
790 self->buffer_mask = self->buffer_size - 1;
791 else
792 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000793 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000794 PyErr_Clear();
795 return 0;
796}
797
Antoine Pitrou707ce822011-02-25 21:24:11 +0000798/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
799 clears the error indicator), 0 otherwise.
800 Should only be called when PyErr_Occurred() is true.
801*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700802int
803_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000804{
805 static PyObject *eintr_int = NULL;
806 PyObject *typ, *val, *tb;
807 PyEnvironmentErrorObject *env_err;
808
809 if (eintr_int == NULL) {
810 eintr_int = PyLong_FromLong(EINTR);
811 assert(eintr_int != NULL);
812 }
813 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
814 return 0;
815 PyErr_Fetch(&typ, &val, &tb);
816 PyErr_NormalizeException(&typ, &val, &tb);
817 env_err = (PyEnvironmentErrorObject *) val;
818 assert(env_err != NULL);
819 if (env_err->myerrno != NULL &&
820 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
821 Py_DECREF(typ);
822 Py_DECREF(val);
823 Py_XDECREF(tb);
824 return 1;
825 }
826 /* This silences any error set by PyObject_RichCompareBool() */
827 PyErr_Restore(typ, val, tb);
828 return 0;
829}
830
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000831/*
832 * Shared methods and wrappers
833 */
834
835static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200836buffered_flush_and_rewind_unlocked(buffered *self)
837{
838 PyObject *res;
839
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100840 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200841 if (res == NULL)
842 return NULL;
843 Py_DECREF(res);
844
845 if (self->readable) {
846 /* Rewind the raw stream so that its position corresponds to
847 the current logical position. */
848 Py_off_t n;
849 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
850 _bufferedreader_reset_buf(self);
851 if (n == -1)
852 return NULL;
853 }
854 Py_RETURN_NONE;
855}
856
857static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000858buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859{
860 PyObject *res;
861
862 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000863 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000865 if (!ENTER_BUFFERED(self))
866 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200867 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868 LEAVE_BUFFERED(self)
869
870 return res;
871}
872
873static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000874buffered_peek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875{
876 Py_ssize_t n = 0;
877 PyObject *res = NULL;
878
879 CHECK_INITIALIZED(self)
880 if (!PyArg_ParseTuple(args, "|n:peek", &n)) {
881 return NULL;
882 }
883
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000884 if (!ENTER_BUFFERED(self))
885 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886
887 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200888 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889 if (res == NULL)
890 goto end;
891 Py_CLEAR(res);
892 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200893 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000894
895end:
896 LEAVE_BUFFERED(self)
897 return res;
898}
899
900static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000901buffered_read(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902{
903 Py_ssize_t n = -1;
904 PyObject *res;
905
906 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +0000907 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000908 return NULL;
909 }
910 if (n < -1) {
911 PyErr_SetString(PyExc_ValueError,
912 "read length must be positive or -1");
913 return NULL;
914 }
915
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000916 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000918 if (n == -1) {
919 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000920 if (!ENTER_BUFFERED(self))
921 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000922 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000923 }
924 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000925 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200926 if (res != Py_None)
927 return res;
928 Py_DECREF(res);
929 if (!ENTER_BUFFERED(self))
930 return NULL;
931 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000932 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000933
Antoine Pitroue05565e2011-08-20 14:39:23 +0200934 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000935 return res;
936}
937
938static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000939buffered_read1(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940{
941 Py_ssize_t n, have, r;
942 PyObject *res = NULL;
943
944 CHECK_INITIALIZED(self)
945 if (!PyArg_ParseTuple(args, "n:read1", &n)) {
946 return NULL;
947 }
948
949 if (n < 0) {
950 PyErr_SetString(PyExc_ValueError,
951 "read length must be positive");
952 return NULL;
953 }
954 if (n == 0)
955 return PyBytes_FromStringAndSize(NULL, 0);
956
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 /* Return up to n bytes. If at least one byte is buffered, we
958 only return buffered bytes. Otherwise, we do one raw read. */
959
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
961 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100962 n = Py_MIN(have, n);
963 res = _bufferedreader_read_fast(self, n);
964 assert(res != Py_None);
965 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000966 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100967 res = PyBytes_FromStringAndSize(NULL, n);
968 if (res == NULL)
969 return NULL;
970 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200971 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100972 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200973 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000974 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100975 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
976 LEAVE_BUFFERED(self)
977 if (r == -1) {
978 Py_DECREF(res);
979 return NULL;
980 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981 if (r == -2)
982 r = 0;
983 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100984 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985 return res;
986}
987
988static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000989buffered_readinto(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200991 Py_buffer buf;
992 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993 PyObject *res = NULL;
994
995 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996
997 if (!PyArg_ParseTuple(args, "w*:readinto", &buf))
998 return NULL;
999
1000 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1001 if (n > 0) {
1002 if (n >= buf.len) {
1003 memcpy(buf.buf, self->buffer + self->pos, buf.len);
1004 self->pos += buf.len;
1005 res = PyLong_FromSsize_t(buf.len);
1006 goto end_unlocked;
1007 }
1008 memcpy(buf.buf, self->buffer + self->pos, n);
1009 self->pos += n;
1010 written = n;
1011 }
1012
1013 if (!ENTER_BUFFERED(self))
1014 goto end_unlocked;
1015
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001016 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001017 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 if (res == NULL)
1019 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001020 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022
1023 _bufferedreader_reset_buf(self);
1024 self->pos = 0;
1025
1026 for (remaining = buf.len - written;
1027 remaining > 0;
1028 written += n, remaining -= n) {
1029 /* If remaining bytes is larger than internal buffer size, copy
1030 * directly into caller's buffer. */
1031 if (remaining > self->buffer_size) {
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001032 n = _bufferedreader_raw_read(self, (char *) buf.buf + written,
1033 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001034 }
1035 else {
1036 n = _bufferedreader_fill_buffer(self);
1037 if (n > 0) {
1038 if (n > remaining)
1039 n = remaining;
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001040 memcpy((char *) buf.buf + written,
1041 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001042 self->pos += n;
1043 continue; /* short circuit */
1044 }
1045 }
1046 if (n == 0 || (n == -2 && written > 0))
1047 break;
1048 if (n < 0) {
1049 if (n == -2) {
1050 Py_INCREF(Py_None);
1051 res = Py_None;
1052 }
1053 goto end;
1054 }
1055 }
1056 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001057
1058end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001059 LEAVE_BUFFERED(self);
1060end_unlocked:
1061 PyBuffer_Release(&buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001062 return res;
1063}
1064
1065static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001066_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067{
1068 PyObject *res = NULL;
1069 PyObject *chunks = NULL;
1070 Py_ssize_t n, written = 0;
1071 const char *start, *s, *end;
1072
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001073 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001074
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001075 /* First, try to find a line in the buffer. This can run unlocked because
1076 the calls to the C API are simple enough that they can't trigger
1077 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001078 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1079 if (limit >= 0 && n > limit)
1080 n = limit;
1081 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001082 s = memchr(start, '\n', n);
1083 if (s != NULL) {
1084 res = PyBytes_FromStringAndSize(start, s - start + 1);
1085 if (res != NULL)
1086 self->pos += s - start + 1;
1087 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001088 }
1089 if (n == limit) {
1090 res = PyBytes_FromStringAndSize(start, n);
1091 if (res != NULL)
1092 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001093 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001094 }
1095
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001096 if (!ENTER_BUFFERED(self))
1097 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001098
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100 chunks = PyList_New(0);
1101 if (chunks == NULL)
1102 goto end;
1103 if (n > 0) {
1104 res = PyBytes_FromStringAndSize(start, n);
1105 if (res == NULL)
1106 goto end;
1107 if (PyList_Append(chunks, res) < 0) {
1108 Py_CLEAR(res);
1109 goto end;
1110 }
1111 Py_CLEAR(res);
1112 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001113 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001114 if (limit >= 0)
1115 limit -= n;
1116 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001117 if (self->writable) {
1118 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1119 if (r == NULL)
1120 goto end;
1121 Py_DECREF(r);
1122 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001123
1124 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001125 _bufferedreader_reset_buf(self);
1126 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127 if (n == -1)
1128 goto end;
1129 if (n <= 0)
1130 break;
1131 if (limit >= 0 && n > limit)
1132 n = limit;
1133 start = self->buffer;
1134 end = start + n;
1135 s = start;
1136 while (s < end) {
1137 if (*s++ == '\n') {
1138 res = PyBytes_FromStringAndSize(start, s - start);
1139 if (res == NULL)
1140 goto end;
1141 self->pos = s - start;
1142 goto found;
1143 }
1144 }
1145 res = PyBytes_FromStringAndSize(start, n);
1146 if (res == NULL)
1147 goto end;
1148 if (n == limit) {
1149 self->pos = n;
1150 break;
1151 }
1152 if (PyList_Append(chunks, res) < 0) {
1153 Py_CLEAR(res);
1154 goto end;
1155 }
1156 Py_CLEAR(res);
1157 written += n;
1158 if (limit >= 0)
1159 limit -= n;
1160 }
1161found:
1162 if (res != NULL && PyList_Append(chunks, res) < 0) {
1163 Py_CLEAR(res);
1164 goto end;
1165 }
1166 Py_CLEAR(res);
1167 res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1168
1169end:
1170 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001171end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172 Py_XDECREF(chunks);
1173 return res;
1174}
1175
1176static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001177buffered_readline(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001178{
1179 Py_ssize_t limit = -1;
1180
1181 CHECK_INITIALIZED(self)
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001182 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001184 return _buffered_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185}
1186
1187
1188static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001189buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190{
1191 Py_off_t pos;
1192
1193 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001194 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001195 if (pos == -1)
1196 return NULL;
1197 pos -= RAW_OFFSET(self);
1198 /* TODO: sanity check (pos >= 0) */
1199 return PyLong_FromOff_t(pos);
1200}
1201
1202static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001203buffered_seek(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204{
1205 Py_off_t target, n;
1206 int whence = 0;
1207 PyObject *targetobj, *res = NULL;
1208
1209 CHECK_INITIALIZED(self)
1210 if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) {
1211 return NULL;
1212 }
Jesus Cea94363612012-06-22 18:32:07 +02001213
1214 /* Do some error checking instead of trusting OS 'seek()'
1215 ** error detection, just in case.
1216 */
1217 if ((whence < 0 || whence >2)
1218#ifdef SEEK_HOLE
1219 && (whence != SEEK_HOLE)
1220#endif
1221#ifdef SEEK_DATA
1222 && (whence != SEEK_DATA)
1223#endif
1224 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001226 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227 return NULL;
1228 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001229
1230 CHECK_CLOSED(self, "seek of closed file")
1231
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001232 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1233 return NULL;
1234
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001235 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1236 if (target == -1 && PyErr_Occurred())
1237 return NULL;
1238
Jesus Cea94363612012-06-22 18:32:07 +02001239 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1240 buffer. Other whence values must be managed without this optimization.
1241 Some Operating Systems can provide additional values, like
1242 SEEK_HOLE/SEEK_DATA. */
1243 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244 Py_off_t current, avail;
1245 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001246 so as to return quickly if possible. Also, we needn't take the
1247 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001248 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001249 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1250 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251 current = RAW_TELL(self);
1252 avail = READAHEAD(self);
1253 if (avail > 0) {
1254 Py_off_t offset;
1255 if (whence == 0)
1256 offset = target - (current - RAW_OFFSET(self));
1257 else
1258 offset = target;
1259 if (offset >= -self->pos && offset <= avail) {
1260 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001261 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262 }
1263 }
1264 }
1265
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001266 if (!ENTER_BUFFERED(self))
1267 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001268
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001269 /* Fallback: invoke raw seek() method and clear buffer */
1270 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001271 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001272 if (res == NULL)
1273 goto end;
1274 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001275 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001276 }
1277
1278 /* TODO: align on block boundary and read buffer if needed? */
1279 if (whence == 1)
1280 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001281 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 if (n == -1)
1283 goto end;
1284 self->raw_pos = -1;
1285 res = PyLong_FromOff_t(n);
1286 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001287 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288
1289end:
1290 LEAVE_BUFFERED(self)
1291 return res;
1292}
1293
1294static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001295buffered_truncate(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296{
1297 PyObject *pos = Py_None;
1298 PyObject *res = NULL;
1299
1300 CHECK_INITIALIZED(self)
1301 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
1302 return NULL;
1303 }
1304
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001305 if (!ENTER_BUFFERED(self))
1306 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307
1308 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001309 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 if (res == NULL)
1311 goto end;
1312 Py_CLEAR(res);
1313 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1315 if (res == NULL)
1316 goto end;
1317 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001318 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319 PyErr_Clear();
1320
1321end:
1322 LEAVE_BUFFERED(self)
1323 return res;
1324}
1325
1326static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001327buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328{
1329 PyObject *line;
1330 PyTypeObject *tp;
1331
1332 CHECK_INITIALIZED(self);
1333
1334 tp = Py_TYPE(self);
1335 if (tp == &PyBufferedReader_Type ||
1336 tp == &PyBufferedRandom_Type) {
1337 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001338 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339 }
1340 else {
1341 line = PyObject_CallMethodObjArgs((PyObject *)self,
1342 _PyIO_str_readline, NULL);
1343 if (line && !PyBytes_Check(line)) {
1344 PyErr_Format(PyExc_IOError,
1345 "readline() should have returned a bytes object, "
1346 "not '%.200s'", Py_TYPE(line)->tp_name);
1347 Py_DECREF(line);
1348 return NULL;
1349 }
1350 }
1351
1352 if (line == NULL)
1353 return NULL;
1354
1355 if (PyBytes_GET_SIZE(line) == 0) {
1356 /* Reached EOF or would have blocked */
1357 Py_DECREF(line);
1358 return NULL;
1359 }
1360
1361 return line;
1362}
1363
Antoine Pitrou716c4442009-05-23 19:04:03 +00001364static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001365buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001366{
1367 PyObject *nameobj, *res;
1368
Martin v. Löwis767046a2011-10-14 15:35:36 +02001369 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001370 if (nameobj == NULL) {
1371 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1372 PyErr_Clear();
1373 else
1374 return NULL;
1375 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1376 }
1377 else {
1378 res = PyUnicode_FromFormat("<%s name=%R>",
1379 Py_TYPE(self)->tp_name, nameobj);
1380 Py_DECREF(nameobj);
1381 }
1382 return res;
1383}
1384
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001385/*
1386 * class BufferedReader
1387 */
1388
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001389PyDoc_STRVAR(bufferedreader_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001390 "Create a new buffered reader using the given readable raw IO object.");
1391
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001392static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393{
1394 self->read_end = -1;
1395}
1396
1397static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001398bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001399{
1400 char *kwlist[] = {"raw", "buffer_size", NULL};
1401 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
1402 PyObject *raw;
1403
1404 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001405 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001406
1407 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist,
1408 &raw, &buffer_size)) {
1409 return -1;
1410 }
1411
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001412 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001413 return -1;
1414
1415 Py_CLEAR(self->raw);
1416 Py_INCREF(raw);
1417 self->raw = raw;
1418 self->buffer_size = buffer_size;
1419 self->readable = 1;
1420 self->writable = 0;
1421
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001422 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001423 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001424 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001425
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001426 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1427 Py_TYPE(raw) == &PyFileIO_Type);
1428
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001429 self->ok = 1;
1430 return 0;
1431}
1432
1433static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001434_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435{
1436 Py_buffer buf;
1437 PyObject *memobj, *res;
1438 Py_ssize_t n;
1439 /* NOTE: the buffer needn't be released as its object is NULL. */
1440 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1441 return -1;
1442 memobj = PyMemoryView_FromBuffer(&buf);
1443 if (memobj == NULL)
1444 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001445 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1446 occurs so we needn't do it ourselves.
1447 We then retry reading, ignoring the signal if no handler has
1448 raised (see issue #10956).
1449 */
1450 do {
1451 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001452 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001453 Py_DECREF(memobj);
1454 if (res == NULL)
1455 return -1;
1456 if (res == Py_None) {
1457 /* Non-blocking stream would have blocked. Special return code! */
1458 Py_DECREF(res);
1459 return -2;
1460 }
1461 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1462 Py_DECREF(res);
1463 if (n < 0 || n > len) {
1464 PyErr_Format(PyExc_IOError,
1465 "raw readinto() returned invalid length %zd "
1466 "(should have been between 0 and %zd)", n, len);
1467 return -1;
1468 }
1469 if (n > 0 && self->abs_pos != -1)
1470 self->abs_pos += n;
1471 return n;
1472}
1473
1474static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001475_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001476{
1477 Py_ssize_t start, len, n;
1478 if (VALID_READ_BUFFER(self))
1479 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1480 else
1481 start = 0;
1482 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001483 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484 if (n <= 0)
1485 return n;
1486 self->read_end = start + n;
1487 self->raw_pos = start + n;
1488 return n;
1489}
1490
1491static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001492_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001493{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001494 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001495 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001496
1497 /* First copy what we have in the current buffer. */
1498 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1499 if (current_size) {
1500 data = PyBytes_FromStringAndSize(
1501 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001502 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001503 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001504 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001505 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001506 /* We're going past the buffer's bounds, flush it */
1507 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001508 tmp = buffered_flush_and_rewind_unlocked(self);
1509 if (tmp == NULL)
1510 goto cleanup;
1511 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001512 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001513 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001514
1515 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001516 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1517 if (tmp == NULL)
1518 goto cleanup;
1519 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001520 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001521 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001522 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001523 if (tmp == Py_None) {
1524 if (current_size == 0) {
1525 res = Py_None;
1526 goto cleanup;
1527 } else {
1528 res = data;
1529 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001530 }
1531 }
1532 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001533 PyBytes_Concat(&data, tmp);
1534 res = data;
1535 goto cleanup;
1536 }
1537 else {
1538 res = tmp;
1539 goto cleanup;
1540 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001541 }
1542
1543 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001544 if (chunks == NULL)
1545 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001546
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001547 while (1) {
1548 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001549 if (PyList_Append(chunks, data) < 0)
1550 goto cleanup;
1551 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001552 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001554 /* Read until EOF or until read() would block. */
1555 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 if (data == NULL)
1557 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001558 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001559 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001560 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001561 }
1562 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1563 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001564 res = data;
1565 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001566 }
1567 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001568 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1569 res = tmp;
1570 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001571 }
1572 }
1573 current_size += PyBytes_GET_SIZE(data);
1574 if (self->abs_pos != -1)
1575 self->abs_pos += PyBytes_GET_SIZE(data);
1576 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001577cleanup:
1578 /* res is either NULL or a borrowed ref */
1579 Py_XINCREF(res);
1580 Py_XDECREF(data);
1581 Py_XDECREF(tmp);
1582 Py_XDECREF(chunks);
1583 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001584}
1585
1586/* Read n bytes from the buffer if it can, otherwise return None.
1587 This function is simple enough that it can run unlocked. */
1588static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001589_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001590{
1591 Py_ssize_t current_size;
1592
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001593 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1594 if (n <= current_size) {
1595 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001596 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1597 if (res != NULL)
1598 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001599 return res;
1600 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001601 Py_RETURN_NONE;
1602}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001603
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001604/* Generic read function: read from the stream until enough bytes are read,
1605 * or until an EOF occurs or until read() would block.
1606 */
1607static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001608_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609{
1610 PyObject *res = NULL;
1611 Py_ssize_t current_size, remaining, written;
1612 char *out;
1613
1614 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1615 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001616 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001617
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001618 res = PyBytes_FromStringAndSize(NULL, n);
1619 if (res == NULL)
1620 goto error;
1621 out = PyBytes_AS_STRING(res);
1622 remaining = n;
1623 written = 0;
1624 if (current_size > 0) {
1625 memcpy(out, self->buffer + self->pos, current_size);
1626 remaining -= current_size;
1627 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001628 self->pos += current_size;
1629 }
1630 /* Flush the write buffer if necessary */
1631 if (self->writable) {
1632 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1633 if (r == NULL)
1634 goto error;
1635 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001636 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001637 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001638 while (remaining > 0) {
1639 /* We want to read a whole block at the end into buffer.
1640 If we had readv() we could do this in one pass. */
1641 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1642 if (r == 0)
1643 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001644 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001645 if (r == -1)
1646 goto error;
1647 if (r == 0 || r == -2) {
1648 /* EOF occurred or read() would block. */
1649 if (r == 0 || written > 0) {
1650 if (_PyBytes_Resize(&res, written))
1651 goto error;
1652 return res;
1653 }
1654 Py_DECREF(res);
1655 Py_INCREF(Py_None);
1656 return Py_None;
1657 }
1658 remaining -= r;
1659 written += r;
1660 }
1661 assert(remaining <= self->buffer_size);
1662 self->pos = 0;
1663 self->raw_pos = 0;
1664 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001665 /* NOTE: when the read is satisfied, we avoid issuing any additional
1666 reads, which could block indefinitely (e.g. on a socket).
1667 See issue #9550. */
1668 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001669 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001670 if (r == -1)
1671 goto error;
1672 if (r == 0 || r == -2) {
1673 /* EOF occurred or read() would block. */
1674 if (r == 0 || written > 0) {
1675 if (_PyBytes_Resize(&res, written))
1676 goto error;
1677 return res;
1678 }
1679 Py_DECREF(res);
1680 Py_INCREF(Py_None);
1681 return Py_None;
1682 }
1683 if (remaining > r) {
1684 memcpy(out + written, self->buffer + self->pos, r);
1685 written += r;
1686 self->pos += r;
1687 remaining -= r;
1688 }
1689 else if (remaining > 0) {
1690 memcpy(out + written, self->buffer + self->pos, remaining);
1691 written += remaining;
1692 self->pos += remaining;
1693 remaining = 0;
1694 }
1695 if (remaining == 0)
1696 break;
1697 }
1698
1699 return res;
1700
1701error:
1702 Py_XDECREF(res);
1703 return NULL;
1704}
1705
1706static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001707_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001708{
1709 Py_ssize_t have, r;
1710
1711 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1712 /* Constraints:
1713 1. we don't want to advance the file position.
1714 2. we don't want to lose block alignment, so we can't shift the buffer
1715 to make some place.
1716 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1717 */
1718 if (have > 0) {
1719 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1720 }
1721
1722 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001723 _bufferedreader_reset_buf(self);
1724 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001725 if (r == -1)
1726 return NULL;
1727 if (r == -2)
1728 r = 0;
1729 self->pos = 0;
1730 return PyBytes_FromStringAndSize(self->buffer, r);
1731}
1732
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001733static PyMethodDef bufferedreader_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001734 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
1736 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
1737 {"close", (PyCFunction)buffered_close, METH_NOARGS},
1738 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
1739 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
1740 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
1741 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
1742 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00001743 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00001744 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001746 {"read", (PyCFunction)buffered_read, METH_VARARGS},
1747 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
1748 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
Antoine Pitrou3486a982011-05-12 01:57:53 +02001749 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001750 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
1751 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
1752 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
1753 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02001754 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001755 {NULL, NULL}
1756};
1757
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758static PyMemberDef bufferedreader_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00001759 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02001760 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761 {NULL}
1762};
1763
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001764static PyGetSetDef bufferedreader_getset[] = {
1765 {"closed", (getter)buffered_closed_get, NULL, NULL},
1766 {"name", (getter)buffered_name_get, NULL, NULL},
1767 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001768 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769};
1770
1771
1772PyTypeObject PyBufferedReader_Type = {
1773 PyVarObject_HEAD_INIT(NULL, 0)
1774 "_io.BufferedReader", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001775 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001777 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 0, /*tp_print*/
1779 0, /*tp_getattr*/
1780 0, /*tp_setattr*/
1781 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001782 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783 0, /*tp_as_number*/
1784 0, /*tp_as_sequence*/
1785 0, /*tp_as_mapping*/
1786 0, /*tp_hash */
1787 0, /*tp_call*/
1788 0, /*tp_str*/
1789 0, /*tp_getattro*/
1790 0, /*tp_setattro*/
1791 0, /*tp_as_buffer*/
1792 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02001793 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001794 bufferedreader_doc, /* tp_doc */
1795 (traverseproc)buffered_traverse, /* tp_traverse */
1796 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001798 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800 (iternextfunc)buffered_iternext, /* tp_iternext */
1801 bufferedreader_methods, /* tp_methods */
1802 bufferedreader_members, /* tp_members */
1803 bufferedreader_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 0, /* tp_base */
1805 0, /* tp_dict */
1806 0, /* tp_descr_get */
1807 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001808 offsetof(buffered, dict), /* tp_dictoffset */
1809 (initproc)bufferedreader_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 0, /* tp_alloc */
1811 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02001812 0, /* tp_free */
1813 0, /* tp_is_gc */
1814 0, /* tp_bases */
1815 0, /* tp_mro */
1816 0, /* tp_cache */
1817 0, /* tp_subclasses */
1818 0, /* tp_weaklist */
1819 0, /* tp_del */
1820 0, /* tp_version_tag */
1821 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822};
1823
1824
Benjamin Peterson59406a92009-03-26 17:10:29 +00001825
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001826/*
1827 * class BufferedWriter
1828 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001829PyDoc_STRVAR(bufferedwriter_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830 "A buffer for a writeable sequential RawIO object.\n"
1831 "\n"
1832 "The constructor creates a BufferedWriter for the given writeable raw\n"
1833 "stream. If the buffer_size is not given, it defaults to\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02001834 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 );
1836
1837static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001838_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001839{
1840 self->write_pos = 0;
1841 self->write_end = -1;
1842}
1843
1844static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001845bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846{
Florent Xicluna109d5732012-07-07 17:03:22 +02001847 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849 PyObject *raw;
1850
1851 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001852 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853
R David Murray9f10f562013-02-23 22:07:55 -05001854 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02001855 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856 return -1;
1857 }
1858
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001859 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001860 return -1;
1861
1862 Py_CLEAR(self->raw);
1863 Py_INCREF(raw);
1864 self->raw = raw;
1865 self->readable = 0;
1866 self->writable = 1;
1867
1868 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001869 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001870 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001871 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872 self->pos = 0;
1873
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001874 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1875 Py_TYPE(raw) == &PyFileIO_Type);
1876
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001877 self->ok = 1;
1878 return 0;
1879}
1880
1881static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001882_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001883{
1884 Py_buffer buf;
1885 PyObject *memobj, *res;
1886 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001887 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001888 /* NOTE: the buffer needn't be released as its object is NULL. */
1889 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1890 return -1;
1891 memobj = PyMemoryView_FromBuffer(&buf);
1892 if (memobj == NULL)
1893 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001894 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1895 occurs so we needn't do it ourselves.
1896 We then retry writing, ignoring the signal if no handler has
1897 raised (see issue #10956).
1898 */
1899 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001900 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001901 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001902 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001903 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001904 Py_DECREF(memobj);
1905 if (res == NULL)
1906 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001907 if (res == Py_None) {
1908 /* Non-blocking stream would have blocked. Special return code!
1909 Being paranoid we reset errno in case it is changed by code
1910 triggered by a decref. errno is used by _set_BlockingIOError(). */
1911 Py_DECREF(res);
1912 errno = errnum;
1913 return -2;
1914 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1916 Py_DECREF(res);
1917 if (n < 0 || n > len) {
1918 PyErr_Format(PyExc_IOError,
1919 "raw write() returned invalid length %zd "
1920 "(should have been between 0 and %zd)", n, len);
1921 return -1;
1922 }
1923 if (n > 0 && self->abs_pos != -1)
1924 self->abs_pos += n;
1925 return n;
1926}
1927
1928/* `restore_pos` is 1 if we need to restore the raw stream position at
1929 the end, 0 otherwise. */
1930static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001931_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001932{
1933 Py_ssize_t written = 0;
1934 Py_off_t n, rewind;
1935
1936 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1937 goto end;
1938 /* First, rewind */
1939 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1940 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001941 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942 if (n < 0) {
1943 goto error;
1944 }
1945 self->raw_pos -= rewind;
1946 }
1947 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001948 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 self->buffer + self->write_pos,
1950 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1951 Py_off_t, Py_ssize_t));
1952 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001953 goto error;
1954 }
1955 else if (n == -2) {
1956 _set_BlockingIOError("write could not complete without blocking",
1957 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 goto error;
1959 }
1960 self->write_pos += n;
1961 self->raw_pos = self->write_pos;
1962 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001963 /* Partial writes can return successfully when interrupted by a
1964 signal (see write(2)). We must run signal handlers before
1965 blocking another time, possibly indefinitely. */
1966 if (PyErr_CheckSignals() < 0)
1967 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001968 }
1969
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001970 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001971
1972end:
1973 Py_RETURN_NONE;
1974
1975error:
1976 return NULL;
1977}
1978
1979static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001980bufferedwriter_write(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981{
1982 PyObject *res = NULL;
1983 Py_buffer buf;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001984 Py_ssize_t written, avail, remaining;
1985 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001986
1987 CHECK_INITIALIZED(self)
1988 if (!PyArg_ParseTuple(args, "y*:write", &buf)) {
1989 return NULL;
1990 }
1991
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001992 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993 PyErr_SetString(PyExc_ValueError, "write to closed file");
1994 PyBuffer_Release(&buf);
1995 return NULL;
1996 }
1997
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001998 if (!ENTER_BUFFERED(self)) {
1999 PyBuffer_Release(&buf);
2000 return NULL;
2001 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002002
2003 /* Fast path: the data to write can be fully buffered. */
2004 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
2005 self->pos = 0;
2006 self->raw_pos = 0;
2007 }
2008 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
2009 if (buf.len <= avail) {
2010 memcpy(self->buffer + self->pos, buf.buf, buf.len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02002011 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 self->write_pos = self->pos;
2013 }
2014 ADJUST_POSITION(self, self->pos + buf.len);
2015 if (self->pos > self->write_end)
2016 self->write_end = self->pos;
2017 written = buf.len;
2018 goto end;
2019 }
2020
2021 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002022 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002023 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002024 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025 if (w == NULL)
2026 goto error;
2027 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002028 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 /* Make some place by shifting the buffer. */
2030 assert(VALID_WRITE_BUFFER(self));
2031 memmove(self->buffer, self->buffer + self->write_pos,
2032 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2033 Py_off_t, Py_ssize_t));
2034 self->write_end -= self->write_pos;
2035 self->raw_pos -= self->write_pos;
2036 self->pos -= self->write_pos;
2037 self->write_pos = 0;
2038 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2039 Py_off_t, Py_ssize_t);
2040 if (buf.len <= avail) {
2041 /* Everything can be buffered */
2042 PyErr_Clear();
2043 memcpy(self->buffer + self->write_end, buf.buf, buf.len);
2044 self->write_end += buf.len;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002045 self->pos += buf.len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 written = buf.len;
2047 goto end;
2048 }
2049 /* Buffer as much as possible. */
2050 memcpy(self->buffer + self->write_end, buf.buf, avail);
2051 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002052 self->pos += avail;
2053 /* XXX Modifying the existing exception e using the pointer w
2054 will change e.characters_written but not e.args[2].
2055 Therefore we just replace with a new error. */
2056 _set_BlockingIOError("write could not complete without blocking",
2057 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002058 goto error;
2059 }
2060 Py_CLEAR(res);
2061
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002062 /* Adjust the raw stream position if it is away from the logical stream
2063 position. This happens if the read buffer has been filled but not
2064 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2065 the raw stream by itself).
2066 Fixes issue #6629.
2067 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002068 offset = RAW_OFFSET(self);
2069 if (offset != 0) {
2070 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002071 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002072 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002073 }
2074
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075 /* Then write buf itself. At this point the buffer has been emptied. */
2076 remaining = buf.len;
2077 written = 0;
2078 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002079 Py_ssize_t n = _bufferedwriter_raw_write(
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002080 self, (char *) buf.buf + written, buf.len - written);
2081 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002082 goto error;
2083 } else if (n == -2) {
2084 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002085 if (remaining > self->buffer_size) {
2086 /* Can't buffer everything, still buffer as much as possible */
2087 memcpy(self->buffer,
2088 (char *) buf.buf + written, self->buffer_size);
2089 self->raw_pos = 0;
2090 ADJUST_POSITION(self, self->buffer_size);
2091 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002092 written += self->buffer_size;
2093 _set_BlockingIOError("write could not complete without "
2094 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095 goto error;
2096 }
2097 PyErr_Clear();
2098 break;
2099 }
2100 written += n;
2101 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002102 /* Partial writes can return successfully when interrupted by a
2103 signal (see write(2)). We must run signal handlers before
2104 blocking another time, possibly indefinitely. */
2105 if (PyErr_CheckSignals() < 0)
2106 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107 }
2108 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002109 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110 if (remaining > 0) {
2111 memcpy(self->buffer, (char *) buf.buf + written, remaining);
2112 written += remaining;
2113 }
2114 self->write_pos = 0;
2115 /* TODO: sanity check (remaining >= 0) */
2116 self->write_end = remaining;
2117 ADJUST_POSITION(self, remaining);
2118 self->raw_pos = 0;
2119
2120end:
2121 res = PyLong_FromSsize_t(written);
2122
2123error:
2124 LEAVE_BUFFERED(self)
2125 PyBuffer_Release(&buf);
2126 return res;
2127}
2128
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129static PyMethodDef bufferedwriter_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2132 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2133 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2134 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2135 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2136 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2137 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002138 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002139 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002141 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
2142 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2143 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2144 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2145 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002146 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147 {NULL, NULL}
2148};
2149
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002150static PyMemberDef bufferedwriter_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002151 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002152 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 {NULL}
2154};
2155
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002156static PyGetSetDef bufferedwriter_getset[] = {
2157 {"closed", (getter)buffered_closed_get, NULL, NULL},
2158 {"name", (getter)buffered_name_get, NULL, NULL},
2159 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002160 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161};
2162
2163
2164PyTypeObject PyBufferedWriter_Type = {
2165 PyVarObject_HEAD_INIT(NULL, 0)
2166 "_io.BufferedWriter", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002167 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002169 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170 0, /*tp_print*/
2171 0, /*tp_getattr*/
2172 0, /*tp_setattr*/
2173 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002174 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175 0, /*tp_as_number*/
2176 0, /*tp_as_sequence*/
2177 0, /*tp_as_mapping*/
2178 0, /*tp_hash */
2179 0, /*tp_call*/
2180 0, /*tp_str*/
2181 0, /*tp_getattro*/
2182 0, /*tp_setattro*/
2183 0, /*tp_as_buffer*/
2184 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002185 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186 bufferedwriter_doc, /* tp_doc */
2187 (traverseproc)buffered_traverse, /* tp_traverse */
2188 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191 0, /* tp_iter */
2192 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002193 bufferedwriter_methods, /* tp_methods */
2194 bufferedwriter_members, /* tp_members */
2195 bufferedwriter_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002196 0, /* tp_base */
2197 0, /* tp_dict */
2198 0, /* tp_descr_get */
2199 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002200 offsetof(buffered, dict), /* tp_dictoffset */
2201 (initproc)bufferedwriter_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 0, /* tp_alloc */
2203 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002204 0, /* tp_free */
2205 0, /* tp_is_gc */
2206 0, /* tp_bases */
2207 0, /* tp_mro */
2208 0, /* tp_cache */
2209 0, /* tp_subclasses */
2210 0, /* tp_weaklist */
2211 0, /* tp_del */
2212 0, /* tp_version_tag */
2213 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214};
2215
2216
2217
2218/*
2219 * BufferedRWPair
2220 */
2221
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222PyDoc_STRVAR(bufferedrwpair_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223 "A buffered reader and writer object together.\n"
2224 "\n"
2225 "A buffered reader object and buffered writer object put together to\n"
2226 "form a sequential IO object that can read and write. This is typically\n"
2227 "used with a socket or two-way pipe.\n"
2228 "\n"
2229 "reader and writer are RawIOBase objects that are readable and\n"
2230 "writeable respectively. If the buffer_size is omitted it defaults to\n"
Benjamin Peterson59406a92009-03-26 17:10:29 +00002231 "DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232 );
2233
2234/* XXX The usefulness of this (compared to having two separate IO objects) is
2235 * questionable.
2236 */
2237
2238typedef struct {
2239 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002240 buffered *reader;
2241 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242 PyObject *dict;
2243 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002244} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245
2246static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002247bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002248{
2249 PyObject *reader, *writer;
2250 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251
Florent Xicluna109d5732012-07-07 17:03:22 +02002252 if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer,
2253 &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254 return -1;
2255 }
2256
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002257 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002258 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260 return -1;
2261
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002263 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002264 if (self->reader == NULL)
2265 return -1;
2266
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002267 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002268 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002269 if (self->writer == NULL) {
2270 Py_CLEAR(self->reader);
2271 return -1;
2272 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002273
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002274 return 0;
2275}
2276
2277static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002278bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002279{
2280 Py_VISIT(self->dict);
2281 return 0;
2282}
2283
2284static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002285bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286{
2287 Py_CLEAR(self->reader);
2288 Py_CLEAR(self->writer);
2289 Py_CLEAR(self->dict);
2290 return 0;
2291}
2292
2293static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002294bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002295{
2296 _PyObject_GC_UNTRACK(self);
2297 Py_CLEAR(self->reader);
2298 Py_CLEAR(self->writer);
2299 Py_CLEAR(self->dict);
2300 Py_TYPE(self)->tp_free((PyObject *) self);
2301}
2302
2303static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002304_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002306 PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307 PyObject *ret;
2308
2309 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002310 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002311 return NULL;
2312 }
2313
2314 ret = PyObject_CallObject(func, args);
2315 Py_DECREF(func);
2316 return ret;
2317}
2318
2319static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002320bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002321{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002322 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323}
2324
2325static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002326bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002327{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002328 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329}
2330
2331static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002332bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002333{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002334 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002335}
2336
2337static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002338bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002339{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002340 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002341}
2342
2343static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002344bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002345{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002346 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347}
2348
2349static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002350bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002351{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002352 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002353}
2354
2355static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002356bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002357{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002358 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002359}
2360
2361static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002362bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002363{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002364 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002365}
2366
2367static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002368bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002369{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002370 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002371 if (ret == NULL)
2372 return NULL;
2373 Py_DECREF(ret);
2374
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002375 return _forward_call(self->reader, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002376}
2377
2378static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002379bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002380{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002381 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002382
2383 if (ret != Py_False) {
2384 /* either True or exception */
2385 return ret;
2386 }
2387 Py_DECREF(ret);
2388
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002389 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002390}
2391
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002392static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002393bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002394{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002395 if (self->writer == NULL) {
2396 PyErr_SetString(PyExc_RuntimeError,
2397 "the BufferedRWPair object is being garbage-collected");
2398 return NULL;
2399 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002400 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2401}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002402
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002403static PyMethodDef bufferedrwpair_methods[] = {
2404 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2405 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2406 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2407 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002408
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002409 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2410 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002411
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002412 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2413 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002414
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002415 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2416 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002417
Antoine Pitrou243757e2010-11-05 21:15:39 +00002418 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2419
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 {NULL, NULL}
2421};
2422
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002423static PyGetSetDef bufferedrwpair_getset[] = {
2424 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002425 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002426};
2427
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428PyTypeObject PyBufferedRWPair_Type = {
2429 PyVarObject_HEAD_INIT(NULL, 0)
2430 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002431 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002433 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002434 0, /*tp_print*/
2435 0, /*tp_getattr*/
2436 0, /*tp_setattr*/
2437 0, /*tp_compare */
2438 0, /*tp_repr*/
2439 0, /*tp_as_number*/
2440 0, /*tp_as_sequence*/
2441 0, /*tp_as_mapping*/
2442 0, /*tp_hash */
2443 0, /*tp_call*/
2444 0, /*tp_str*/
2445 0, /*tp_getattro*/
2446 0, /*tp_setattro*/
2447 0, /*tp_as_buffer*/
2448 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002449 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002450 bufferedrwpair_doc, /* tp_doc */
2451 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2452 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002453 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002454 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002455 0, /* tp_iter */
2456 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002457 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002460 0, /* tp_base */
2461 0, /* tp_dict */
2462 0, /* tp_descr_get */
2463 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002464 offsetof(rwpair, dict), /* tp_dictoffset */
2465 (initproc)bufferedrwpair_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466 0, /* tp_alloc */
2467 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002468 0, /* tp_free */
2469 0, /* tp_is_gc */
2470 0, /* tp_bases */
2471 0, /* tp_mro */
2472 0, /* tp_cache */
2473 0, /* tp_subclasses */
2474 0, /* tp_weaklist */
2475 0, /* tp_del */
2476 0, /* tp_version_tag */
2477 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002478};
2479
2480
2481
2482/*
2483 * BufferedRandom
2484 */
2485
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002486PyDoc_STRVAR(bufferedrandom_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002487 "A buffered interface to random access streams.\n"
2488 "\n"
2489 "The constructor creates a reader and writer for a seekable stream,\n"
2490 "raw, given in the first argument. If the buffer_size is omitted it\n"
Florent Xicluna109d5732012-07-07 17:03:22 +02002491 "defaults to DEFAULT_BUFFER_SIZE.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002492 );
2493
2494static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002495bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002496{
Florent Xicluna109d5732012-07-07 17:03:22 +02002497 char *kwlist[] = {"raw", "buffer_size", NULL};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002498 Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002499 PyObject *raw;
2500
2501 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002502 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002503
R David Murray9f10f562013-02-23 22:07:55 -05002504 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist,
Florent Xicluna109d5732012-07-07 17:03:22 +02002505 &raw, &buffer_size)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002506 return -1;
2507 }
2508
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002509 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002510 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002511 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002512 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002513 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002514 return -1;
2515
2516 Py_CLEAR(self->raw);
2517 Py_INCREF(raw);
2518 self->raw = raw;
2519 self->buffer_size = buffer_size;
2520 self->readable = 1;
2521 self->writable = 1;
2522
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002523 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002524 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002525 _bufferedreader_reset_buf(self);
2526 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002527 self->pos = 0;
2528
Antoine Pitrou711af3a2009-04-11 15:39:24 +00002529 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2530 Py_TYPE(raw) == &PyFileIO_Type);
2531
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002532 self->ok = 1;
2533 return 0;
2534}
2535
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002538 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2539 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2540 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2541 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2542 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2543 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2544 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002545 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002546 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002547
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002548 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002549
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002550 {"seek", (PyCFunction)buffered_seek, METH_VARARGS},
2551 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2552 {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
2553 {"read", (PyCFunction)buffered_read, METH_VARARGS},
2554 {"read1", (PyCFunction)buffered_read1, METH_VARARGS},
2555 {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS},
2556 {"readline", (PyCFunction)buffered_readline, METH_VARARGS},
2557 {"peek", (PyCFunction)buffered_peek, METH_VARARGS},
2558 {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002559 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560 {NULL, NULL}
2561};
2562
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002563static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002564 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002565 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566 {NULL}
2567};
2568
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002569static PyGetSetDef bufferedrandom_getset[] = {
2570 {"closed", (getter)buffered_closed_get, NULL, NULL},
2571 {"name", (getter)buffered_name_get, NULL, NULL},
2572 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002573 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002574};
2575
2576
2577PyTypeObject PyBufferedRandom_Type = {
2578 PyVarObject_HEAD_INIT(NULL, 0)
2579 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002581 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002582 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002583 0, /*tp_print*/
2584 0, /*tp_getattr*/
2585 0, /*tp_setattr*/
2586 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002587 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002588 0, /*tp_as_number*/
2589 0, /*tp_as_sequence*/
2590 0, /*tp_as_mapping*/
2591 0, /*tp_hash */
2592 0, /*tp_call*/
2593 0, /*tp_str*/
2594 0, /*tp_getattro*/
2595 0, /*tp_setattro*/
2596 0, /*tp_as_buffer*/
2597 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002598 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002599 bufferedrandom_doc, /* tp_doc */
2600 (traverseproc)buffered_traverse, /* tp_traverse */
2601 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002602 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002603 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002604 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002605 (iternextfunc)buffered_iternext, /* tp_iternext */
2606 bufferedrandom_methods, /* tp_methods */
2607 bufferedrandom_members, /* tp_members */
2608 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002609 0, /* tp_base */
2610 0, /*tp_dict*/
2611 0, /* tp_descr_get */
2612 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002613 offsetof(buffered, dict), /*tp_dictoffset*/
2614 (initproc)bufferedrandom_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002615 0, /* tp_alloc */
2616 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002617 0, /* tp_free */
2618 0, /* tp_is_gc */
2619 0, /* tp_bases */
2620 0, /* tp_mro */
2621 0, /* tp_cache */
2622 0, /* tp_subclasses */
2623 0, /* tp_weaklist */
2624 0, /* tp_del */
2625 0, /* tp_version_tag */
2626 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002627};