blob: cb4173e5981fb7273abe63d76a248e799b8c4109 [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
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030016/*[clinic input]
17module _io
18class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24[clinic start generated code]*/
25/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26
27/*[python input]
28class io_ssize_t_converter(CConverter):
29 type = 'Py_ssize_t'
30 converter = '_PyIO_ConvertSsize_t'
31[python start generated code]*/
32/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
33
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020034_Py_IDENTIFIER(close);
35_Py_IDENTIFIER(_dealloc_warn);
36_Py_IDENTIFIER(flush);
37_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020038_Py_IDENTIFIER(mode);
39_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020040_Py_IDENTIFIER(peek);
41_Py_IDENTIFIER(read);
42_Py_IDENTIFIER(read1);
43_Py_IDENTIFIER(readable);
44_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070045_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020046_Py_IDENTIFIER(writable);
47_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020048
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000049/*
50 * BufferedIOBase class, inherits from IOBase.
51 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000052PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000053 "Base class for buffered IO objects.\n"
54 "\n"
55 "The main difference with RawIOBase is that the read() method\n"
56 "supports omitting the size argument, and does not have a default\n"
57 "implementation that defers to readinto().\n"
58 "\n"
59 "In addition, read(), readinto() and write() may raise\n"
60 "BlockingIOError if the underlying raw stream is in non-blocking\n"
61 "mode and not ready; unlike their raw counterparts, they will never\n"
62 "return None.\n"
63 "\n"
64 "A typical implementation should not inherit from a RawIOBase\n"
65 "implementation, but wrap one.\n"
66 );
67
68static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030069_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071 Py_ssize_t len;
72 PyObject *data;
73
Benjamin Petersona96fea02014-06-22 14:17:44 -070074 data = _PyObject_CallMethodId(self,
75 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030076 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030078 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000079
80 if (!PyBytes_Check(data)) {
81 Py_DECREF(data);
82 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030083 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000084 }
85
86 len = Py_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030087 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030088 PyErr_Format(PyExc_ValueError,
89 "read() returned too much data: "
90 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030091 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030092 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030093 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030094 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030095 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000096
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000097 Py_DECREF(data);
98
99 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000100}
101
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300102/*[clinic input]
103_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700104 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300105 /
106[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700107
108static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300109_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700110/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700111{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300112 return _bufferediobase_readinto_generic(self, buffer, 0);
113}
114
115/*[clinic input]
116_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700117 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300118 /
119[clinic start generated code]*/
120
121static PyObject *
122_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700123/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300124{
125 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700126}
127
128static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000129bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000130{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100131 _PyIO_State *state = IO_STATE();
132 if (state != NULL)
133 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000134 return NULL;
135}
136
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300137/*[clinic input]
138_io._BufferedIOBase.detach
139
140Disconnect this buffer from its underlying raw stream and return it.
141
142After the raw stream has been detached, the buffer is in an unusable
143state.
144[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000145
146static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300147_io__BufferedIOBase_detach_impl(PyObject *self)
148/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000149{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000151}
152
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000153PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000154 "Read and return up to n bytes.\n"
155 "\n"
156 "If the argument is omitted, None, or negative, reads and\n"
157 "returns all data until EOF.\n"
158 "\n"
159 "If the argument is positive, and the underlying raw stream is\n"
160 "not 'interactive', multiple raw reads may be issued to satisfy\n"
161 "the byte count (unless EOF is reached first). But for\n"
162 "interactive raw streams (as well as sockets and pipes), at most\n"
163 "one raw read will be issued, and a short result does not imply\n"
164 "that EOF is imminent.\n"
165 "\n"
166 "Returns an empty bytes object on EOF.\n"
167 "\n"
168 "Returns None if the underlying raw stream was open in non-blocking\n"
169 "mode and no data is available at the moment.\n");
170
171static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000172bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000173{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000174 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000175}
176
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000177PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000178 "Read and return up to n bytes, with at most one read() call\n"
179 "to the underlying raw stream. A short result does not imply\n"
180 "that EOF is imminent.\n"
181 "\n"
182 "Returns an empty bytes object on EOF.\n");
183
184static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000185bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000186{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000187 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188}
189
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000190PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000191 "Write the given buffer to the IO stream.\n"
192 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000193 "Returns the number of bytes written, which is always the length of b\n"
194 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 "\n"
196 "Raises BlockingIOError if the buffer is full and the\n"
197 "underlying raw stream cannot accept more data at the moment.\n");
198
199static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000200bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000201{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000202 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000203}
204
205
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206typedef struct {
207 PyObject_HEAD
208
209 PyObject *raw;
210 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000211 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212 int readable;
213 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200214 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200215
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000216 /* True if this is a vanilla Buffered object (rather than a user derived
217 class) *and* the raw stream is a vanilla FileIO object. */
218 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000219
220 /* Absolute position inside the raw stream (-1 if unknown). */
221 Py_off_t abs_pos;
222
223 /* A static buffer of size `buffer_size` */
224 char *buffer;
225 /* Current logical position in the buffer. */
226 Py_off_t pos;
227 /* Position of the raw stream in the buffer. */
228 Py_off_t raw_pos;
229
230 /* Just after the last buffered byte in the buffer, or -1 if the buffer
231 isn't ready for reading. */
232 Py_off_t read_end;
233
234 /* Just after the last byte actually written */
235 Py_off_t write_pos;
236 /* Just after the last byte waiting to be written, or -1 if the buffer
237 isn't ready for writing. */
238 Py_off_t write_end;
239
Georg Brandldfd73442009-04-05 11:47:34 +0000240#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000241 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000242 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000243#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000244
245 Py_ssize_t buffer_size;
246 Py_ssize_t buffer_mask;
247
248 PyObject *dict;
249 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000250} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251
252/*
253 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200254
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000255 * BufferedReader, BufferedWriter and BufferedRandom try to share most
256 methods (this is helped by the members `readable` and `writable`, which
257 are initialized in the respective constructors)
258 * They also share a single buffer for reading and writing. This enables
259 interleaved reads and writes without flushing. It also makes the logic
260 a bit trickier to get right.
261 * The absolute position of the raw stream is cached, if possible, in the
262 `abs_pos` member. It must be updated every time an operation is done
263 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000264 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000265 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000266 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
267 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268
269 NOTE: we should try to maintain block alignment of reads and writes to the
270 raw stream (according to the buffer size), but for now it is only done
271 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200272
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000273*/
274
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000275/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000276
Georg Brandldfd73442009-04-05 11:47:34 +0000277#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000278
279static int
280_enter_buffered_busy(buffered *self)
281{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200282 int relax_locking;
283 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000284 if (self->owner == PyThread_get_thread_ident()) {
285 PyErr_Format(PyExc_RuntimeError,
286 "reentrant call inside %R", self);
287 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000288 }
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200289 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000290 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200291 if (!relax_locking)
292 st = PyThread_acquire_lock(self->lock, 1);
293 else {
294 /* When finalizing, we don't want a deadlock to happen with daemon
295 * threads abruptly shut down while they owned the lock.
296 * Therefore, only wait for a grace period (1 s.).
297 * Note that non-daemon threads have already exited here, so this
298 * shouldn't affect carefully written threaded I/O code.
299 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700300 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200301 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000302 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200303 if (relax_locking && st != PY_LOCK_ACQUIRED) {
304 PyObject *msgobj = PyUnicode_FromFormat(
305 "could not acquire lock for %A at interpreter "
306 "shutdown, possibly due to daemon threads",
307 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200308 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200309 Py_FatalError(msg);
310 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000311 return 1;
312}
313
314#define ENTER_BUFFERED(self) \
315 ( (PyThread_acquire_lock(self->lock, 0) ? \
316 1 : _enter_buffered_busy(self)) \
317 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000318
319#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000320 do { \
321 self->owner = 0; \
322 PyThread_release_lock(self->lock); \
323 } while(0);
324
Georg Brandldfd73442009-04-05 11:47:34 +0000325#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000326#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000327#define LEAVE_BUFFERED(self)
328#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000329
330#define CHECK_INITIALIZED(self) \
331 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000332 if (self->detached) { \
333 PyErr_SetString(PyExc_ValueError, \
334 "raw stream has been detached"); \
335 } else { \
336 PyErr_SetString(PyExc_ValueError, \
337 "I/O operation on uninitialized object"); \
338 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 return NULL; \
340 }
341
342#define CHECK_INITIALIZED_INT(self) \
343 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000344 if (self->detached) { \
345 PyErr_SetString(PyExc_ValueError, \
346 "raw stream has been detached"); \
347 } else { \
348 PyErr_SetString(PyExc_ValueError, \
349 "I/O operation on uninitialized object"); \
350 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000351 return -1; \
352 }
353
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000354#define IS_CLOSED(self) \
355 (self->fast_closed_checks \
356 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000357 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000358
359#define CHECK_CLOSED(self, error_msg) \
360 if (IS_CLOSED(self)) { \
361 PyErr_SetString(PyExc_ValueError, error_msg); \
362 return NULL; \
363 }
364
365
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000366#define VALID_READ_BUFFER(self) \
367 (self->readable && self->read_end != -1)
368
369#define VALID_WRITE_BUFFER(self) \
370 (self->writable && self->write_end != -1)
371
372#define ADJUST_POSITION(self, _new_pos) \
373 do { \
374 self->pos = _new_pos; \
375 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
376 self->read_end = self->pos; \
377 } while(0)
378
379#define READAHEAD(self) \
380 ((self->readable && VALID_READ_BUFFER(self)) \
381 ? (self->read_end - self->pos) : 0)
382
383#define RAW_OFFSET(self) \
384 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
385 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
386
387#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000388 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000389
390#define MINUS_LAST_BLOCK(self, size) \
391 (self->buffer_mask ? \
392 (size & ~self->buffer_mask) : \
393 (self->buffer_size * (size / self->buffer_size)))
394
395
396static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000397buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000398{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200399 self->finalizing = 1;
400 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000401 return;
402 _PyObject_GC_UNTRACK(self);
403 self->ok = 0;
404 if (self->weakreflist != NULL)
405 PyObject_ClearWeakRefs((PyObject *)self);
406 Py_CLEAR(self->raw);
407 if (self->buffer) {
408 PyMem_Free(self->buffer);
409 self->buffer = NULL;
410 }
Georg Brandldfd73442009-04-05 11:47:34 +0000411#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000412 if (self->lock) {
413 PyThread_free_lock(self->lock);
414 self->lock = NULL;
415 }
Georg Brandldfd73442009-04-05 11:47:34 +0000416#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000417 Py_CLEAR(self->dict);
418 Py_TYPE(self)->tp_free((PyObject *)self);
419}
420
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200421static PyObject *
422buffered_sizeof(buffered *self, void *unused)
423{
424 Py_ssize_t res;
425
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200426 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200427 if (self->buffer)
428 res += self->buffer_size;
429 return PyLong_FromSsize_t(res);
430}
431
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000432static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000433buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000434{
435 Py_VISIT(self->raw);
436 Py_VISIT(self->dict);
437 return 0;
438}
439
440static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000441buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000442{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000443 self->ok = 0;
444 Py_CLEAR(self->raw);
445 Py_CLEAR(self->dict);
446 return 0;
447}
448
Antoine Pitroue033e062010-10-29 10:38:18 +0000449/* Because this can call arbitrary code, it shouldn't be called when
450 the refcount is 0 (that is, not directly from tp_dealloc unless
451 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000452static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000453buffered_dealloc_warn(buffered *self, PyObject *source)
454{
455 if (self->ok && self->raw) {
456 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100457 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
458 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000459 if (r)
460 Py_DECREF(r);
461 else
462 PyErr_Clear();
463 }
464 Py_RETURN_NONE;
465}
466
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000467/*
468 * _BufferedIOMixin methods
469 * This is not a class, just a collection of methods that will be reused
470 * by BufferedReader and BufferedWriter
471 */
472
473/* Flush and close */
474
475static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000476buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000477{
478 CHECK_INITIALIZED(self)
479 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
480}
481
482static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000483buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000484{
485 int closed;
486 PyObject *res;
487 CHECK_INITIALIZED_INT(self)
488 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
489 if (res == NULL)
490 return -1;
491 closed = PyObject_IsTrue(res);
492 Py_DECREF(res);
493 return closed;
494}
495
496static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498{
499 CHECK_INITIALIZED(self)
500 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
501}
502
503static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000504buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505{
Benjamin Peterson68623612012-12-20 11:53:11 -0600506 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507 int r;
508
509 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000510 if (!ENTER_BUFFERED(self))
511 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000513 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000514 if (r < 0)
515 goto end;
516 if (r > 0) {
517 res = Py_None;
518 Py_INCREF(res);
519 goto end;
520 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000521
Antoine Pitrou796564c2013-07-30 19:59:21 +0200522 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000523 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
524 if (r)
525 Py_DECREF(r);
526 else
527 PyErr_Clear();
528 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000529 /* flush() will most probably re-take the lock, so drop it first */
530 LEAVE_BUFFERED(self)
531 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000532 if (!ENTER_BUFFERED(self))
533 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600534 if (res == NULL)
535 PyErr_Fetch(&exc, &val, &tb);
536 else
537 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000538
539 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
540
Jesus Ceadc469452012-10-04 12:37:56 +0200541 if (self->buffer) {
542 PyMem_Free(self->buffer);
543 self->buffer = NULL;
544 }
545
Benjamin Peterson68623612012-12-20 11:53:11 -0600546 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300547 _PyErr_ChainExceptions(exc, val, tb);
548 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600549 }
550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551end:
552 LEAVE_BUFFERED(self)
553 return res;
554}
555
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000556/* detach */
557
558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000560{
561 PyObject *raw, *res;
562 CHECK_INITIALIZED(self)
563 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
564 if (res == NULL)
565 return NULL;
566 Py_DECREF(res);
567 raw = self->raw;
568 self->raw = NULL;
569 self->detached = 1;
570 self->ok = 0;
571 return raw;
572}
573
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574/* Inquiries */
575
576static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000577buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578{
579 CHECK_INITIALIZED(self)
580 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
581}
582
583static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 CHECK_INITIALIZED(self)
587 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
588}
589
590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000591buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
594 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
595}
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200601 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200608 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609}
610
611/* Lower-level APIs */
612
613static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615{
616 CHECK_INITIALIZED(self)
617 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
618}
619
620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000621buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622{
623 CHECK_INITIALIZED(self)
624 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
625}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626
Antoine Pitrou243757e2010-11-05 21:15:39 +0000627/* Serialization */
628
629static PyObject *
630buffered_getstate(buffered *self, PyObject *args)
631{
632 PyErr_Format(PyExc_TypeError,
633 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
634 return NULL;
635}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000636
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637/* Forward decls */
638static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100639_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000645_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200647_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000650static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000652static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200654static Py_ssize_t
655_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
657/*
658 * Helpers
659 */
660
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100661/* Sets the current error to BlockingIOError */
662static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200663_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100664{
665 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200666 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100667 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
668 errno, msg, written);
669 if (err)
670 PyErr_SetObject(PyExc_BlockingIOError, err);
671 Py_XDECREF(err);
672}
673
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674/* Returns the address of the `written` member if a BlockingIOError was
675 raised, NULL otherwise. The error is always re-raised. */
676static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000677_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678{
679 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200680 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681
682 PyErr_Fetch(&t, &v, &tb);
683 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
684 PyErr_Restore(t, v, tb);
685 return NULL;
686 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200687 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688 /* TODO: sanity check (err->written >= 0) */
689 PyErr_Restore(t, v, tb);
690 return &err->written;
691}
692
693static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000694_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000697 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
699 if (res == NULL)
700 return -1;
701 n = PyNumber_AsOff_t(res, PyExc_ValueError);
702 Py_DECREF(res);
703 if (n < 0) {
704 if (!PyErr_Occurred())
705 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000706 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200707 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708 return -1;
709 }
710 self->abs_pos = n;
711 return n;
712}
713
714static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000715_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716{
717 PyObject *res, *posobj, *whenceobj;
718 Py_off_t n;
719
720 posobj = PyLong_FromOff_t(target);
721 if (posobj == NULL)
722 return -1;
723 whenceobj = PyLong_FromLong(whence);
724 if (whenceobj == NULL) {
725 Py_DECREF(posobj);
726 return -1;
727 }
728 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
729 posobj, whenceobj, NULL);
730 Py_DECREF(posobj);
731 Py_DECREF(whenceobj);
732 if (res == NULL)
733 return -1;
734 n = PyNumber_AsOff_t(res, PyExc_ValueError);
735 Py_DECREF(res);
736 if (n < 0) {
737 if (!PyErr_Occurred())
738 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000739 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200740 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 return -1;
742 }
743 self->abs_pos = n;
744 return n;
745}
746
747static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000748_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000749{
750 Py_ssize_t n;
751 if (self->buffer_size <= 0) {
752 PyErr_SetString(PyExc_ValueError,
753 "buffer size must be strictly positive");
754 return -1;
755 }
756 if (self->buffer)
757 PyMem_Free(self->buffer);
758 self->buffer = PyMem_Malloc(self->buffer_size);
759 if (self->buffer == NULL) {
760 PyErr_NoMemory();
761 return -1;
762 }
Georg Brandldfd73442009-04-05 11:47:34 +0000763#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000764 if (self->lock)
765 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766 self->lock = PyThread_allocate_lock();
767 if (self->lock == NULL) {
768 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
769 return -1;
770 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000771 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000772#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773 /* Find out whether buffer_size is a power of 2 */
774 /* XXX is this optimization useful? */
775 for (n = self->buffer_size - 1; n & 1; n >>= 1)
776 ;
777 if (n == 0)
778 self->buffer_mask = self->buffer_size - 1;
779 else
780 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000781 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000782 PyErr_Clear();
783 return 0;
784}
785
Antoine Pitrou707ce822011-02-25 21:24:11 +0000786/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
787 clears the error indicator), 0 otherwise.
788 Should only be called when PyErr_Occurred() is true.
789*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700790int
791_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000792{
793 static PyObject *eintr_int = NULL;
794 PyObject *typ, *val, *tb;
795 PyEnvironmentErrorObject *env_err;
796
797 if (eintr_int == NULL) {
798 eintr_int = PyLong_FromLong(EINTR);
799 assert(eintr_int != NULL);
800 }
801 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
802 return 0;
803 PyErr_Fetch(&typ, &val, &tb);
804 PyErr_NormalizeException(&typ, &val, &tb);
805 env_err = (PyEnvironmentErrorObject *) val;
806 assert(env_err != NULL);
807 if (env_err->myerrno != NULL &&
808 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
809 Py_DECREF(typ);
810 Py_DECREF(val);
811 Py_XDECREF(tb);
812 return 1;
813 }
814 /* This silences any error set by PyObject_RichCompareBool() */
815 PyErr_Restore(typ, val, tb);
816 return 0;
817}
818
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819/*
820 * Shared methods and wrappers
821 */
822
823static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200824buffered_flush_and_rewind_unlocked(buffered *self)
825{
826 PyObject *res;
827
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100828 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200829 if (res == NULL)
830 return NULL;
831 Py_DECREF(res);
832
833 if (self->readable) {
834 /* Rewind the raw stream so that its position corresponds to
835 the current logical position. */
836 Py_off_t n;
837 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
838 _bufferedreader_reset_buf(self);
839 if (n == -1)
840 return NULL;
841 }
842 Py_RETURN_NONE;
843}
844
845static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000846buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000847{
848 PyObject *res;
849
850 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000851 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000853 if (!ENTER_BUFFERED(self))
854 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200855 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000856 LEAVE_BUFFERED(self)
857
858 return res;
859}
860
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300861/*[clinic input]
862_io._Buffered.peek
863 size: Py_ssize_t = 0
864 /
865
866[clinic start generated code]*/
867
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300869_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
870/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000872 PyObject *res = NULL;
873
874 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300875 CHECK_CLOSED(self, "peek of closed file")
876
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000877 if (!ENTER_BUFFERED(self))
878 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000879
880 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200881 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882 if (res == NULL)
883 goto end;
884 Py_CLEAR(res);
885 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200886 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887
888end:
889 LEAVE_BUFFERED(self)
890 return res;
891}
892
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300893/*[clinic input]
894_io._Buffered.read
895 size as n: io_ssize_t = -1
896 /
897[clinic start generated code]*/
898
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300900_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
901/*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903 PyObject *res;
904
905 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000906 if (n < -1) {
907 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000908 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909 return NULL;
910 }
911
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000912 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000914 if (n == -1) {
915 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000916 if (!ENTER_BUFFERED(self))
917 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000918 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000919 }
920 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000921 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200922 if (res != Py_None)
923 return res;
924 Py_DECREF(res);
925 if (!ENTER_BUFFERED(self))
926 return NULL;
927 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000928 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929
Antoine Pitroue05565e2011-08-20 14:39:23 +0200930 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931 return res;
932}
933
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300934/*[clinic input]
935_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000936 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300937 /
938[clinic start generated code]*/
939
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300941_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000942/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300944 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945 PyObject *res = NULL;
946
947 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000949 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300951
952 CHECK_CLOSED(self, "read of closed file")
953
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954 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 *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300989_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200991 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 PyObject *res = NULL;
993
994 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
997 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300998 if (n >= buffer->len) {
999 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1000 self->pos += buffer->len;
1001 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001003 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001004 self->pos += n;
1005 written = n;
1006 }
1007
1008 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001009 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001010
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001011 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001012 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001013 if (res == NULL)
1014 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001015 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001016 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001017
1018 _bufferedreader_reset_buf(self);
1019 self->pos = 0;
1020
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001021 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022 remaining > 0;
1023 written += n, remaining -= n) {
1024 /* If remaining bytes is larger than internal buffer size, copy
1025 * directly into caller's buffer. */
1026 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001027 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001028 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001029 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001030
1031 /* In readinto1 mode, we do not want to fill the internal
1032 buffer if we already have some data to return */
1033 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001034 n = _bufferedreader_fill_buffer(self);
1035 if (n > 0) {
1036 if (n > remaining)
1037 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001038 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001039 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001040 self->pos += n;
1041 continue; /* short circuit */
1042 }
1043 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001044 else
1045 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001046
Antoine Pitrou3486a982011-05-12 01:57:53 +02001047 if (n == 0 || (n == -2 && written > 0))
1048 break;
1049 if (n < 0) {
1050 if (n == -2) {
1051 Py_INCREF(Py_None);
1052 res = Py_None;
1053 }
1054 goto end;
1055 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001056
Benjamin Petersona96fea02014-06-22 14:17:44 -07001057 /* At most one read in readinto1 mode */
1058 if (readinto1) {
1059 written += n;
1060 break;
1061 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001062 }
1063 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001064
1065end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001066 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067 return res;
1068}
1069
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001070/*[clinic input]
1071_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001072 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001073 /
1074[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001075
1076static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001077_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001078/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001079{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001080 return _buffered_readinto_generic(self, buffer, 0);
1081}
1082
1083/*[clinic input]
1084_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001085 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001086 /
1087[clinic start generated code]*/
1088
1089static PyObject *
1090_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001091/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001092{
1093 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001094}
1095
1096
1097static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001098_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099{
1100 PyObject *res = NULL;
1101 PyObject *chunks = NULL;
1102 Py_ssize_t n, written = 0;
1103 const char *start, *s, *end;
1104
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001105 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001107 /* First, try to find a line in the buffer. This can run unlocked because
1108 the calls to the C API are simple enough that they can't trigger
1109 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001110 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1111 if (limit >= 0 && n > limit)
1112 n = limit;
1113 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001114 s = memchr(start, '\n', n);
1115 if (s != NULL) {
1116 res = PyBytes_FromStringAndSize(start, s - start + 1);
1117 if (res != NULL)
1118 self->pos += s - start + 1;
1119 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001120 }
1121 if (n == limit) {
1122 res = PyBytes_FromStringAndSize(start, n);
1123 if (res != NULL)
1124 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001125 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126 }
1127
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001128 if (!ENTER_BUFFERED(self))
1129 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001130
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001131 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132 chunks = PyList_New(0);
1133 if (chunks == NULL)
1134 goto end;
1135 if (n > 0) {
1136 res = PyBytes_FromStringAndSize(start, n);
1137 if (res == NULL)
1138 goto end;
1139 if (PyList_Append(chunks, res) < 0) {
1140 Py_CLEAR(res);
1141 goto end;
1142 }
1143 Py_CLEAR(res);
1144 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001145 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001146 if (limit >= 0)
1147 limit -= n;
1148 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001149 if (self->writable) {
1150 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1151 if (r == NULL)
1152 goto end;
1153 Py_DECREF(r);
1154 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001155
1156 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001157 _bufferedreader_reset_buf(self);
1158 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001159 if (n == -1)
1160 goto end;
1161 if (n <= 0)
1162 break;
1163 if (limit >= 0 && n > limit)
1164 n = limit;
1165 start = self->buffer;
1166 end = start + n;
1167 s = start;
1168 while (s < end) {
1169 if (*s++ == '\n') {
1170 res = PyBytes_FromStringAndSize(start, s - start);
1171 if (res == NULL)
1172 goto end;
1173 self->pos = s - start;
1174 goto found;
1175 }
1176 }
1177 res = PyBytes_FromStringAndSize(start, n);
1178 if (res == NULL)
1179 goto end;
1180 if (n == limit) {
1181 self->pos = n;
1182 break;
1183 }
1184 if (PyList_Append(chunks, res) < 0) {
1185 Py_CLEAR(res);
1186 goto end;
1187 }
1188 Py_CLEAR(res);
1189 written += n;
1190 if (limit >= 0)
1191 limit -= n;
1192 }
1193found:
1194 if (res != NULL && PyList_Append(chunks, res) < 0) {
1195 Py_CLEAR(res);
1196 goto end;
1197 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001198 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199
1200end:
1201 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001202end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001203 Py_XDECREF(chunks);
1204 return res;
1205}
1206
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001207/*[clinic input]
1208_io._Buffered.readline
1209 size: io_ssize_t = -1
1210 /
1211[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001212
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001213static PyObject *
1214_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
1215/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
1216{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001218 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219}
1220
1221
1222static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001223buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001224{
1225 Py_off_t pos;
1226
1227 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001228 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001229 if (pos == -1)
1230 return NULL;
1231 pos -= RAW_OFFSET(self);
1232 /* TODO: sanity check (pos >= 0) */
1233 return PyLong_FromOff_t(pos);
1234}
1235
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001236/*[clinic input]
1237_io._Buffered.seek
1238 target as targetobj: object
1239 whence: int = 0
1240 /
1241[clinic start generated code]*/
1242
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001244_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1245/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246{
1247 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001248 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249
1250 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001251
1252 /* Do some error checking instead of trusting OS 'seek()'
1253 ** error detection, just in case.
1254 */
1255 if ((whence < 0 || whence >2)
1256#ifdef SEEK_HOLE
1257 && (whence != SEEK_HOLE)
1258#endif
1259#ifdef SEEK_DATA
1260 && (whence != SEEK_DATA)
1261#endif
1262 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001264 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265 return NULL;
1266 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001267
1268 CHECK_CLOSED(self, "seek of closed file")
1269
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001270 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1271 return NULL;
1272
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1274 if (target == -1 && PyErr_Occurred())
1275 return NULL;
1276
Jesus Cea94363612012-06-22 18:32:07 +02001277 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1278 buffer. Other whence values must be managed without this optimization.
1279 Some Operating Systems can provide additional values, like
1280 SEEK_HOLE/SEEK_DATA. */
1281 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 Py_off_t current, avail;
1283 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001284 so as to return quickly if possible. Also, we needn't take the
1285 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001287 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1288 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 current = RAW_TELL(self);
1290 avail = READAHEAD(self);
1291 if (avail > 0) {
1292 Py_off_t offset;
1293 if (whence == 0)
1294 offset = target - (current - RAW_OFFSET(self));
1295 else
1296 offset = target;
1297 if (offset >= -self->pos && offset <= avail) {
1298 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001299 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300 }
1301 }
1302 }
1303
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001304 if (!ENTER_BUFFERED(self))
1305 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001306
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307 /* Fallback: invoke raw seek() method and clear buffer */
1308 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001309 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 if (res == NULL)
1311 goto end;
1312 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001313 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 }
1315
1316 /* TODO: align on block boundary and read buffer if needed? */
1317 if (whence == 1)
1318 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001319 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320 if (n == -1)
1321 goto end;
1322 self->raw_pos = -1;
1323 res = PyLong_FromOff_t(n);
1324 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001325 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001326
1327end:
1328 LEAVE_BUFFERED(self)
1329 return res;
1330}
1331
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001332/*[clinic input]
1333_io._Buffered.truncate
1334 pos: object = None
1335 /
1336[clinic start generated code]*/
1337
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001338static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001339_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1340/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001342 PyObject *res = NULL;
1343
1344 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001345 if (!ENTER_BUFFERED(self))
1346 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001347
1348 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001349 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350 if (res == NULL)
1351 goto end;
1352 Py_CLEAR(res);
1353 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001354 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1355 if (res == NULL)
1356 goto end;
1357 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001358 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359 PyErr_Clear();
1360
1361end:
1362 LEAVE_BUFFERED(self)
1363 return res;
1364}
1365
1366static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001367buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001368{
1369 PyObject *line;
1370 PyTypeObject *tp;
1371
1372 CHECK_INITIALIZED(self);
1373
1374 tp = Py_TYPE(self);
1375 if (tp == &PyBufferedReader_Type ||
1376 tp == &PyBufferedRandom_Type) {
1377 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001378 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001379 }
1380 else {
1381 line = PyObject_CallMethodObjArgs((PyObject *)self,
1382 _PyIO_str_readline, NULL);
1383 if (line && !PyBytes_Check(line)) {
1384 PyErr_Format(PyExc_IOError,
1385 "readline() should have returned a bytes object, "
1386 "not '%.200s'", Py_TYPE(line)->tp_name);
1387 Py_DECREF(line);
1388 return NULL;
1389 }
1390 }
1391
1392 if (line == NULL)
1393 return NULL;
1394
1395 if (PyBytes_GET_SIZE(line) == 0) {
1396 /* Reached EOF or would have blocked */
1397 Py_DECREF(line);
1398 return NULL;
1399 }
1400
1401 return line;
1402}
1403
Antoine Pitrou716c4442009-05-23 19:04:03 +00001404static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001405buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001406{
1407 PyObject *nameobj, *res;
1408
Martin v. Löwis767046a2011-10-14 15:35:36 +02001409 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001410 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001411 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001412 PyErr_Clear();
1413 else
1414 return NULL;
1415 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1416 }
1417 else {
1418 res = PyUnicode_FromFormat("<%s name=%R>",
1419 Py_TYPE(self)->tp_name, nameobj);
1420 Py_DECREF(nameobj);
1421 }
1422 return res;
1423}
1424
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001425/*
1426 * class BufferedReader
1427 */
1428
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001429static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001430{
1431 self->read_end = -1;
1432}
1433
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001434/*[clinic input]
1435_io.BufferedReader.__init__
1436 raw: object
1437 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001439Create a new buffered reader using the given readable raw IO object.
1440[clinic start generated code]*/
1441
1442static int
1443_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1444 Py_ssize_t buffer_size)
1445/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1446{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001447 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001448 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001449
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001450 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001451 return -1;
1452
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001453 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001454 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001455 self->buffer_size = buffer_size;
1456 self->readable = 1;
1457 self->writable = 0;
1458
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001459 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001460 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001461 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001463 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1464 Py_TYPE(raw) == &PyFileIO_Type);
1465
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 self->ok = 1;
1467 return 0;
1468}
1469
1470static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001471_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001472{
1473 Py_buffer buf;
1474 PyObject *memobj, *res;
1475 Py_ssize_t n;
1476 /* NOTE: the buffer needn't be released as its object is NULL. */
1477 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1478 return -1;
1479 memobj = PyMemoryView_FromBuffer(&buf);
1480 if (memobj == NULL)
1481 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001482 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1483 occurs so we needn't do it ourselves.
1484 We then retry reading, ignoring the signal if no handler has
1485 raised (see issue #10956).
1486 */
1487 do {
1488 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001489 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001490 Py_DECREF(memobj);
1491 if (res == NULL)
1492 return -1;
1493 if (res == Py_None) {
1494 /* Non-blocking stream would have blocked. Special return code! */
1495 Py_DECREF(res);
1496 return -2;
1497 }
1498 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1499 Py_DECREF(res);
1500 if (n < 0 || n > len) {
1501 PyErr_Format(PyExc_IOError,
1502 "raw readinto() returned invalid length %zd "
1503 "(should have been between 0 and %zd)", n, len);
1504 return -1;
1505 }
1506 if (n > 0 && self->abs_pos != -1)
1507 self->abs_pos += n;
1508 return n;
1509}
1510
1511static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001512_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001513{
1514 Py_ssize_t start, len, n;
1515 if (VALID_READ_BUFFER(self))
1516 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1517 else
1518 start = 0;
1519 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001520 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001521 if (n <= 0)
1522 return n;
1523 self->read_end = start + n;
1524 self->raw_pos = start + n;
1525 return n;
1526}
1527
1528static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001529_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001530{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001531 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001532 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001533
1534 /* First copy what we have in the current buffer. */
1535 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1536 if (current_size) {
1537 data = PyBytes_FromStringAndSize(
1538 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001539 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001540 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001541 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001542 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001543 /* We're going past the buffer's bounds, flush it */
1544 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001545 tmp = buffered_flush_and_rewind_unlocked(self);
1546 if (tmp == NULL)
1547 goto cleanup;
1548 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001549 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001550 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001551
1552 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001553 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1554 if (tmp == NULL)
1555 goto cleanup;
1556 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001557 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001558 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001559 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001560 if (tmp == Py_None) {
1561 if (current_size == 0) {
1562 res = Py_None;
1563 goto cleanup;
1564 } else {
1565 res = data;
1566 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001567 }
1568 }
1569 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001570 PyBytes_Concat(&data, tmp);
1571 res = data;
1572 goto cleanup;
1573 }
1574 else {
1575 res = tmp;
1576 goto cleanup;
1577 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001578 }
1579
1580 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001581 if (chunks == NULL)
1582 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001583
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001584 while (1) {
1585 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001586 if (PyList_Append(chunks, data) < 0)
1587 goto cleanup;
1588 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001589 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001590
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591 /* Read until EOF or until read() would block. */
1592 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001593 if (data == NULL)
1594 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001596 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001597 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001598 }
1599 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1600 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001601 res = data;
1602 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001603 }
1604 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001605 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1606 res = tmp;
1607 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608 }
1609 }
1610 current_size += PyBytes_GET_SIZE(data);
1611 if (self->abs_pos != -1)
1612 self->abs_pos += PyBytes_GET_SIZE(data);
1613 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001614cleanup:
1615 /* res is either NULL or a borrowed ref */
1616 Py_XINCREF(res);
1617 Py_XDECREF(data);
1618 Py_XDECREF(tmp);
1619 Py_XDECREF(chunks);
1620 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001621}
1622
1623/* Read n bytes from the buffer if it can, otherwise return None.
1624 This function is simple enough that it can run unlocked. */
1625static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001626_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001627{
1628 Py_ssize_t current_size;
1629
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1631 if (n <= current_size) {
1632 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001633 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1634 if (res != NULL)
1635 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001636 return res;
1637 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001638 Py_RETURN_NONE;
1639}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001640
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001641/* Generic read function: read from the stream until enough bytes are read,
1642 * or until an EOF occurs or until read() would block.
1643 */
1644static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001645_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001646{
1647 PyObject *res = NULL;
1648 Py_ssize_t current_size, remaining, written;
1649 char *out;
1650
1651 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1652 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001653 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001654
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001655 res = PyBytes_FromStringAndSize(NULL, n);
1656 if (res == NULL)
1657 goto error;
1658 out = PyBytes_AS_STRING(res);
1659 remaining = n;
1660 written = 0;
1661 if (current_size > 0) {
1662 memcpy(out, self->buffer + self->pos, current_size);
1663 remaining -= current_size;
1664 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001665 self->pos += current_size;
1666 }
1667 /* Flush the write buffer if necessary */
1668 if (self->writable) {
1669 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1670 if (r == NULL)
1671 goto error;
1672 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001673 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001674 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001675 while (remaining > 0) {
1676 /* We want to read a whole block at the end into buffer.
1677 If we had readv() we could do this in one pass. */
1678 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1679 if (r == 0)
1680 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001681 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001682 if (r == -1)
1683 goto error;
1684 if (r == 0 || r == -2) {
1685 /* EOF occurred or read() would block. */
1686 if (r == 0 || written > 0) {
1687 if (_PyBytes_Resize(&res, written))
1688 goto error;
1689 return res;
1690 }
1691 Py_DECREF(res);
1692 Py_INCREF(Py_None);
1693 return Py_None;
1694 }
1695 remaining -= r;
1696 written += r;
1697 }
1698 assert(remaining <= self->buffer_size);
1699 self->pos = 0;
1700 self->raw_pos = 0;
1701 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001702 /* NOTE: when the read is satisfied, we avoid issuing any additional
1703 reads, which could block indefinitely (e.g. on a socket).
1704 See issue #9550. */
1705 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001706 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001707 if (r == -1)
1708 goto error;
1709 if (r == 0 || r == -2) {
1710 /* EOF occurred or read() would block. */
1711 if (r == 0 || written > 0) {
1712 if (_PyBytes_Resize(&res, written))
1713 goto error;
1714 return res;
1715 }
1716 Py_DECREF(res);
1717 Py_INCREF(Py_None);
1718 return Py_None;
1719 }
1720 if (remaining > r) {
1721 memcpy(out + written, self->buffer + self->pos, r);
1722 written += r;
1723 self->pos += r;
1724 remaining -= r;
1725 }
1726 else if (remaining > 0) {
1727 memcpy(out + written, self->buffer + self->pos, remaining);
1728 written += remaining;
1729 self->pos += remaining;
1730 remaining = 0;
1731 }
1732 if (remaining == 0)
1733 break;
1734 }
1735
1736 return res;
1737
1738error:
1739 Py_XDECREF(res);
1740 return NULL;
1741}
1742
1743static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001744_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745{
1746 Py_ssize_t have, r;
1747
1748 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1749 /* Constraints:
1750 1. we don't want to advance the file position.
1751 2. we don't want to lose block alignment, so we can't shift the buffer
1752 to make some place.
1753 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1754 */
1755 if (have > 0) {
1756 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1757 }
1758
1759 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001760 _bufferedreader_reset_buf(self);
1761 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762 if (r == -1)
1763 return NULL;
1764 if (r == -2)
1765 r = 0;
1766 self->pos = 0;
1767 return PyBytes_FromStringAndSize(self->buffer, r);
1768}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001769
1770
Benjamin Peterson59406a92009-03-26 17:10:29 +00001771
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001772/*
1773 * class BufferedWriter
1774 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001777{
1778 self->write_pos = 0;
1779 self->write_end = -1;
1780}
1781
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001782/*[clinic input]
1783_io.BufferedWriter.__init__
1784 raw: object
1785 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001787A buffer for a writeable sequential RawIO object.
1788
1789The constructor creates a BufferedWriter for the given writeable raw
1790stream. If the buffer_size is not given, it defaults to
1791DEFAULT_BUFFER_SIZE.
1792[clinic start generated code]*/
1793
1794static int
1795_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1796 Py_ssize_t buffer_size)
1797/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1798{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001800 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001802 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001803 return -1;
1804
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001806 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807 self->readable = 0;
1808 self->writable = 1;
1809
1810 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001811 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001813 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814 self->pos = 0;
1815
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001816 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1817 Py_TYPE(raw) == &PyFileIO_Type);
1818
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001819 self->ok = 1;
1820 return 0;
1821}
1822
1823static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825{
1826 Py_buffer buf;
1827 PyObject *memobj, *res;
1828 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001829 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830 /* NOTE: the buffer needn't be released as its object is NULL. */
1831 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1832 return -1;
1833 memobj = PyMemoryView_FromBuffer(&buf);
1834 if (memobj == NULL)
1835 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001836 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1837 occurs so we needn't do it ourselves.
1838 We then retry writing, ignoring the signal if no handler has
1839 raised (see issue #10956).
1840 */
1841 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001842 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001843 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001844 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001845 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 Py_DECREF(memobj);
1847 if (res == NULL)
1848 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001849 if (res == Py_None) {
1850 /* Non-blocking stream would have blocked. Special return code!
1851 Being paranoid we reset errno in case it is changed by code
1852 triggered by a decref. errno is used by _set_BlockingIOError(). */
1853 Py_DECREF(res);
1854 errno = errnum;
1855 return -2;
1856 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001857 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1858 Py_DECREF(res);
1859 if (n < 0 || n > len) {
1860 PyErr_Format(PyExc_IOError,
1861 "raw write() returned invalid length %zd "
1862 "(should have been between 0 and %zd)", n, len);
1863 return -1;
1864 }
1865 if (n > 0 && self->abs_pos != -1)
1866 self->abs_pos += n;
1867 return n;
1868}
1869
1870/* `restore_pos` is 1 if we need to restore the raw stream position at
1871 the end, 0 otherwise. */
1872static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001873_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001874{
1875 Py_ssize_t written = 0;
1876 Py_off_t n, rewind;
1877
1878 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1879 goto end;
1880 /* First, rewind */
1881 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1882 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001883 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884 if (n < 0) {
1885 goto error;
1886 }
1887 self->raw_pos -= rewind;
1888 }
1889 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001890 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001891 self->buffer + self->write_pos,
1892 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1893 Py_off_t, Py_ssize_t));
1894 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001895 goto error;
1896 }
1897 else if (n == -2) {
1898 _set_BlockingIOError("write could not complete without blocking",
1899 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900 goto error;
1901 }
1902 self->write_pos += n;
1903 self->raw_pos = self->write_pos;
1904 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001905 /* Partial writes can return successfully when interrupted by a
1906 signal (see write(2)). We must run signal handlers before
1907 blocking another time, possibly indefinitely. */
1908 if (PyErr_CheckSignals() < 0)
1909 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001910 }
1911
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001912 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913
1914end:
1915 Py_RETURN_NONE;
1916
1917error:
1918 return NULL;
1919}
1920
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001921/*[clinic input]
1922_io.BufferedWriter.write
1923 buffer: Py_buffer
1924 /
1925[clinic start generated code]*/
1926
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001927static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001928_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1929/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001930{
1931 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001932 Py_ssize_t written, avail, remaining;
1933 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934
1935 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001936 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938 return NULL;
1939 }
1940
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001941 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001942 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001943
1944 /* Fast path: the data to write can be fully buffered. */
1945 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1946 self->pos = 0;
1947 self->raw_pos = 0;
1948 }
1949 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001950 if (buffer->len <= avail) {
1951 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001952 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001953 self->write_pos = self->pos;
1954 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001955 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001956 if (self->pos > self->write_end)
1957 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001958 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001959 goto end;
1960 }
1961
1962 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001963 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001965 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966 if (w == NULL)
1967 goto error;
1968 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001969 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 /* Make some place by shifting the buffer. */
1971 assert(VALID_WRITE_BUFFER(self));
1972 memmove(self->buffer, self->buffer + self->write_pos,
1973 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1974 Py_off_t, Py_ssize_t));
1975 self->write_end -= self->write_pos;
1976 self->raw_pos -= self->write_pos;
1977 self->pos -= self->write_pos;
1978 self->write_pos = 0;
1979 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1980 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001981 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982 /* Everything can be buffered */
1983 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001984 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1985 self->write_end += buffer->len;
1986 self->pos += buffer->len;
1987 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988 goto end;
1989 }
1990 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001991 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001992 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001993 self->pos += avail;
1994 /* XXX Modifying the existing exception e using the pointer w
1995 will change e.characters_written but not e.args[2].
1996 Therefore we just replace with a new error. */
1997 _set_BlockingIOError("write could not complete without blocking",
1998 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 goto error;
2000 }
2001 Py_CLEAR(res);
2002
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002003 /* Adjust the raw stream position if it is away from the logical stream
2004 position. This happens if the read buffer has been filled but not
2005 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2006 the raw stream by itself).
2007 Fixes issue #6629.
2008 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002009 offset = RAW_OFFSET(self);
2010 if (offset != 0) {
2011 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002012 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002013 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002014 }
2015
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002016 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002017 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 written = 0;
2019 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002020 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002021 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002023 goto error;
2024 } else if (n == -2) {
2025 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 if (remaining > self->buffer_size) {
2027 /* Can't buffer everything, still buffer as much as possible */
2028 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002029 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 self->raw_pos = 0;
2031 ADJUST_POSITION(self, self->buffer_size);
2032 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002033 written += self->buffer_size;
2034 _set_BlockingIOError("write could not complete without "
2035 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002036 goto error;
2037 }
2038 PyErr_Clear();
2039 break;
2040 }
2041 written += n;
2042 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002043 /* Partial writes can return successfully when interrupted by a
2044 signal (see write(2)). We must run signal handlers before
2045 blocking another time, possibly indefinitely. */
2046 if (PyErr_CheckSignals() < 0)
2047 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048 }
2049 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002050 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002052 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002053 written += remaining;
2054 }
2055 self->write_pos = 0;
2056 /* TODO: sanity check (remaining >= 0) */
2057 self->write_end = remaining;
2058 ADJUST_POSITION(self, remaining);
2059 self->raw_pos = 0;
2060
2061end:
2062 res = PyLong_FromSsize_t(written);
2063
2064error:
2065 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 return res;
2067}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068
2069
2070
2071/*
2072 * BufferedRWPair
2073 */
2074
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075/* XXX The usefulness of this (compared to having two separate IO objects) is
2076 * questionable.
2077 */
2078
2079typedef struct {
2080 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002081 buffered *reader;
2082 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083 PyObject *dict;
2084 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002085} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002087/*[clinic input]
2088_io.BufferedRWPair.__init__
2089 reader: object
2090 writer: object
2091 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2092 /
2093
2094A buffered reader and writer object together.
2095
2096A buffered reader object and buffered writer object put together to
2097form a sequential IO object that can read and write. This is typically
2098used with a socket or two-way pipe.
2099
2100reader and writer are RawIOBase objects that are readable and
2101writeable respectively. If the buffer_size is omitted it defaults to
2102DEFAULT_BUFFER_SIZE.
2103[clinic start generated code]*/
2104
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002105static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002106_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2107 PyObject *writer, Py_ssize_t buffer_size)
2108/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113 return -1;
2114
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002115 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002116 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002117 if (self->reader == NULL)
2118 return -1;
2119
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002121 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002122 if (self->writer == NULL) {
2123 Py_CLEAR(self->reader);
2124 return -1;
2125 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002126
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002127 return 0;
2128}
2129
2130static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002132{
2133 Py_VISIT(self->dict);
2134 return 0;
2135}
2136
2137static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002138bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139{
2140 Py_CLEAR(self->reader);
2141 Py_CLEAR(self->writer);
2142 Py_CLEAR(self->dict);
2143 return 0;
2144}
2145
2146static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148{
2149 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002150 if (self->weakreflist != NULL)
2151 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152 Py_CLEAR(self->reader);
2153 Py_CLEAR(self->writer);
2154 Py_CLEAR(self->dict);
2155 Py_TYPE(self)->tp_free((PyObject *) self);
2156}
2157
2158static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002159_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002161 PyObject *func, *ret;
2162 if (self == NULL) {
2163 PyErr_SetString(PyExc_ValueError,
2164 "I/O operation on uninitialized object");
2165 return NULL;
2166 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002168 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002170 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 return NULL;
2172 }
2173
2174 ret = PyObject_CallObject(func, args);
2175 Py_DECREF(func);
2176 return ret;
2177}
2178
2179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002182 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183}
2184
2185static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002188 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189}
2190
2191static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002194 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195}
2196
2197static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002198bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002199{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002200 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002201}
2202
2203static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002204bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2205{
2206 return _forward_call(self->reader, &PyId_readinto1, args);
2207}
2208
2209static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002212 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213}
2214
2215static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002216bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002218 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219}
2220
2221static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002224 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225}
2226
2227static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002228bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002230 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002231}
2232
2233static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002234bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002236 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002237 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002239 PyErr_Fetch(&exc, &val, &tb);
2240 else
2241 Py_DECREF(ret);
2242 ret = _forward_call(self->reader, &PyId_close, args);
2243 if (exc != NULL) {
2244 _PyErr_ChainExceptions(exc, val, tb);
2245 Py_CLEAR(ret);
2246 }
2247 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002248}
2249
2250static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002251bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002252{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002253 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254
2255 if (ret != Py_False) {
2256 /* either True or exception */
2257 return ret;
2258 }
2259 Py_DECREF(ret);
2260
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002261 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262}
2263
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002264static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002266{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002267 if (self->writer == NULL) {
2268 PyErr_SetString(PyExc_RuntimeError,
2269 "the BufferedRWPair object is being garbage-collected");
2270 return NULL;
2271 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002272 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2273}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002274
2275
2276
2277/*
2278 * BufferedRandom
2279 */
2280
2281/*[clinic input]
2282_io.BufferedRandom.__init__
2283 raw: object
2284 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2285
2286A buffered interface to random access streams.
2287
2288The constructor creates a reader and writer for a seekable stream,
2289raw, given in the first argument. If the buffer_size is omitted it
2290defaults to DEFAULT_BUFFER_SIZE.
2291[clinic start generated code]*/
2292
2293static int
2294_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2295 Py_ssize_t buffer_size)
2296/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2297{
2298 self->ok = 0;
2299 self->detached = 0;
2300
2301 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2302 return -1;
2303 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2304 return -1;
2305 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2306 return -1;
2307
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002308 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002309 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002310 self->buffer_size = buffer_size;
2311 self->readable = 1;
2312 self->writable = 1;
2313
2314 if (_buffered_init(self) < 0)
2315 return -1;
2316 _bufferedreader_reset_buf(self);
2317 _bufferedwriter_reset_buf(self);
2318 self->pos = 0;
2319
2320 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2321 Py_TYPE(raw) == &PyFileIO_Type);
2322
2323 self->ok = 1;
2324 return 0;
2325}
2326
2327#include "clinic/bufferedio.c.h"
2328
2329
2330static PyMethodDef bufferediobase_methods[] = {
2331 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2332 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2333 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2334 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2335 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2336 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2337 {NULL, NULL}
2338};
2339
2340PyTypeObject PyBufferedIOBase_Type = {
2341 PyVarObject_HEAD_INIT(NULL, 0)
2342 "_io._BufferedIOBase", /*tp_name*/
2343 0, /*tp_basicsize*/
2344 0, /*tp_itemsize*/
2345 0, /*tp_dealloc*/
2346 0, /*tp_print*/
2347 0, /*tp_getattr*/
2348 0, /*tp_setattr*/
2349 0, /*tp_compare */
2350 0, /*tp_repr*/
2351 0, /*tp_as_number*/
2352 0, /*tp_as_sequence*/
2353 0, /*tp_as_mapping*/
2354 0, /*tp_hash */
2355 0, /*tp_call*/
2356 0, /*tp_str*/
2357 0, /*tp_getattro*/
2358 0, /*tp_setattro*/
2359 0, /*tp_as_buffer*/
2360 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2361 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2362 bufferediobase_doc, /* tp_doc */
2363 0, /* tp_traverse */
2364 0, /* tp_clear */
2365 0, /* tp_richcompare */
2366 0, /* tp_weaklistoffset */
2367 0, /* tp_iter */
2368 0, /* tp_iternext */
2369 bufferediobase_methods, /* tp_methods */
2370 0, /* tp_members */
2371 0, /* tp_getset */
2372 &PyIOBase_Type, /* tp_base */
2373 0, /* tp_dict */
2374 0, /* tp_descr_get */
2375 0, /* tp_descr_set */
2376 0, /* tp_dictoffset */
2377 0, /* tp_init */
2378 0, /* tp_alloc */
2379 0, /* tp_new */
2380 0, /* tp_free */
2381 0, /* tp_is_gc */
2382 0, /* tp_bases */
2383 0, /* tp_mro */
2384 0, /* tp_cache */
2385 0, /* tp_subclasses */
2386 0, /* tp_weaklist */
2387 0, /* tp_del */
2388 0, /* tp_version_tag */
2389 0, /* tp_finalize */
2390};
2391
2392
2393static PyMethodDef bufferedreader_methods[] = {
2394 /* BufferedIOMixin methods */
2395 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2396 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2397 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2398 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2399 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002400 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2401 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2402 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2403 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2404
2405 _IO__BUFFERED_READ_METHODDEF
2406 _IO__BUFFERED_PEEK_METHODDEF
2407 _IO__BUFFERED_READ1_METHODDEF
2408 _IO__BUFFERED_READINTO_METHODDEF
2409 _IO__BUFFERED_READINTO1_METHODDEF
2410 _IO__BUFFERED_READLINE_METHODDEF
2411 _IO__BUFFERED_SEEK_METHODDEF
2412 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2413 _IO__BUFFERED_TRUNCATE_METHODDEF
2414 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2415 {NULL, NULL}
2416};
2417
2418static PyMemberDef bufferedreader_members[] = {
2419 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2420 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2421 {NULL}
2422};
2423
2424static PyGetSetDef bufferedreader_getset[] = {
2425 {"closed", (getter)buffered_closed_get, NULL, NULL},
2426 {"name", (getter)buffered_name_get, NULL, NULL},
2427 {"mode", (getter)buffered_mode_get, NULL, NULL},
2428 {NULL}
2429};
2430
2431
2432PyTypeObject PyBufferedReader_Type = {
2433 PyVarObject_HEAD_INIT(NULL, 0)
2434 "_io.BufferedReader", /*tp_name*/
2435 sizeof(buffered), /*tp_basicsize*/
2436 0, /*tp_itemsize*/
2437 (destructor)buffered_dealloc, /*tp_dealloc*/
2438 0, /*tp_print*/
2439 0, /*tp_getattr*/
2440 0, /*tp_setattr*/
2441 0, /*tp_compare */
2442 (reprfunc)buffered_repr, /*tp_repr*/
2443 0, /*tp_as_number*/
2444 0, /*tp_as_sequence*/
2445 0, /*tp_as_mapping*/
2446 0, /*tp_hash */
2447 0, /*tp_call*/
2448 0, /*tp_str*/
2449 0, /*tp_getattro*/
2450 0, /*tp_setattro*/
2451 0, /*tp_as_buffer*/
2452 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2453 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2454 _io_BufferedReader___init____doc__, /* tp_doc */
2455 (traverseproc)buffered_traverse, /* tp_traverse */
2456 (inquiry)buffered_clear, /* tp_clear */
2457 0, /* tp_richcompare */
2458 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2459 0, /* tp_iter */
2460 (iternextfunc)buffered_iternext, /* tp_iternext */
2461 bufferedreader_methods, /* tp_methods */
2462 bufferedreader_members, /* tp_members */
2463 bufferedreader_getset, /* tp_getset */
2464 0, /* tp_base */
2465 0, /* tp_dict */
2466 0, /* tp_descr_get */
2467 0, /* tp_descr_set */
2468 offsetof(buffered, dict), /* tp_dictoffset */
2469 _io_BufferedReader___init__, /* tp_init */
2470 0, /* tp_alloc */
2471 PyType_GenericNew, /* tp_new */
2472 0, /* tp_free */
2473 0, /* tp_is_gc */
2474 0, /* tp_bases */
2475 0, /* tp_mro */
2476 0, /* tp_cache */
2477 0, /* tp_subclasses */
2478 0, /* tp_weaklist */
2479 0, /* tp_del */
2480 0, /* tp_version_tag */
2481 0, /* tp_finalize */
2482};
2483
2484
2485static PyMethodDef bufferedwriter_methods[] = {
2486 /* BufferedIOMixin methods */
2487 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2488 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2489 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002490 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2491 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2492 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2493 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2494 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2495
2496 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2497 _IO__BUFFERED_TRUNCATE_METHODDEF
2498 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2499 _IO__BUFFERED_SEEK_METHODDEF
2500 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2501 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2502 {NULL, NULL}
2503};
2504
2505static PyMemberDef bufferedwriter_members[] = {
2506 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2507 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2508 {NULL}
2509};
2510
2511static PyGetSetDef bufferedwriter_getset[] = {
2512 {"closed", (getter)buffered_closed_get, NULL, NULL},
2513 {"name", (getter)buffered_name_get, NULL, NULL},
2514 {"mode", (getter)buffered_mode_get, NULL, NULL},
2515 {NULL}
2516};
2517
2518
2519PyTypeObject PyBufferedWriter_Type = {
2520 PyVarObject_HEAD_INIT(NULL, 0)
2521 "_io.BufferedWriter", /*tp_name*/
2522 sizeof(buffered), /*tp_basicsize*/
2523 0, /*tp_itemsize*/
2524 (destructor)buffered_dealloc, /*tp_dealloc*/
2525 0, /*tp_print*/
2526 0, /*tp_getattr*/
2527 0, /*tp_setattr*/
2528 0, /*tp_compare */
2529 (reprfunc)buffered_repr, /*tp_repr*/
2530 0, /*tp_as_number*/
2531 0, /*tp_as_sequence*/
2532 0, /*tp_as_mapping*/
2533 0, /*tp_hash */
2534 0, /*tp_call*/
2535 0, /*tp_str*/
2536 0, /*tp_getattro*/
2537 0, /*tp_setattro*/
2538 0, /*tp_as_buffer*/
2539 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2540 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2541 _io_BufferedWriter___init____doc__, /* tp_doc */
2542 (traverseproc)buffered_traverse, /* tp_traverse */
2543 (inquiry)buffered_clear, /* tp_clear */
2544 0, /* tp_richcompare */
2545 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2546 0, /* tp_iter */
2547 0, /* tp_iternext */
2548 bufferedwriter_methods, /* tp_methods */
2549 bufferedwriter_members, /* tp_members */
2550 bufferedwriter_getset, /* tp_getset */
2551 0, /* tp_base */
2552 0, /* tp_dict */
2553 0, /* tp_descr_get */
2554 0, /* tp_descr_set */
2555 offsetof(buffered, dict), /* tp_dictoffset */
2556 _io_BufferedWriter___init__, /* tp_init */
2557 0, /* tp_alloc */
2558 PyType_GenericNew, /* tp_new */
2559 0, /* tp_free */
2560 0, /* tp_is_gc */
2561 0, /* tp_bases */
2562 0, /* tp_mro */
2563 0, /* tp_cache */
2564 0, /* tp_subclasses */
2565 0, /* tp_weaklist */
2566 0, /* tp_del */
2567 0, /* tp_version_tag */
2568 0, /* tp_finalize */
2569};
2570
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002571
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002572static PyMethodDef bufferedrwpair_methods[] = {
2573 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2574 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2575 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2576 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002577 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002578
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002579 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2580 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002581
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002582 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2583 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002584
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002585 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2586 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002587
Antoine Pitrou243757e2010-11-05 21:15:39 +00002588 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2589
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002590 {NULL, NULL}
2591};
2592
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002593static PyGetSetDef bufferedrwpair_getset[] = {
2594 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002595 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002596};
2597
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002598PyTypeObject PyBufferedRWPair_Type = {
2599 PyVarObject_HEAD_INIT(NULL, 0)
2600 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002602 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002603 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002604 0, /*tp_print*/
2605 0, /*tp_getattr*/
2606 0, /*tp_setattr*/
2607 0, /*tp_compare */
2608 0, /*tp_repr*/
2609 0, /*tp_as_number*/
2610 0, /*tp_as_sequence*/
2611 0, /*tp_as_mapping*/
2612 0, /*tp_hash */
2613 0, /*tp_call*/
2614 0, /*tp_str*/
2615 0, /*tp_getattro*/
2616 0, /*tp_setattro*/
2617 0, /*tp_as_buffer*/
2618 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002619 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002620 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002621 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2622 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002624 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002625 0, /* tp_iter */
2626 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002627 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002628 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002629 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002630 0, /* tp_base */
2631 0, /* tp_dict */
2632 0, /* tp_descr_get */
2633 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002634 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002635 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636 0, /* tp_alloc */
2637 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002638 0, /* tp_free */
2639 0, /* tp_is_gc */
2640 0, /* tp_bases */
2641 0, /* tp_mro */
2642 0, /* tp_cache */
2643 0, /* tp_subclasses */
2644 0, /* tp_weaklist */
2645 0, /* tp_del */
2646 0, /* tp_version_tag */
2647 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002648};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002649
2650
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002651static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002652 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002653 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2654 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2655 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2656 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2657 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2658 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2659 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002660 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002661 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002662
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002663 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002664
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002665 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002666 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002667 _IO__BUFFERED_TRUNCATE_METHODDEF
2668 _IO__BUFFERED_READ_METHODDEF
2669 _IO__BUFFERED_READ1_METHODDEF
2670 _IO__BUFFERED_READINTO_METHODDEF
2671 _IO__BUFFERED_READINTO1_METHODDEF
2672 _IO__BUFFERED_READLINE_METHODDEF
2673 _IO__BUFFERED_PEEK_METHODDEF
2674 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002675 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002676 {NULL, NULL}
2677};
2678
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002679static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002680 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002681 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002682 {NULL}
2683};
2684
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002685static PyGetSetDef bufferedrandom_getset[] = {
2686 {"closed", (getter)buffered_closed_get, NULL, NULL},
2687 {"name", (getter)buffered_name_get, NULL, NULL},
2688 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002689 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690};
2691
2692
2693PyTypeObject PyBufferedRandom_Type = {
2694 PyVarObject_HEAD_INIT(NULL, 0)
2695 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002696 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002697 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002698 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002699 0, /*tp_print*/
2700 0, /*tp_getattr*/
2701 0, /*tp_setattr*/
2702 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002703 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002704 0, /*tp_as_number*/
2705 0, /*tp_as_sequence*/
2706 0, /*tp_as_mapping*/
2707 0, /*tp_hash */
2708 0, /*tp_call*/
2709 0, /*tp_str*/
2710 0, /*tp_getattro*/
2711 0, /*tp_setattro*/
2712 0, /*tp_as_buffer*/
2713 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002714 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002715 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002716 (traverseproc)buffered_traverse, /* tp_traverse */
2717 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002718 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002719 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002720 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002721 (iternextfunc)buffered_iternext, /* tp_iternext */
2722 bufferedrandom_methods, /* tp_methods */
2723 bufferedrandom_members, /* tp_members */
2724 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002725 0, /* tp_base */
2726 0, /*tp_dict*/
2727 0, /* tp_descr_get */
2728 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002729 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002730 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002731 0, /* tp_alloc */
2732 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002733 0, /* tp_free */
2734 0, /* tp_is_gc */
2735 0, /* tp_bases */
2736 0, /* tp_mro */
2737 0, /* tp_cache */
2738 0, /* tp_subclasses */
2739 0, /* tp_weaklist */
2740 0, /* tp_del */
2741 0, /* tp_version_tag */
2742 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002743};