blob: 6c88bbb2b01629802091d796b3ef566f43423fa0 [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);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001692 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693 }
1694 remaining -= r;
1695 written += r;
1696 }
1697 assert(remaining <= self->buffer_size);
1698 self->pos = 0;
1699 self->raw_pos = 0;
1700 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001701 /* NOTE: when the read is satisfied, we avoid issuing any additional
1702 reads, which could block indefinitely (e.g. on a socket).
1703 See issue #9550. */
1704 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 if (r == -1)
1707 goto error;
1708 if (r == 0 || r == -2) {
1709 /* EOF occurred or read() would block. */
1710 if (r == 0 || written > 0) {
1711 if (_PyBytes_Resize(&res, written))
1712 goto error;
1713 return res;
1714 }
1715 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001716 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001717 }
1718 if (remaining > r) {
1719 memcpy(out + written, self->buffer + self->pos, r);
1720 written += r;
1721 self->pos += r;
1722 remaining -= r;
1723 }
1724 else if (remaining > 0) {
1725 memcpy(out + written, self->buffer + self->pos, remaining);
1726 written += remaining;
1727 self->pos += remaining;
1728 remaining = 0;
1729 }
1730 if (remaining == 0)
1731 break;
1732 }
1733
1734 return res;
1735
1736error:
1737 Py_XDECREF(res);
1738 return NULL;
1739}
1740
1741static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001742_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743{
1744 Py_ssize_t have, r;
1745
1746 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1747 /* Constraints:
1748 1. we don't want to advance the file position.
1749 2. we don't want to lose block alignment, so we can't shift the buffer
1750 to make some place.
1751 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1752 */
1753 if (have > 0) {
1754 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1755 }
1756
1757 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758 _bufferedreader_reset_buf(self);
1759 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760 if (r == -1)
1761 return NULL;
1762 if (r == -2)
1763 r = 0;
1764 self->pos = 0;
1765 return PyBytes_FromStringAndSize(self->buffer, r);
1766}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767
1768
Benjamin Peterson59406a92009-03-26 17:10:29 +00001769
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770/*
1771 * class BufferedWriter
1772 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001774_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775{
1776 self->write_pos = 0;
1777 self->write_end = -1;
1778}
1779
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001780/*[clinic input]
1781_io.BufferedWriter.__init__
1782 raw: object
1783 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001785A buffer for a writeable sequential RawIO object.
1786
1787The constructor creates a BufferedWriter for the given writeable raw
1788stream. If the buffer_size is not given, it defaults to
1789DEFAULT_BUFFER_SIZE.
1790[clinic start generated code]*/
1791
1792static int
1793_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1794 Py_ssize_t buffer_size)
1795/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1796{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001798 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 return -1;
1802
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001803 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001804 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 self->readable = 0;
1806 self->writable = 1;
1807
1808 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001811 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812 self->pos = 0;
1813
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001814 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1815 Py_TYPE(raw) == &PyFileIO_Type);
1816
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001817 self->ok = 1;
1818 return 0;
1819}
1820
1821static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001822_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823{
1824 Py_buffer buf;
1825 PyObject *memobj, *res;
1826 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001827 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828 /* NOTE: the buffer needn't be released as its object is NULL. */
1829 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1830 return -1;
1831 memobj = PyMemoryView_FromBuffer(&buf);
1832 if (memobj == NULL)
1833 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001834 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1835 occurs so we needn't do it ourselves.
1836 We then retry writing, ignoring the signal if no handler has
1837 raised (see issue #10956).
1838 */
1839 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001840 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001841 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001842 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001843 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844 Py_DECREF(memobj);
1845 if (res == NULL)
1846 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001847 if (res == Py_None) {
1848 /* Non-blocking stream would have blocked. Special return code!
1849 Being paranoid we reset errno in case it is changed by code
1850 triggered by a decref. errno is used by _set_BlockingIOError(). */
1851 Py_DECREF(res);
1852 errno = errnum;
1853 return -2;
1854 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001855 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1856 Py_DECREF(res);
1857 if (n < 0 || n > len) {
1858 PyErr_Format(PyExc_IOError,
1859 "raw write() returned invalid length %zd "
1860 "(should have been between 0 and %zd)", n, len);
1861 return -1;
1862 }
1863 if (n > 0 && self->abs_pos != -1)
1864 self->abs_pos += n;
1865 return n;
1866}
1867
1868/* `restore_pos` is 1 if we need to restore the raw stream position at
1869 the end, 0 otherwise. */
1870static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001871_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872{
1873 Py_ssize_t written = 0;
1874 Py_off_t n, rewind;
1875
1876 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1877 goto end;
1878 /* First, rewind */
1879 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1880 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001881 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001882 if (n < 0) {
1883 goto error;
1884 }
1885 self->raw_pos -= rewind;
1886 }
1887 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001888 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 self->buffer + self->write_pos,
1890 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1891 Py_off_t, Py_ssize_t));
1892 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001893 goto error;
1894 }
1895 else if (n == -2) {
1896 _set_BlockingIOError("write could not complete without blocking",
1897 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898 goto error;
1899 }
1900 self->write_pos += n;
1901 self->raw_pos = self->write_pos;
1902 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001903 /* Partial writes can return successfully when interrupted by a
1904 signal (see write(2)). We must run signal handlers before
1905 blocking another time, possibly indefinitely. */
1906 if (PyErr_CheckSignals() < 0)
1907 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908 }
1909
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001910 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001911
1912end:
1913 Py_RETURN_NONE;
1914
1915error:
1916 return NULL;
1917}
1918
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001919/*[clinic input]
1920_io.BufferedWriter.write
1921 buffer: Py_buffer
1922 /
1923[clinic start generated code]*/
1924
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001925static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001926_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1927/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928{
1929 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001930 Py_ssize_t written, avail, remaining;
1931 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001932
1933 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001934 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936 return NULL;
1937 }
1938
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001939 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001940 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941
1942 /* Fast path: the data to write can be fully buffered. */
1943 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1944 self->pos = 0;
1945 self->raw_pos = 0;
1946 }
1947 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001948 if (buffer->len <= avail) {
1949 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001950 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951 self->write_pos = self->pos;
1952 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001953 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 if (self->pos > self->write_end)
1955 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001956 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957 goto end;
1958 }
1959
1960 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001961 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001962 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001963 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 if (w == NULL)
1965 goto error;
1966 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001967 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001968 /* Make some place by shifting the buffer. */
1969 assert(VALID_WRITE_BUFFER(self));
1970 memmove(self->buffer, self->buffer + self->write_pos,
1971 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1972 Py_off_t, Py_ssize_t));
1973 self->write_end -= self->write_pos;
1974 self->raw_pos -= self->write_pos;
1975 self->pos -= self->write_pos;
1976 self->write_pos = 0;
1977 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1978 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001979 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001980 /* Everything can be buffered */
1981 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001982 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1983 self->write_end += buffer->len;
1984 self->pos += buffer->len;
1985 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001986 goto end;
1987 }
1988 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001989 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001990 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001991 self->pos += avail;
1992 /* XXX Modifying the existing exception e using the pointer w
1993 will change e.characters_written but not e.args[2].
1994 Therefore we just replace with a new error. */
1995 _set_BlockingIOError("write could not complete without blocking",
1996 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001997 goto error;
1998 }
1999 Py_CLEAR(res);
2000
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002001 /* Adjust the raw stream position if it is away from the logical stream
2002 position. This happens if the read buffer has been filled but not
2003 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2004 the raw stream by itself).
2005 Fixes issue #6629.
2006 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002007 offset = RAW_OFFSET(self);
2008 if (offset != 0) {
2009 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002010 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002011 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002012 }
2013
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002015 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002016 written = 0;
2017 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002018 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002019 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002021 goto error;
2022 } else if (n == -2) {
2023 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 if (remaining > self->buffer_size) {
2025 /* Can't buffer everything, still buffer as much as possible */
2026 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002027 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002028 self->raw_pos = 0;
2029 ADJUST_POSITION(self, self->buffer_size);
2030 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002031 written += self->buffer_size;
2032 _set_BlockingIOError("write could not complete without "
2033 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002034 goto error;
2035 }
2036 PyErr_Clear();
2037 break;
2038 }
2039 written += n;
2040 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002041 /* Partial writes can return successfully when interrupted by a
2042 signal (see write(2)). We must run signal handlers before
2043 blocking another time, possibly indefinitely. */
2044 if (PyErr_CheckSignals() < 0)
2045 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 }
2047 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002048 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002049 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002050 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 written += remaining;
2052 }
2053 self->write_pos = 0;
2054 /* TODO: sanity check (remaining >= 0) */
2055 self->write_end = remaining;
2056 ADJUST_POSITION(self, remaining);
2057 self->raw_pos = 0;
2058
2059end:
2060 res = PyLong_FromSsize_t(written);
2061
2062error:
2063 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064 return res;
2065}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066
2067
2068
2069/*
2070 * BufferedRWPair
2071 */
2072
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002073/* XXX The usefulness of this (compared to having two separate IO objects) is
2074 * questionable.
2075 */
2076
2077typedef struct {
2078 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002079 buffered *reader;
2080 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 PyObject *dict;
2082 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002083} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002084
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002085/*[clinic input]
2086_io.BufferedRWPair.__init__
2087 reader: object
2088 writer: object
2089 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2090 /
2091
2092A buffered reader and writer object together.
2093
2094A buffered reader object and buffered writer object put together to
2095form a sequential IO object that can read and write. This is typically
2096used with a socket or two-way pipe.
2097
2098reader and writer are RawIOBase objects that are readable and
2099writeable respectively. If the buffer_size is omitted it defaults to
2100DEFAULT_BUFFER_SIZE.
2101[clinic start generated code]*/
2102
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002103static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002104_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2105 PyObject *writer, Py_ssize_t buffer_size)
2106/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002108 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 return -1;
2112
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002113 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002114 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002115 if (self->reader == NULL)
2116 return -1;
2117
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002118 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002119 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002120 if (self->writer == NULL) {
2121 Py_CLEAR(self->reader);
2122 return -1;
2123 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002124
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002125 return 0;
2126}
2127
2128static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130{
2131 Py_VISIT(self->dict);
2132 return 0;
2133}
2134
2135static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002136bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002137{
2138 Py_CLEAR(self->reader);
2139 Py_CLEAR(self->writer);
2140 Py_CLEAR(self->dict);
2141 return 0;
2142}
2143
2144static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002145bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002146{
2147 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002148 if (self->weakreflist != NULL)
2149 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150 Py_CLEAR(self->reader);
2151 Py_CLEAR(self->writer);
2152 Py_CLEAR(self->dict);
2153 Py_TYPE(self)->tp_free((PyObject *) self);
2154}
2155
2156static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002157_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002158{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002159 PyObject *func, *ret;
2160 if (self == NULL) {
2161 PyErr_SetString(PyExc_ValueError,
2162 "I/O operation on uninitialized object");
2163 return NULL;
2164 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002166 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002168 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 return NULL;
2170 }
2171
2172 ret = PyObject_CallObject(func, args);
2173 Py_DECREF(func);
2174 return ret;
2175}
2176
2177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002178bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002180 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181}
2182
2183static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002185{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002186 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187}
2188
2189static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002192 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193}
2194
2195static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002196bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002197{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002198 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002199}
2200
2201static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002202bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2203{
2204 return _forward_call(self->reader, &PyId_readinto1, args);
2205}
2206
2207static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002208bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002210 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211}
2212
2213static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002214bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002216 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217}
2218
2219static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002220bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002222 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223}
2224
2225static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002226bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002228 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229}
2230
2231static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002232bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002234 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002235 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002237 PyErr_Fetch(&exc, &val, &tb);
2238 else
2239 Py_DECREF(ret);
2240 ret = _forward_call(self->reader, &PyId_close, args);
2241 if (exc != NULL) {
2242 _PyErr_ChainExceptions(exc, val, tb);
2243 Py_CLEAR(ret);
2244 }
2245 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246}
2247
2248static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002249bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002251 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002252
2253 if (ret != Py_False) {
2254 /* either True or exception */
2255 return ret;
2256 }
2257 Py_DECREF(ret);
2258
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002259 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260}
2261
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002262static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002263bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002264{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002265 if (self->writer == NULL) {
2266 PyErr_SetString(PyExc_RuntimeError,
2267 "the BufferedRWPair object is being garbage-collected");
2268 return NULL;
2269 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002270 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2271}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002272
2273
2274
2275/*
2276 * BufferedRandom
2277 */
2278
2279/*[clinic input]
2280_io.BufferedRandom.__init__
2281 raw: object
2282 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2283
2284A buffered interface to random access streams.
2285
2286The constructor creates a reader and writer for a seekable stream,
2287raw, given in the first argument. If the buffer_size is omitted it
2288defaults to DEFAULT_BUFFER_SIZE.
2289[clinic start generated code]*/
2290
2291static int
2292_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2293 Py_ssize_t buffer_size)
2294/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2295{
2296 self->ok = 0;
2297 self->detached = 0;
2298
2299 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2300 return -1;
2301 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2302 return -1;
2303 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2304 return -1;
2305
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002306 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002307 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002308 self->buffer_size = buffer_size;
2309 self->readable = 1;
2310 self->writable = 1;
2311
2312 if (_buffered_init(self) < 0)
2313 return -1;
2314 _bufferedreader_reset_buf(self);
2315 _bufferedwriter_reset_buf(self);
2316 self->pos = 0;
2317
2318 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2319 Py_TYPE(raw) == &PyFileIO_Type);
2320
2321 self->ok = 1;
2322 return 0;
2323}
2324
2325#include "clinic/bufferedio.c.h"
2326
2327
2328static PyMethodDef bufferediobase_methods[] = {
2329 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2330 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2331 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2332 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2333 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2334 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2335 {NULL, NULL}
2336};
2337
2338PyTypeObject PyBufferedIOBase_Type = {
2339 PyVarObject_HEAD_INIT(NULL, 0)
2340 "_io._BufferedIOBase", /*tp_name*/
2341 0, /*tp_basicsize*/
2342 0, /*tp_itemsize*/
2343 0, /*tp_dealloc*/
2344 0, /*tp_print*/
2345 0, /*tp_getattr*/
2346 0, /*tp_setattr*/
2347 0, /*tp_compare */
2348 0, /*tp_repr*/
2349 0, /*tp_as_number*/
2350 0, /*tp_as_sequence*/
2351 0, /*tp_as_mapping*/
2352 0, /*tp_hash */
2353 0, /*tp_call*/
2354 0, /*tp_str*/
2355 0, /*tp_getattro*/
2356 0, /*tp_setattro*/
2357 0, /*tp_as_buffer*/
2358 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2359 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2360 bufferediobase_doc, /* tp_doc */
2361 0, /* tp_traverse */
2362 0, /* tp_clear */
2363 0, /* tp_richcompare */
2364 0, /* tp_weaklistoffset */
2365 0, /* tp_iter */
2366 0, /* tp_iternext */
2367 bufferediobase_methods, /* tp_methods */
2368 0, /* tp_members */
2369 0, /* tp_getset */
2370 &PyIOBase_Type, /* tp_base */
2371 0, /* tp_dict */
2372 0, /* tp_descr_get */
2373 0, /* tp_descr_set */
2374 0, /* tp_dictoffset */
2375 0, /* tp_init */
2376 0, /* tp_alloc */
2377 0, /* tp_new */
2378 0, /* tp_free */
2379 0, /* tp_is_gc */
2380 0, /* tp_bases */
2381 0, /* tp_mro */
2382 0, /* tp_cache */
2383 0, /* tp_subclasses */
2384 0, /* tp_weaklist */
2385 0, /* tp_del */
2386 0, /* tp_version_tag */
2387 0, /* tp_finalize */
2388};
2389
2390
2391static PyMethodDef bufferedreader_methods[] = {
2392 /* BufferedIOMixin methods */
2393 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2394 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2395 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2396 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2397 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002398 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2399 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2400 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2401 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2402
2403 _IO__BUFFERED_READ_METHODDEF
2404 _IO__BUFFERED_PEEK_METHODDEF
2405 _IO__BUFFERED_READ1_METHODDEF
2406 _IO__BUFFERED_READINTO_METHODDEF
2407 _IO__BUFFERED_READINTO1_METHODDEF
2408 _IO__BUFFERED_READLINE_METHODDEF
2409 _IO__BUFFERED_SEEK_METHODDEF
2410 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2411 _IO__BUFFERED_TRUNCATE_METHODDEF
2412 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2413 {NULL, NULL}
2414};
2415
2416static PyMemberDef bufferedreader_members[] = {
2417 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2418 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2419 {NULL}
2420};
2421
2422static PyGetSetDef bufferedreader_getset[] = {
2423 {"closed", (getter)buffered_closed_get, NULL, NULL},
2424 {"name", (getter)buffered_name_get, NULL, NULL},
2425 {"mode", (getter)buffered_mode_get, NULL, NULL},
2426 {NULL}
2427};
2428
2429
2430PyTypeObject PyBufferedReader_Type = {
2431 PyVarObject_HEAD_INIT(NULL, 0)
2432 "_io.BufferedReader", /*tp_name*/
2433 sizeof(buffered), /*tp_basicsize*/
2434 0, /*tp_itemsize*/
2435 (destructor)buffered_dealloc, /*tp_dealloc*/
2436 0, /*tp_print*/
2437 0, /*tp_getattr*/
2438 0, /*tp_setattr*/
2439 0, /*tp_compare */
2440 (reprfunc)buffered_repr, /*tp_repr*/
2441 0, /*tp_as_number*/
2442 0, /*tp_as_sequence*/
2443 0, /*tp_as_mapping*/
2444 0, /*tp_hash */
2445 0, /*tp_call*/
2446 0, /*tp_str*/
2447 0, /*tp_getattro*/
2448 0, /*tp_setattro*/
2449 0, /*tp_as_buffer*/
2450 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2451 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2452 _io_BufferedReader___init____doc__, /* tp_doc */
2453 (traverseproc)buffered_traverse, /* tp_traverse */
2454 (inquiry)buffered_clear, /* tp_clear */
2455 0, /* tp_richcompare */
2456 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2457 0, /* tp_iter */
2458 (iternextfunc)buffered_iternext, /* tp_iternext */
2459 bufferedreader_methods, /* tp_methods */
2460 bufferedreader_members, /* tp_members */
2461 bufferedreader_getset, /* tp_getset */
2462 0, /* tp_base */
2463 0, /* tp_dict */
2464 0, /* tp_descr_get */
2465 0, /* tp_descr_set */
2466 offsetof(buffered, dict), /* tp_dictoffset */
2467 _io_BufferedReader___init__, /* tp_init */
2468 0, /* tp_alloc */
2469 PyType_GenericNew, /* tp_new */
2470 0, /* tp_free */
2471 0, /* tp_is_gc */
2472 0, /* tp_bases */
2473 0, /* tp_mro */
2474 0, /* tp_cache */
2475 0, /* tp_subclasses */
2476 0, /* tp_weaklist */
2477 0, /* tp_del */
2478 0, /* tp_version_tag */
2479 0, /* tp_finalize */
2480};
2481
2482
2483static PyMethodDef bufferedwriter_methods[] = {
2484 /* BufferedIOMixin methods */
2485 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2486 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2487 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002488 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2489 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2490 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2491 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2492 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2493
2494 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2495 _IO__BUFFERED_TRUNCATE_METHODDEF
2496 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2497 _IO__BUFFERED_SEEK_METHODDEF
2498 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2499 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2500 {NULL, NULL}
2501};
2502
2503static PyMemberDef bufferedwriter_members[] = {
2504 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2505 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2506 {NULL}
2507};
2508
2509static PyGetSetDef bufferedwriter_getset[] = {
2510 {"closed", (getter)buffered_closed_get, NULL, NULL},
2511 {"name", (getter)buffered_name_get, NULL, NULL},
2512 {"mode", (getter)buffered_mode_get, NULL, NULL},
2513 {NULL}
2514};
2515
2516
2517PyTypeObject PyBufferedWriter_Type = {
2518 PyVarObject_HEAD_INIT(NULL, 0)
2519 "_io.BufferedWriter", /*tp_name*/
2520 sizeof(buffered), /*tp_basicsize*/
2521 0, /*tp_itemsize*/
2522 (destructor)buffered_dealloc, /*tp_dealloc*/
2523 0, /*tp_print*/
2524 0, /*tp_getattr*/
2525 0, /*tp_setattr*/
2526 0, /*tp_compare */
2527 (reprfunc)buffered_repr, /*tp_repr*/
2528 0, /*tp_as_number*/
2529 0, /*tp_as_sequence*/
2530 0, /*tp_as_mapping*/
2531 0, /*tp_hash */
2532 0, /*tp_call*/
2533 0, /*tp_str*/
2534 0, /*tp_getattro*/
2535 0, /*tp_setattro*/
2536 0, /*tp_as_buffer*/
2537 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2538 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2539 _io_BufferedWriter___init____doc__, /* tp_doc */
2540 (traverseproc)buffered_traverse, /* tp_traverse */
2541 (inquiry)buffered_clear, /* tp_clear */
2542 0, /* tp_richcompare */
2543 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2544 0, /* tp_iter */
2545 0, /* tp_iternext */
2546 bufferedwriter_methods, /* tp_methods */
2547 bufferedwriter_members, /* tp_members */
2548 bufferedwriter_getset, /* tp_getset */
2549 0, /* tp_base */
2550 0, /* tp_dict */
2551 0, /* tp_descr_get */
2552 0, /* tp_descr_set */
2553 offsetof(buffered, dict), /* tp_dictoffset */
2554 _io_BufferedWriter___init__, /* tp_init */
2555 0, /* tp_alloc */
2556 PyType_GenericNew, /* tp_new */
2557 0, /* tp_free */
2558 0, /* tp_is_gc */
2559 0, /* tp_bases */
2560 0, /* tp_mro */
2561 0, /* tp_cache */
2562 0, /* tp_subclasses */
2563 0, /* tp_weaklist */
2564 0, /* tp_del */
2565 0, /* tp_version_tag */
2566 0, /* tp_finalize */
2567};
2568
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570static PyMethodDef bufferedrwpair_methods[] = {
2571 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2572 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2573 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2574 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002575 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002576
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002577 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2578 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2581 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002583 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2584 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585
Antoine Pitrou243757e2010-11-05 21:15:39 +00002586 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2587
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002588 {NULL, NULL}
2589};
2590
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002591static PyGetSetDef bufferedrwpair_getset[] = {
2592 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002593 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002594};
2595
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002596PyTypeObject PyBufferedRWPair_Type = {
2597 PyVarObject_HEAD_INIT(NULL, 0)
2598 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002599 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002600 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002602 0, /*tp_print*/
2603 0, /*tp_getattr*/
2604 0, /*tp_setattr*/
2605 0, /*tp_compare */
2606 0, /*tp_repr*/
2607 0, /*tp_as_number*/
2608 0, /*tp_as_sequence*/
2609 0, /*tp_as_mapping*/
2610 0, /*tp_hash */
2611 0, /*tp_call*/
2612 0, /*tp_str*/
2613 0, /*tp_getattro*/
2614 0, /*tp_setattro*/
2615 0, /*tp_as_buffer*/
2616 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002617 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002618 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002619 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2620 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002621 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623 0, /* tp_iter */
2624 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002625 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002626 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002627 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002628 0, /* tp_base */
2629 0, /* tp_dict */
2630 0, /* tp_descr_get */
2631 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002632 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002633 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002634 0, /* tp_alloc */
2635 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002636 0, /* tp_free */
2637 0, /* tp_is_gc */
2638 0, /* tp_bases */
2639 0, /* tp_mro */
2640 0, /* tp_cache */
2641 0, /* tp_subclasses */
2642 0, /* tp_weaklist */
2643 0, /* tp_del */
2644 0, /* tp_version_tag */
2645 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002646};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647
2648
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002649static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002651 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2652 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2653 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2654 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2655 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2656 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2657 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002658 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002659 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002660
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002661 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002662
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002663 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002664 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002665 _IO__BUFFERED_TRUNCATE_METHODDEF
2666 _IO__BUFFERED_READ_METHODDEF
2667 _IO__BUFFERED_READ1_METHODDEF
2668 _IO__BUFFERED_READINTO_METHODDEF
2669 _IO__BUFFERED_READINTO1_METHODDEF
2670 _IO__BUFFERED_READLINE_METHODDEF
2671 _IO__BUFFERED_PEEK_METHODDEF
2672 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002673 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002674 {NULL, NULL}
2675};
2676
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002677static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002678 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002679 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002680 {NULL}
2681};
2682
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002683static PyGetSetDef bufferedrandom_getset[] = {
2684 {"closed", (getter)buffered_closed_get, NULL, NULL},
2685 {"name", (getter)buffered_name_get, NULL, NULL},
2686 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002687 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002688};
2689
2690
2691PyTypeObject PyBufferedRandom_Type = {
2692 PyVarObject_HEAD_INIT(NULL, 0)
2693 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002694 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002695 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002696 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002697 0, /*tp_print*/
2698 0, /*tp_getattr*/
2699 0, /*tp_setattr*/
2700 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002701 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002702 0, /*tp_as_number*/
2703 0, /*tp_as_sequence*/
2704 0, /*tp_as_mapping*/
2705 0, /*tp_hash */
2706 0, /*tp_call*/
2707 0, /*tp_str*/
2708 0, /*tp_getattro*/
2709 0, /*tp_setattro*/
2710 0, /*tp_as_buffer*/
2711 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002712 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002713 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002714 (traverseproc)buffered_traverse, /* tp_traverse */
2715 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002716 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002717 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002718 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002719 (iternextfunc)buffered_iternext, /* tp_iternext */
2720 bufferedrandom_methods, /* tp_methods */
2721 bufferedrandom_members, /* tp_members */
2722 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002723 0, /* tp_base */
2724 0, /*tp_dict*/
2725 0, /* tp_descr_get */
2726 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002727 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002728 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002729 0, /* tp_alloc */
2730 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002731 0, /* tp_free */
2732 0, /* tp_is_gc */
2733 0, /* tp_bases */
2734 0, /* tp_mro */
2735 0, /* tp_cache */
2736 0, /* tp_subclasses */
2737 0, /* tp_weaklist */
2738 0, /* tp_del */
2739 0, /* tp_version_tag */
2740 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002741};