blob: 5984d34cc08290c4b17552ee43f2eb938af3ffa2 [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"
Victor Stinnerbcda8f12018-11-21 22:27:47 +010012#include "pycore_object.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020013#include "structmember.h" // PyMemberDef
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000014#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
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020027_Py_IDENTIFIER(close);
28_Py_IDENTIFIER(_dealloc_warn);
29_Py_IDENTIFIER(flush);
30_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020031_Py_IDENTIFIER(mode);
32_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020033_Py_IDENTIFIER(peek);
34_Py_IDENTIFIER(read);
35_Py_IDENTIFIER(read1);
36_Py_IDENTIFIER(readable);
37_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070038_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020039_Py_IDENTIFIER(writable);
40_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042/*
43 * BufferedIOBase class, inherits from IOBase.
44 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000045PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000046 "Base class for buffered IO objects.\n"
47 "\n"
48 "The main difference with RawIOBase is that the read() method\n"
49 "supports omitting the size argument, and does not have a default\n"
50 "implementation that defers to readinto().\n"
51 "\n"
52 "In addition, read(), readinto() and write() may raise\n"
53 "BlockingIOError if the underlying raw stream is in non-blocking\n"
54 "mode and not ready; unlike their raw counterparts, they will never\n"
55 "return None.\n"
56 "\n"
57 "A typical implementation should not inherit from a RawIOBase\n"
58 "implementation, but wrap one.\n"
59 );
60
61static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030062_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000063{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064 Py_ssize_t len;
65 PyObject *data;
66
Benjamin Petersona96fea02014-06-22 14:17:44 -070067 data = _PyObject_CallMethodId(self,
68 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030069 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030071 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000072
73 if (!PyBytes_Check(data)) {
74 Py_DECREF(data);
75 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030076 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 }
78
Serhiy Storchakafff9a312017-03-21 08:53:25 +020079 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030080 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030081 PyErr_Format(PyExc_ValueError,
82 "read() returned too much data: "
83 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030084 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030085 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030086 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030087 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030088 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090 Py_DECREF(data);
91
92 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000093}
94
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030095/*[clinic input]
96_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070097 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030098 /
99[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700100
101static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300102_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700103/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700104{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300105 return _bufferediobase_readinto_generic(self, buffer, 0);
106}
107
108/*[clinic input]
109_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700110 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300111 /
112[clinic start generated code]*/
113
114static PyObject *
115_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700116/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300117{
118 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700119}
120
121static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100124 _PyIO_State *state = IO_STATE();
125 if (state != NULL)
126 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000127 return NULL;
128}
129
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300130/*[clinic input]
131_io._BufferedIOBase.detach
132
133Disconnect this buffer from its underlying raw stream and return it.
134
135After the raw stream has been detached, the buffer is in an unusable
136state.
137[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000138
139static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300140_io__BufferedIOBase_detach_impl(PyObject *self)
141/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000142{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000144}
145
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000146PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000147 "Read and return up to n bytes.\n"
148 "\n"
149 "If the argument is omitted, None, or negative, reads and\n"
150 "returns all data until EOF.\n"
151 "\n"
152 "If the argument is positive, and the underlying raw stream is\n"
153 "not 'interactive', multiple raw reads may be issued to satisfy\n"
154 "the byte count (unless EOF is reached first). But for\n"
155 "interactive raw streams (as well as sockets and pipes), at most\n"
156 "one raw read will be issued, and a short result does not imply\n"
157 "that EOF is imminent.\n"
158 "\n"
159 "Returns an empty bytes object on EOF.\n"
160 "\n"
161 "Returns None if the underlying raw stream was open in non-blocking\n"
162 "mode and no data is available at the moment.\n");
163
164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000166{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000168}
169
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000170PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171 "Read and return up to n bytes, with at most one read() call\n"
172 "to the underlying raw stream. A short result does not imply\n"
173 "that EOF is imminent.\n"
174 "\n"
175 "Returns an empty bytes object on EOF.\n");
176
177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000178bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000179{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000180 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181}
182
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000183PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000184 "Write the given buffer to the IO stream.\n"
185 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000186 "Returns the number of bytes written, which is always the length of b\n"
187 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188 "\n"
189 "Raises BlockingIOError if the buffer is full and the\n"
190 "underlying raw stream cannot accept more data at the moment.\n");
191
192static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000193bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000194{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000195 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196}
197
198
Antoine Pitrou317def92017-12-13 01:39:26 +0100199typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000200 PyObject_HEAD
201
202 PyObject *raw;
203 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000204 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000205 int readable;
206 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200207 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200208
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000209 /* True if this is a vanilla Buffered object (rather than a user derived
210 class) *and* the raw stream is a vanilla FileIO object. */
211 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212
213 /* Absolute position inside the raw stream (-1 if unknown). */
214 Py_off_t abs_pos;
215
216 /* A static buffer of size `buffer_size` */
217 char *buffer;
218 /* Current logical position in the buffer. */
219 Py_off_t pos;
220 /* Position of the raw stream in the buffer. */
221 Py_off_t raw_pos;
222
223 /* Just after the last buffered byte in the buffer, or -1 if the buffer
224 isn't ready for reading. */
225 Py_off_t read_end;
226
227 /* Just after the last byte actually written */
228 Py_off_t write_pos;
229 /* Just after the last byte waiting to be written, or -1 if the buffer
230 isn't ready for writing. */
231 Py_off_t write_end;
232
233 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200234 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000235
236 Py_ssize_t buffer_size;
237 Py_ssize_t buffer_mask;
238
239 PyObject *dict;
240 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000241} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000242
243/*
244 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000246 * BufferedReader, BufferedWriter and BufferedRandom try to share most
247 methods (this is helped by the members `readable` and `writable`, which
248 are initialized in the respective constructors)
249 * They also share a single buffer for reading and writing. This enables
250 interleaved reads and writes without flushing. It also makes the logic
251 a bit trickier to get right.
252 * The absolute position of the raw stream is cached, if possible, in the
253 `abs_pos` member. It must be updated every time an operation is done
254 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000255 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000256 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000257 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
258 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000259
260 NOTE: we should try to maintain block alignment of reads and writes to the
261 raw stream (according to the buffer size), but for now it is only done
262 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200263
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264*/
265
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000266/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000267
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000268static int
269_enter_buffered_busy(buffered *self)
270{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200271 int relax_locking;
272 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000273 if (self->owner == PyThread_get_thread_ident()) {
274 PyErr_Format(PyExc_RuntimeError,
275 "reentrant call inside %R", self);
276 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000277 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600278 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000279 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200280 if (!relax_locking)
281 st = PyThread_acquire_lock(self->lock, 1);
282 else {
283 /* When finalizing, we don't want a deadlock to happen with daemon
284 * threads abruptly shut down while they owned the lock.
285 * Therefore, only wait for a grace period (1 s.).
286 * Note that non-daemon threads have already exited here, so this
287 * shouldn't affect carefully written threaded I/O code.
288 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700289 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200290 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000291 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200292 if (relax_locking && st != PY_LOCK_ACQUIRED) {
Victor Stinner87d3b9d2020-03-25 19:27:36 +0100293 PyObject *ascii = PyObject_ASCII((PyObject*)self);
294 _Py_FatalErrorFormat(__func__,
295 "could not acquire lock for %s at interpreter "
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200296 "shutdown, possibly due to daemon threads",
Victor Stinner87d3b9d2020-03-25 19:27:36 +0100297 ascii ? PyUnicode_AsUTF8(ascii) : "<ascii(self) failed>");
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200298 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000299 return 1;
300}
301
302#define ENTER_BUFFERED(self) \
303 ( (PyThread_acquire_lock(self->lock, 0) ? \
304 1 : _enter_buffered_busy(self)) \
305 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000306
307#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000308 do { \
309 self->owner = 0; \
310 PyThread_release_lock(self->lock); \
311 } while(0);
312
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000313#define CHECK_INITIALIZED(self) \
314 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000315 if (self->detached) { \
316 PyErr_SetString(PyExc_ValueError, \
317 "raw stream has been detached"); \
318 } else { \
319 PyErr_SetString(PyExc_ValueError, \
320 "I/O operation on uninitialized object"); \
321 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000322 return NULL; \
323 }
324
325#define CHECK_INITIALIZED_INT(self) \
326 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000327 if (self->detached) { \
328 PyErr_SetString(PyExc_ValueError, \
329 "raw stream has been detached"); \
330 } else { \
331 PyErr_SetString(PyExc_ValueError, \
332 "I/O operation on uninitialized object"); \
333 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000334 return -1; \
335 }
336
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000337#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500338 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000339 (self->fast_closed_checks \
340 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500341 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000342
343#define CHECK_CLOSED(self, error_msg) \
344 if (IS_CLOSED(self)) { \
345 PyErr_SetString(PyExc_ValueError, error_msg); \
346 return NULL; \
347 }
348
349
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000350#define VALID_READ_BUFFER(self) \
351 (self->readable && self->read_end != -1)
352
353#define VALID_WRITE_BUFFER(self) \
354 (self->writable && self->write_end != -1)
355
356#define ADJUST_POSITION(self, _new_pos) \
357 do { \
358 self->pos = _new_pos; \
359 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
360 self->read_end = self->pos; \
361 } while(0)
362
363#define READAHEAD(self) \
364 ((self->readable && VALID_READ_BUFFER(self)) \
365 ? (self->read_end - self->pos) : 0)
366
367#define RAW_OFFSET(self) \
368 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
369 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
370
371#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000372 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000373
374#define MINUS_LAST_BLOCK(self, size) \
375 (self->buffer_mask ? \
376 (size & ~self->buffer_mask) : \
377 (self->buffer_size * (size / self->buffer_size)))
378
379
380static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000381buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000382{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200383 self->finalizing = 1;
384 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385 return;
386 _PyObject_GC_UNTRACK(self);
387 self->ok = 0;
388 if (self->weakreflist != NULL)
389 PyObject_ClearWeakRefs((PyObject *)self);
390 Py_CLEAR(self->raw);
391 if (self->buffer) {
392 PyMem_Free(self->buffer);
393 self->buffer = NULL;
394 }
395 if (self->lock) {
396 PyThread_free_lock(self->lock);
397 self->lock = NULL;
398 }
399 Py_CLEAR(self->dict);
400 Py_TYPE(self)->tp_free((PyObject *)self);
401}
402
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200403static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200404buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200405{
406 Py_ssize_t res;
407
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200408 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200409 if (self->buffer)
410 res += self->buffer_size;
411 return PyLong_FromSsize_t(res);
412}
413
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000414static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000415buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416{
417 Py_VISIT(self->raw);
418 Py_VISIT(self->dict);
419 return 0;
420}
421
422static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000423buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000424{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425 self->ok = 0;
426 Py_CLEAR(self->raw);
427 Py_CLEAR(self->dict);
428 return 0;
429}
430
Antoine Pitroue033e062010-10-29 10:38:18 +0000431/* Because this can call arbitrary code, it shouldn't be called when
432 the refcount is 0 (that is, not directly from tp_dealloc unless
433 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000434static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000435buffered_dealloc_warn(buffered *self, PyObject *source)
436{
437 if (self->ok && self->raw) {
438 PyObject *r;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200439 r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn,
440 source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000441 if (r)
442 Py_DECREF(r);
443 else
444 PyErr_Clear();
445 }
446 Py_RETURN_NONE;
447}
448
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000449/*
450 * _BufferedIOMixin methods
451 * This is not a class, just a collection of methods that will be reused
452 * by BufferedReader and BufferedWriter
453 */
454
455/* Flush and close */
456
457static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000458buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000459{
460 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100461 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462}
463
464static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000465buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466{
467 int closed;
468 PyObject *res;
469 CHECK_INITIALIZED_INT(self)
470 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
471 if (res == NULL)
472 return -1;
473 closed = PyObject_IsTrue(res);
474 Py_DECREF(res);
475 return closed;
476}
477
478static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000479buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000480{
481 CHECK_INITIALIZED(self)
482 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
483}
484
485static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000486buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487{
Benjamin Peterson68623612012-12-20 11:53:11 -0600488 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489 int r;
490
491 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000492 if (!ENTER_BUFFERED(self))
493 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000494
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000495 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 if (r < 0)
497 goto end;
498 if (r > 0) {
499 res = Py_None;
500 Py_INCREF(res);
501 goto end;
502 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000503
Antoine Pitrou796564c2013-07-30 19:59:21 +0200504 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000505 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
506 if (r)
507 Py_DECREF(r);
508 else
509 PyErr_Clear();
510 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511 /* flush() will most probably re-take the lock, so drop it first */
512 LEAVE_BUFFERED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100513 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000514 if (!ENTER_BUFFERED(self))
515 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600516 if (res == NULL)
517 PyErr_Fetch(&exc, &val, &tb);
518 else
519 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000520
Petr Viktorinffd97532020-02-11 17:46:57 +0100521 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522
Jesus Ceadc469452012-10-04 12:37:56 +0200523 if (self->buffer) {
524 PyMem_Free(self->buffer);
525 self->buffer = NULL;
526 }
527
Benjamin Peterson68623612012-12-20 11:53:11 -0600528 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300529 _PyErr_ChainExceptions(exc, val, tb);
530 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600531 }
532
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000533end:
534 LEAVE_BUFFERED(self)
535 return res;
536}
537
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000538/* detach */
539
540static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200541buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000542{
543 PyObject *raw, *res;
544 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100545 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000546 if (res == NULL)
547 return NULL;
548 Py_DECREF(res);
549 raw = self->raw;
550 self->raw = NULL;
551 self->detached = 1;
552 self->ok = 0;
553 return raw;
554}
555
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000556/* Inquiries */
557
558static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200559buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000560{
561 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100562 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000563}
564
565static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200566buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000567{
568 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100569 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570}
571
572static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200573buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574{
575 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100576 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000577}
578
579static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000580buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000581{
582 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200583 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584}
585
586static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000587buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000588{
589 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200590 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591}
592
593/* Lower-level APIs */
594
595static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200596buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597{
598 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100599 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600}
601
602static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200603buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604{
605 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100606 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000608
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609/* Forward decls */
610static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100611_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000612static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000617_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200619_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000621_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000622static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000623_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200626static Py_ssize_t
627_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000628
629/*
630 * Helpers
631 */
632
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100633/* Sets the current error to BlockingIOError */
634static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200635_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100636{
637 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200638 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100639 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
640 errno, msg, written);
641 if (err)
642 PyErr_SetObject(PyExc_BlockingIOError, err);
643 Py_XDECREF(err);
644}
645
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646/* Returns the address of the `written` member if a BlockingIOError was
647 raised, NULL otherwise. The error is always re-raised. */
648static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000650{
651 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200652 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653
654 PyErr_Fetch(&t, &v, &tb);
655 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
656 PyErr_Restore(t, v, tb);
657 return NULL;
658 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200659 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660 /* TODO: sanity check (err->written >= 0) */
661 PyErr_Restore(t, v, tb);
662 return &err->written;
663}
664
665static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000666_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000667{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000669 PyObject *res;
Petr Viktorinffd97532020-02-11 17:46:57 +0100670 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671 if (res == NULL)
672 return -1;
673 n = PyNumber_AsOff_t(res, PyExc_ValueError);
674 Py_DECREF(res);
675 if (n < 0) {
676 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300677 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000678 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200679 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680 return -1;
681 }
682 self->abs_pos = n;
683 return n;
684}
685
686static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000687_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688{
689 PyObject *res, *posobj, *whenceobj;
690 Py_off_t n;
691
692 posobj = PyLong_FromOff_t(target);
693 if (posobj == NULL)
694 return -1;
695 whenceobj = PyLong_FromLong(whence);
696 if (whenceobj == NULL) {
697 Py_DECREF(posobj);
698 return -1;
699 }
700 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
701 posobj, whenceobj, NULL);
702 Py_DECREF(posobj);
703 Py_DECREF(whenceobj);
704 if (res == NULL)
705 return -1;
706 n = PyNumber_AsOff_t(res, PyExc_ValueError);
707 Py_DECREF(res);
708 if (n < 0) {
709 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300710 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000711 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200712 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000713 return -1;
714 }
715 self->abs_pos = n;
716 return n;
717}
718
719static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000720_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000721{
722 Py_ssize_t n;
723 if (self->buffer_size <= 0) {
724 PyErr_SetString(PyExc_ValueError,
725 "buffer size must be strictly positive");
726 return -1;
727 }
728 if (self->buffer)
729 PyMem_Free(self->buffer);
730 self->buffer = PyMem_Malloc(self->buffer_size);
731 if (self->buffer == NULL) {
732 PyErr_NoMemory();
733 return -1;
734 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000735 if (self->lock)
736 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000737 self->lock = PyThread_allocate_lock();
738 if (self->lock == NULL) {
739 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
740 return -1;
741 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000742 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000743 /* Find out whether buffer_size is a power of 2 */
744 /* XXX is this optimization useful? */
745 for (n = self->buffer_size - 1; n & 1; n >>= 1)
746 ;
747 if (n == 0)
748 self->buffer_mask = self->buffer_size - 1;
749 else
750 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000751 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000752 PyErr_Clear();
753 return 0;
754}
755
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300756/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000757 clears the error indicator), 0 otherwise.
758 Should only be called when PyErr_Occurred() is true.
759*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700760int
761_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000762{
763 static PyObject *eintr_int = NULL;
764 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300765 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000766
767 if (eintr_int == NULL) {
768 eintr_int = PyLong_FromLong(EINTR);
769 assert(eintr_int != NULL);
770 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300771 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000772 return 0;
773 PyErr_Fetch(&typ, &val, &tb);
774 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300775 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000776 assert(env_err != NULL);
777 if (env_err->myerrno != NULL &&
778 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
779 Py_DECREF(typ);
780 Py_DECREF(val);
781 Py_XDECREF(tb);
782 return 1;
783 }
784 /* This silences any error set by PyObject_RichCompareBool() */
785 PyErr_Restore(typ, val, tb);
786 return 0;
787}
788
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000789/*
790 * Shared methods and wrappers
791 */
792
793static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200794buffered_flush_and_rewind_unlocked(buffered *self)
795{
796 PyObject *res;
797
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100798 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200799 if (res == NULL)
800 return NULL;
801 Py_DECREF(res);
802
803 if (self->readable) {
804 /* Rewind the raw stream so that its position corresponds to
805 the current logical position. */
806 Py_off_t n;
807 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
808 _bufferedreader_reset_buf(self);
809 if (n == -1)
810 return NULL;
811 }
812 Py_RETURN_NONE;
813}
814
815static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000816buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000817{
818 PyObject *res;
819
820 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000821 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000823 if (!ENTER_BUFFERED(self))
824 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200825 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000826 LEAVE_BUFFERED(self)
827
828 return res;
829}
830
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300831/*[clinic input]
832_io._Buffered.peek
833 size: Py_ssize_t = 0
834 /
835
836[clinic start generated code]*/
837
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000838static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300839_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
840/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000842 PyObject *res = NULL;
843
844 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300845 CHECK_CLOSED(self, "peek of closed file")
846
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000847 if (!ENTER_BUFFERED(self))
848 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849
850 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200851 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852 if (res == NULL)
853 goto end;
854 Py_CLEAR(res);
855 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200856 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000857
858end:
859 LEAVE_BUFFERED(self)
860 return res;
861}
862
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300863/*[clinic input]
864_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300865 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300866 /
867[clinic start generated code]*/
868
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000869static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300870_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300871/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000872{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000873 PyObject *res;
874
875 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876 if (n < -1) {
877 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000878 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000879 return NULL;
880 }
881
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000882 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000883
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000884 if (n == -1) {
885 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000886 if (!ENTER_BUFFERED(self))
887 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000888 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000889 }
890 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000891 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200892 if (res != Py_None)
893 return res;
894 Py_DECREF(res);
895 if (!ENTER_BUFFERED(self))
896 return NULL;
897 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000898 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899
Antoine Pitroue05565e2011-08-20 14:39:23 +0200900 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901 return res;
902}
903
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300904/*[clinic input]
905_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000906 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300907 /
908[clinic start generated code]*/
909
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000910static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300911_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000912/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300914 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915 PyObject *res = NULL;
916
917 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000918 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000919 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300921
922 CHECK_CLOSED(self, "read of closed file")
923
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 if (n == 0)
925 return PyBytes_FromStringAndSize(NULL, 0);
926
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927 /* Return up to n bytes. If at least one byte is buffered, we
928 only return buffered bytes. Otherwise, we do one raw read. */
929
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
931 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100932 n = Py_MIN(have, n);
933 res = _bufferedreader_read_fast(self, n);
934 assert(res != Py_None);
935 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100937 res = PyBytes_FromStringAndSize(NULL, n);
938 if (res == NULL)
939 return NULL;
940 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200941 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100942 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200943 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000944 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100945 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
946 LEAVE_BUFFERED(self)
947 if (r == -1) {
948 Py_DECREF(res);
949 return NULL;
950 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000951 if (r == -2)
952 r = 0;
953 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000955 return res;
956}
957
958static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300959_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200961 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 PyObject *res = NULL;
963
964 CHECK_INITIALIZED(self)
Philipp Gesangcb1c0742020-02-04 22:25:16 +0100965 CHECK_CLOSED(self, "readinto of closed file")
Antoine Pitrou3486a982011-05-12 01:57:53 +0200966
Antoine Pitrou3486a982011-05-12 01:57:53 +0200967 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
968 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300969 if (n >= buffer->len) {
970 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
971 self->pos += buffer->len;
972 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200973 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300974 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200975 self->pos += n;
976 written = n;
977 }
978
979 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300980 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200981
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200983 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 if (res == NULL)
985 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200986 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988
989 _bufferedreader_reset_buf(self);
990 self->pos = 0;
991
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300992 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200993 remaining > 0;
994 written += n, remaining -= n) {
995 /* If remaining bytes is larger than internal buffer size, copy
996 * directly into caller's buffer. */
997 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300998 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200999 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001000 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001001
1002 /* In readinto1 mode, we do not want to fill the internal
1003 buffer if we already have some data to return */
1004 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001005 n = _bufferedreader_fill_buffer(self);
1006 if (n > 0) {
1007 if (n > remaining)
1008 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001009 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001010 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001011 self->pos += n;
1012 continue; /* short circuit */
1013 }
1014 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001015 else
1016 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001017
Antoine Pitrou3486a982011-05-12 01:57:53 +02001018 if (n == 0 || (n == -2 && written > 0))
1019 break;
1020 if (n < 0) {
1021 if (n == -2) {
1022 Py_INCREF(Py_None);
1023 res = Py_None;
1024 }
1025 goto end;
1026 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001027
Benjamin Petersona96fea02014-06-22 14:17:44 -07001028 /* At most one read in readinto1 mode */
1029 if (readinto1) {
1030 written += n;
1031 break;
1032 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001033 }
1034 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001035
1036end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001037 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001038 return res;
1039}
1040
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001041/*[clinic input]
1042_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001043 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001044 /
1045[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001046
1047static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001048_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001049/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001050{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001051 return _buffered_readinto_generic(self, buffer, 0);
1052}
1053
1054/*[clinic input]
1055_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001056 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001057 /
1058[clinic start generated code]*/
1059
1060static PyObject *
1061_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001062/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001063{
1064 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001065}
1066
1067
1068static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001069_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070{
1071 PyObject *res = NULL;
1072 PyObject *chunks = NULL;
1073 Py_ssize_t n, written = 0;
1074 const char *start, *s, *end;
1075
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001076 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001077
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001078 /* First, try to find a line in the buffer. This can run unlocked because
1079 the calls to the C API are simple enough that they can't trigger
1080 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1082 if (limit >= 0 && n > limit)
1083 n = limit;
1084 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001085 s = memchr(start, '\n', n);
1086 if (s != NULL) {
1087 res = PyBytes_FromStringAndSize(start, s - start + 1);
1088 if (res != NULL)
1089 self->pos += s - start + 1;
1090 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001091 }
1092 if (n == limit) {
1093 res = PyBytes_FromStringAndSize(start, n);
1094 if (res != NULL)
1095 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001096 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001097 }
1098
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001099 if (!ENTER_BUFFERED(self))
1100 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001101
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001103 chunks = PyList_New(0);
1104 if (chunks == NULL)
1105 goto end;
1106 if (n > 0) {
1107 res = PyBytes_FromStringAndSize(start, n);
1108 if (res == NULL)
1109 goto end;
1110 if (PyList_Append(chunks, res) < 0) {
1111 Py_CLEAR(res);
1112 goto end;
1113 }
1114 Py_CLEAR(res);
1115 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001116 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001117 if (limit >= 0)
1118 limit -= n;
1119 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001120 if (self->writable) {
1121 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1122 if (r == NULL)
1123 goto end;
1124 Py_DECREF(r);
1125 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126
1127 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001128 _bufferedreader_reset_buf(self);
1129 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001130 if (n == -1)
1131 goto end;
1132 if (n <= 0)
1133 break;
1134 if (limit >= 0 && n > limit)
1135 n = limit;
1136 start = self->buffer;
1137 end = start + n;
1138 s = start;
1139 while (s < end) {
1140 if (*s++ == '\n') {
1141 res = PyBytes_FromStringAndSize(start, s - start);
1142 if (res == NULL)
1143 goto end;
1144 self->pos = s - start;
1145 goto found;
1146 }
1147 }
1148 res = PyBytes_FromStringAndSize(start, n);
1149 if (res == NULL)
1150 goto end;
1151 if (n == limit) {
1152 self->pos = n;
1153 break;
1154 }
1155 if (PyList_Append(chunks, res) < 0) {
1156 Py_CLEAR(res);
1157 goto end;
1158 }
1159 Py_CLEAR(res);
1160 written += n;
1161 if (limit >= 0)
1162 limit -= n;
1163 }
1164found:
1165 if (res != NULL && PyList_Append(chunks, res) < 0) {
1166 Py_CLEAR(res);
1167 goto end;
1168 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001169 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001170
1171end:
1172 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001173end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 Py_XDECREF(chunks);
1175 return res;
1176}
1177
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001178/*[clinic input]
1179_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001180 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001181 /
1182[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001184static PyObject *
1185_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001186/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001187{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001188 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001189 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190}
1191
1192
1193static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001194buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001195{
1196 Py_off_t pos;
1197
1198 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001199 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001200 if (pos == -1)
1201 return NULL;
1202 pos -= RAW_OFFSET(self);
1203 /* TODO: sanity check (pos >= 0) */
1204 return PyLong_FromOff_t(pos);
1205}
1206
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001207/*[clinic input]
1208_io._Buffered.seek
1209 target as targetobj: object
1210 whence: int = 0
1211 /
1212[clinic start generated code]*/
1213
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001214static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001215_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1216/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217{
1218 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001219 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220
1221 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001222
1223 /* Do some error checking instead of trusting OS 'seek()'
1224 ** error detection, just in case.
1225 */
1226 if ((whence < 0 || whence >2)
1227#ifdef SEEK_HOLE
1228 && (whence != SEEK_HOLE)
1229#endif
1230#ifdef SEEK_DATA
1231 && (whence != SEEK_DATA)
1232#endif
1233 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001234 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001235 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 return NULL;
1237 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001238
1239 CHECK_CLOSED(self, "seek of closed file")
1240
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001241 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1242 return NULL;
1243
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1245 if (target == -1 && PyErr_Occurred())
1246 return NULL;
1247
Jesus Cea94363612012-06-22 18:32:07 +02001248 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1249 buffer. Other whence values must be managed without this optimization.
1250 Some Operating Systems can provide additional values, like
1251 SEEK_HOLE/SEEK_DATA. */
1252 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001253 Py_off_t current, avail;
1254 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001255 so as to return quickly if possible. Also, we needn't take the
1256 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001257 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001258 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1259 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260 current = RAW_TELL(self);
1261 avail = READAHEAD(self);
1262 if (avail > 0) {
1263 Py_off_t offset;
1264 if (whence == 0)
1265 offset = target - (current - RAW_OFFSET(self));
1266 else
1267 offset = target;
1268 if (offset >= -self->pos && offset <= avail) {
1269 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001270 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001271 }
1272 }
1273 }
1274
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001275 if (!ENTER_BUFFERED(self))
1276 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001277
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278 /* Fallback: invoke raw seek() method and clear buffer */
1279 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001280 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001281 if (res == NULL)
1282 goto end;
1283 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001284 }
1285
1286 /* TODO: align on block boundary and read buffer if needed? */
1287 if (whence == 1)
1288 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001289 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290 if (n == -1)
1291 goto end;
1292 self->raw_pos = -1;
1293 res = PyLong_FromOff_t(n);
1294 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001295 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296
1297end:
1298 LEAVE_BUFFERED(self)
1299 return res;
1300}
1301
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001302/*[clinic input]
1303_io._Buffered.truncate
1304 pos: object = None
1305 /
1306[clinic start generated code]*/
1307
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001309_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1310/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001312 PyObject *res = NULL;
1313
1314 CHECK_INITIALIZED(self)
Berker Peksagfd5116c2020-02-21 20:57:26 +03001315 CHECK_CLOSED(self, "truncate of closed file")
1316 if (!self->writable) {
1317 return bufferediobase_unsupported("truncate");
1318 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001319 if (!ENTER_BUFFERED(self))
1320 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321
Berker Peksagfd5116c2020-02-21 20:57:26 +03001322 res = buffered_flush_and_rewind_unlocked(self);
1323 if (res == NULL) {
1324 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001325 }
Berker Peksagfd5116c2020-02-21 20:57:26 +03001326 Py_CLEAR(res);
1327
Petr Viktorinffd97532020-02-11 17:46:57 +01001328 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001329 if (res == NULL)
1330 goto end;
1331 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001332 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001333 PyErr_Clear();
1334
1335end:
1336 LEAVE_BUFFERED(self)
1337 return res;
1338}
1339
1340static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001341buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001342{
1343 PyObject *line;
1344 PyTypeObject *tp;
1345
1346 CHECK_INITIALIZED(self);
1347
1348 tp = Py_TYPE(self);
1349 if (tp == &PyBufferedReader_Type ||
1350 tp == &PyBufferedRandom_Type) {
1351 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001352 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001353 }
1354 else {
Petr Viktorinffd97532020-02-11 17:46:57 +01001355 line = PyObject_CallMethodNoArgs((PyObject *)self,
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001356 _PyIO_str_readline);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001357 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001358 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359 "readline() should have returned a bytes object, "
1360 "not '%.200s'", Py_TYPE(line)->tp_name);
1361 Py_DECREF(line);
1362 return NULL;
1363 }
1364 }
1365
1366 if (line == NULL)
1367 return NULL;
1368
1369 if (PyBytes_GET_SIZE(line) == 0) {
1370 /* Reached EOF or would have blocked */
1371 Py_DECREF(line);
1372 return NULL;
1373 }
1374
1375 return line;
1376}
1377
Antoine Pitrou716c4442009-05-23 19:04:03 +00001378static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001379buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001380{
1381 PyObject *nameobj, *res;
1382
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001383 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1384 if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001385 return NULL;
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001386 }
1387 /* Ignore ValueError raised if the underlying stream was detached */
1388 PyErr_Clear();
1389 }
1390 if (nameobj == NULL) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001391 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1392 }
1393 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001394 int status = Py_ReprEnter((PyObject *)self);
1395 res = NULL;
1396 if (status == 0) {
1397 res = PyUnicode_FromFormat("<%s name=%R>",
1398 Py_TYPE(self)->tp_name, nameobj);
1399 Py_ReprLeave((PyObject *)self);
1400 }
1401 else if (status > 0) {
1402 PyErr_Format(PyExc_RuntimeError,
1403 "reentrant call inside %s.__repr__",
1404 Py_TYPE(self)->tp_name);
1405 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001406 Py_DECREF(nameobj);
1407 }
1408 return res;
1409}
1410
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411/*
1412 * class BufferedReader
1413 */
1414
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001415static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416{
1417 self->read_end = -1;
1418}
1419
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001420/*[clinic input]
1421_io.BufferedReader.__init__
1422 raw: object
1423 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001424
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001425Create a new buffered reader using the given readable raw IO object.
1426[clinic start generated code]*/
1427
1428static int
1429_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1430 Py_ssize_t buffer_size)
1431/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1432{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001433 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001434 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001436 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437 return -1;
1438
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001439 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001440 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441 self->buffer_size = buffer_size;
1442 self->readable = 1;
1443 self->writable = 0;
1444
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001445 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001446 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001447 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448
Andy Lesterdffe4c02020-03-04 07:15:20 -06001449 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
1450 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001451
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001452 self->ok = 1;
1453 return 0;
1454}
1455
1456static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001457_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458{
1459 Py_buffer buf;
1460 PyObject *memobj, *res;
1461 Py_ssize_t n;
1462 /* NOTE: the buffer needn't be released as its object is NULL. */
1463 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1464 return -1;
1465 memobj = PyMemoryView_FromBuffer(&buf);
1466 if (memobj == NULL)
1467 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001468 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1469 occurs so we needn't do it ourselves.
1470 We then retry reading, ignoring the signal if no handler has
1471 raised (see issue #10956).
1472 */
1473 do {
Petr Viktorinffd97532020-02-11 17:46:57 +01001474 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj);
Gregory P. Smith51359922012-06-23 23:55:39 -07001475 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001476 Py_DECREF(memobj);
1477 if (res == NULL)
1478 return -1;
1479 if (res == Py_None) {
1480 /* Non-blocking stream would have blocked. Special return code! */
1481 Py_DECREF(res);
1482 return -2;
1483 }
1484 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1485 Py_DECREF(res);
David Szotten86663562020-06-16 00:53:57 +01001486
1487 if (n == -1 && PyErr_Occurred()) {
1488 _PyErr_FormatFromCause(
1489 PyExc_OSError,
1490 "raw readinto() failed"
1491 );
1492 return -1;
1493 }
1494
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001495 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001496 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001497 "raw readinto() returned invalid length %zd "
1498 "(should have been between 0 and %zd)", n, len);
1499 return -1;
1500 }
1501 if (n > 0 && self->abs_pos != -1)
1502 self->abs_pos += n;
1503 return n;
1504}
1505
1506static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001507_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001508{
1509 Py_ssize_t start, len, n;
1510 if (VALID_READ_BUFFER(self))
1511 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1512 else
1513 start = 0;
1514 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001515 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001516 if (n <= 0)
1517 return n;
1518 self->read_end = start + n;
1519 self->raw_pos = start + n;
1520 return n;
1521}
1522
1523static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001524_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001525{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001526 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001527 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001528
1529 /* First copy what we have in the current buffer. */
1530 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1531 if (current_size) {
1532 data = PyBytes_FromStringAndSize(
1533 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001534 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001535 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001536 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001538 /* We're going past the buffer's bounds, flush it */
1539 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001540 tmp = buffered_flush_and_rewind_unlocked(self);
1541 if (tmp == NULL)
1542 goto cleanup;
1543 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001544 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001545 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001546
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001547 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1548 goto cleanup;
1549 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001550 if (readall) {
1551 tmp = _PyObject_CallNoArg(readall);
1552 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001553 if (tmp == NULL)
1554 goto cleanup;
1555 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001556 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001558 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001559 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001560 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001561 } else {
1562 if (tmp != Py_None) {
1563 PyBytes_Concat(&data, tmp);
1564 }
1565 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001566 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001567 goto cleanup;
1568 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001569
1570 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001571 if (chunks == NULL)
1572 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001573
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001574 while (1) {
1575 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001576 if (PyList_Append(chunks, data) < 0)
1577 goto cleanup;
1578 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001579 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001580
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581 /* Read until EOF or until read() would block. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001582 data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001583 if (data == NULL)
1584 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001585 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001587 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001588 }
1589 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1590 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001591 res = data;
1592 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001593 }
1594 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001595 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1596 res = tmp;
1597 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001598 }
1599 }
1600 current_size += PyBytes_GET_SIZE(data);
1601 if (self->abs_pos != -1)
1602 self->abs_pos += PyBytes_GET_SIZE(data);
1603 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001604cleanup:
1605 /* res is either NULL or a borrowed ref */
1606 Py_XINCREF(res);
1607 Py_XDECREF(data);
1608 Py_XDECREF(tmp);
1609 Py_XDECREF(chunks);
1610 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611}
1612
1613/* Read n bytes from the buffer if it can, otherwise return None.
1614 This function is simple enough that it can run unlocked. */
1615static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001616_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001617{
1618 Py_ssize_t current_size;
1619
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1621 if (n <= current_size) {
1622 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001623 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1624 if (res != NULL)
1625 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001626 return res;
1627 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001628 Py_RETURN_NONE;
1629}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001631/* Generic read function: read from the stream until enough bytes are read,
1632 * or until an EOF occurs or until read() would block.
1633 */
1634static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001635_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001636{
1637 PyObject *res = NULL;
1638 Py_ssize_t current_size, remaining, written;
1639 char *out;
1640
1641 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1642 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001643 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001644
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001645 res = PyBytes_FromStringAndSize(NULL, n);
1646 if (res == NULL)
1647 goto error;
1648 out = PyBytes_AS_STRING(res);
1649 remaining = n;
1650 written = 0;
1651 if (current_size > 0) {
1652 memcpy(out, self->buffer + self->pos, current_size);
1653 remaining -= current_size;
1654 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001655 self->pos += current_size;
1656 }
1657 /* Flush the write buffer if necessary */
1658 if (self->writable) {
1659 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1660 if (r == NULL)
1661 goto error;
1662 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001663 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001664 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001665 while (remaining > 0) {
1666 /* We want to read a whole block at the end into buffer.
1667 If we had readv() we could do this in one pass. */
1668 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1669 if (r == 0)
1670 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001671 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001672 if (r == -1)
1673 goto error;
1674 if (r == 0 || r == -2) {
1675 /* EOF occurred or read() would block. */
1676 if (r == 0 || written > 0) {
1677 if (_PyBytes_Resize(&res, written))
1678 goto error;
1679 return res;
1680 }
1681 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001682 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683 }
1684 remaining -= r;
1685 written += r;
1686 }
1687 assert(remaining <= self->buffer_size);
1688 self->pos = 0;
1689 self->raw_pos = 0;
1690 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001691 /* NOTE: when the read is satisfied, we avoid issuing any additional
1692 reads, which could block indefinitely (e.g. on a socket).
1693 See issue #9550. */
1694 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001695 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001696 if (r == -1)
1697 goto error;
1698 if (r == 0 || r == -2) {
1699 /* EOF occurred or read() would block. */
1700 if (r == 0 || written > 0) {
1701 if (_PyBytes_Resize(&res, written))
1702 goto error;
1703 return res;
1704 }
1705 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001706 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001707 }
1708 if (remaining > r) {
1709 memcpy(out + written, self->buffer + self->pos, r);
1710 written += r;
1711 self->pos += r;
1712 remaining -= r;
1713 }
1714 else if (remaining > 0) {
1715 memcpy(out + written, self->buffer + self->pos, remaining);
1716 written += remaining;
1717 self->pos += remaining;
1718 remaining = 0;
1719 }
1720 if (remaining == 0)
1721 break;
1722 }
1723
1724 return res;
1725
1726error:
1727 Py_XDECREF(res);
1728 return NULL;
1729}
1730
1731static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001732_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001733{
1734 Py_ssize_t have, r;
1735
1736 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1737 /* Constraints:
1738 1. we don't want to advance the file position.
1739 2. we don't want to lose block alignment, so we can't shift the buffer
1740 to make some place.
1741 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1742 */
1743 if (have > 0) {
1744 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1745 }
1746
1747 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001748 _bufferedreader_reset_buf(self);
1749 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750 if (r == -1)
1751 return NULL;
1752 if (r == -2)
1753 r = 0;
1754 self->pos = 0;
1755 return PyBytes_FromStringAndSize(self->buffer, r);
1756}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757
1758
Benjamin Peterson59406a92009-03-26 17:10:29 +00001759
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760/*
1761 * class BufferedWriter
1762 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001764_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001765{
1766 self->write_pos = 0;
1767 self->write_end = -1;
1768}
1769
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001770/*[clinic input]
1771_io.BufferedWriter.__init__
1772 raw: object
1773 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001775A buffer for a writeable sequential RawIO object.
1776
1777The constructor creates a BufferedWriter for the given writeable raw
1778stream. If the buffer_size is not given, it defaults to
1779DEFAULT_BUFFER_SIZE.
1780[clinic start generated code]*/
1781
1782static int
1783_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1784 Py_ssize_t buffer_size)
1785/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1786{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001788 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001790 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791 return -1;
1792
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001794 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 self->readable = 0;
1796 self->writable = 1;
1797
1798 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001801 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802 self->pos = 0;
1803
Andy Lesterdffe4c02020-03-04 07:15:20 -06001804 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
1805 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001806
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807 self->ok = 1;
1808 return 0;
1809}
1810
1811static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813{
1814 Py_buffer buf;
1815 PyObject *memobj, *res;
1816 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001817 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818 /* NOTE: the buffer needn't be released as its object is NULL. */
1819 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1820 return -1;
1821 memobj = PyMemoryView_FromBuffer(&buf);
1822 if (memobj == NULL)
1823 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001824 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1825 occurs so we needn't do it ourselves.
1826 We then retry writing, ignoring the signal if no handler has
1827 raised (see issue #10956).
1828 */
1829 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001830 errno = 0;
Petr Viktorinffd97532020-02-11 17:46:57 +01001831 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001832 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001833 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834 Py_DECREF(memobj);
1835 if (res == NULL)
1836 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001837 if (res == Py_None) {
1838 /* Non-blocking stream would have blocked. Special return code!
1839 Being paranoid we reset errno in case it is changed by code
1840 triggered by a decref. errno is used by _set_BlockingIOError(). */
1841 Py_DECREF(res);
1842 errno = errnum;
1843 return -2;
1844 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001845 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1846 Py_DECREF(res);
1847 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001848 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849 "raw write() returned invalid length %zd "
1850 "(should have been between 0 and %zd)", n, len);
1851 return -1;
1852 }
1853 if (n > 0 && self->abs_pos != -1)
1854 self->abs_pos += n;
1855 return n;
1856}
1857
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001859_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001860{
1861 Py_ssize_t written = 0;
1862 Py_off_t n, rewind;
1863
1864 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1865 goto end;
1866 /* First, rewind */
1867 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1868 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001869 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001870 if (n < 0) {
1871 goto error;
1872 }
1873 self->raw_pos -= rewind;
1874 }
1875 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001876 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001877 self->buffer + self->write_pos,
1878 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1879 Py_off_t, Py_ssize_t));
1880 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881 goto error;
1882 }
1883 else if (n == -2) {
1884 _set_BlockingIOError("write could not complete without blocking",
1885 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001886 goto error;
1887 }
1888 self->write_pos += n;
1889 self->raw_pos = self->write_pos;
1890 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001891 /* Partial writes can return successfully when interrupted by a
1892 signal (see write(2)). We must run signal handlers before
1893 blocking another time, possibly indefinitely. */
1894 if (PyErr_CheckSignals() < 0)
1895 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001896 }
1897
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898
1899end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301900 /* This ensures that after return from this function,
1901 VALID_WRITE_BUFFER(self) returns false.
1902
1903 This is a required condition because when a tell() is called
1904 after flushing and if VALID_READ_BUFFER(self) is false, we need
1905 VALID_WRITE_BUFFER(self) to be false to have
1906 RAW_OFFSET(self) == 0.
1907
1908 Issue: https://bugs.python.org/issue32228 */
1909 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001910 Py_RETURN_NONE;
1911
1912error:
1913 return NULL;
1914}
1915
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001916/*[clinic input]
1917_io.BufferedWriter.write
1918 buffer: Py_buffer
1919 /
1920[clinic start generated code]*/
1921
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001922static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001923_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1924/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001925{
1926 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001927 Py_ssize_t written, avail, remaining;
1928 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929
1930 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001931
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001932 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001933 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934
benfogle9703f092017-11-10 16:03:40 -05001935 /* Issue #31976: Check for closed file after acquiring the lock. Another
1936 thread could be holding the lock while closing the file. */
1937 if (IS_CLOSED(self)) {
1938 PyErr_SetString(PyExc_ValueError, "write to closed file");
1939 goto error;
1940 }
1941
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942 /* 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 *
jdemeyerfc512e32018-08-02 13:14:54 +02002214bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215{
jdemeyerfc512e32018-08-02 13:14:54 +02002216 return _forward_call(self->writer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217}
2218
2219static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002220bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221{
jdemeyerfc512e32018-08-02 13:14:54 +02002222 return _forward_call(self->reader, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223}
2224
2225static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002226bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227{
jdemeyerfc512e32018-08-02 13:14:54 +02002228 return _forward_call(self->writer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229}
2230
2231static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002232bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002234 PyObject *exc = NULL, *val, *tb;
jdemeyerfc512e32018-08-02 13:14:54 +02002235 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
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);
jdemeyerfc512e32018-08-02 13:14:54 +02002240 ret = _forward_call(self->reader, &PyId_close, NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002241 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 *
jdemeyerfc512e32018-08-02 13:14:54 +02002249bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250{
jdemeyerfc512e32018-08-02 13:14:54 +02002251 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
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
jdemeyerfc512e32018-08-02 13:14:54 +02002259 return _forward_call(self->reader, &PyId_isatty, NULL);
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
Andy Lesterdffe4c02020-03-04 07:15:20 -06002318 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
2319 Py_IS_TYPE(raw, &PyFileIO_Type));
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002320
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*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002344 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002345 0, /*tp_getattr*/
2346 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002347 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002348 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*/
Antoine Pitrouada319b2019-05-29 22:12:38 +02002358 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002359 bufferediobase_doc, /* tp_doc */
2360 0, /* tp_traverse */
2361 0, /* tp_clear */
2362 0, /* tp_richcompare */
2363 0, /* tp_weaklistoffset */
2364 0, /* tp_iter */
2365 0, /* tp_iternext */
2366 bufferediobase_methods, /* tp_methods */
2367 0, /* tp_members */
2368 0, /* tp_getset */
2369 &PyIOBase_Type, /* tp_base */
2370 0, /* tp_dict */
2371 0, /* tp_descr_get */
2372 0, /* tp_descr_set */
2373 0, /* tp_dictoffset */
2374 0, /* tp_init */
2375 0, /* tp_alloc */
2376 0, /* tp_new */
2377 0, /* tp_free */
2378 0, /* tp_is_gc */
2379 0, /* tp_bases */
2380 0, /* tp_mro */
2381 0, /* tp_cache */
2382 0, /* tp_subclasses */
2383 0, /* tp_weaklist */
2384 0, /* tp_del */
2385 0, /* tp_version_tag */
2386 0, /* tp_finalize */
2387};
2388
2389
2390static PyMethodDef bufferedreader_methods[] = {
2391 /* BufferedIOMixin methods */
2392 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2393 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2394 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2395 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2396 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002397 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2398 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2399 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002400
2401 _IO__BUFFERED_READ_METHODDEF
2402 _IO__BUFFERED_PEEK_METHODDEF
2403 _IO__BUFFERED_READ1_METHODDEF
2404 _IO__BUFFERED_READINTO_METHODDEF
2405 _IO__BUFFERED_READINTO1_METHODDEF
2406 _IO__BUFFERED_READLINE_METHODDEF
2407 _IO__BUFFERED_SEEK_METHODDEF
2408 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2409 _IO__BUFFERED_TRUNCATE_METHODDEF
2410 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2411 {NULL, NULL}
2412};
2413
2414static PyMemberDef bufferedreader_members[] = {
2415 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2416 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2417 {NULL}
2418};
2419
2420static PyGetSetDef bufferedreader_getset[] = {
2421 {"closed", (getter)buffered_closed_get, NULL, NULL},
2422 {"name", (getter)buffered_name_get, NULL, NULL},
2423 {"mode", (getter)buffered_mode_get, NULL, NULL},
2424 {NULL}
2425};
2426
2427
2428PyTypeObject PyBufferedReader_Type = {
2429 PyVarObject_HEAD_INIT(NULL, 0)
2430 "_io.BufferedReader", /*tp_name*/
2431 sizeof(buffered), /*tp_basicsize*/
2432 0, /*tp_itemsize*/
2433 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002434 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002435 0, /*tp_getattr*/
2436 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002437 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002438 (reprfunc)buffered_repr, /*tp_repr*/
2439 0, /*tp_as_number*/
2440 0, /*tp_as_sequence*/
2441 0, /*tp_as_mapping*/
2442 0, /*tp_hash */
2443 0, /*tp_call*/
2444 0, /*tp_str*/
2445 0, /*tp_getattro*/
2446 0, /*tp_setattro*/
2447 0, /*tp_as_buffer*/
2448 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002449 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002450 _io_BufferedReader___init____doc__, /* tp_doc */
2451 (traverseproc)buffered_traverse, /* tp_traverse */
2452 (inquiry)buffered_clear, /* tp_clear */
2453 0, /* tp_richcompare */
2454 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2455 0, /* tp_iter */
2456 (iternextfunc)buffered_iternext, /* tp_iternext */
2457 bufferedreader_methods, /* tp_methods */
2458 bufferedreader_members, /* tp_members */
2459 bufferedreader_getset, /* tp_getset */
2460 0, /* tp_base */
2461 0, /* tp_dict */
2462 0, /* tp_descr_get */
2463 0, /* tp_descr_set */
2464 offsetof(buffered, dict), /* tp_dictoffset */
2465 _io_BufferedReader___init__, /* tp_init */
2466 0, /* tp_alloc */
2467 PyType_GenericNew, /* tp_new */
2468 0, /* tp_free */
2469 0, /* tp_is_gc */
2470 0, /* tp_bases */
2471 0, /* tp_mro */
2472 0, /* tp_cache */
2473 0, /* tp_subclasses */
2474 0, /* tp_weaklist */
2475 0, /* tp_del */
2476 0, /* tp_version_tag */
2477 0, /* tp_finalize */
2478};
2479
2480
2481static PyMethodDef bufferedwriter_methods[] = {
2482 /* BufferedIOMixin methods */
2483 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2484 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2485 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002486 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2487 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2488 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2489 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002490
2491 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2492 _IO__BUFFERED_TRUNCATE_METHODDEF
2493 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2494 _IO__BUFFERED_SEEK_METHODDEF
2495 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2496 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2497 {NULL, NULL}
2498};
2499
2500static PyMemberDef bufferedwriter_members[] = {
2501 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2502 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2503 {NULL}
2504};
2505
2506static PyGetSetDef bufferedwriter_getset[] = {
2507 {"closed", (getter)buffered_closed_get, NULL, NULL},
2508 {"name", (getter)buffered_name_get, NULL, NULL},
2509 {"mode", (getter)buffered_mode_get, NULL, NULL},
2510 {NULL}
2511};
2512
2513
2514PyTypeObject PyBufferedWriter_Type = {
2515 PyVarObject_HEAD_INIT(NULL, 0)
2516 "_io.BufferedWriter", /*tp_name*/
2517 sizeof(buffered), /*tp_basicsize*/
2518 0, /*tp_itemsize*/
2519 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002520 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002521 0, /*tp_getattr*/
2522 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002523 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002524 (reprfunc)buffered_repr, /*tp_repr*/
2525 0, /*tp_as_number*/
2526 0, /*tp_as_sequence*/
2527 0, /*tp_as_mapping*/
2528 0, /*tp_hash */
2529 0, /*tp_call*/
2530 0, /*tp_str*/
2531 0, /*tp_getattro*/
2532 0, /*tp_setattro*/
2533 0, /*tp_as_buffer*/
2534 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002535 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002536 _io_BufferedWriter___init____doc__, /* tp_doc */
2537 (traverseproc)buffered_traverse, /* tp_traverse */
2538 (inquiry)buffered_clear, /* tp_clear */
2539 0, /* tp_richcompare */
2540 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2541 0, /* tp_iter */
2542 0, /* tp_iternext */
2543 bufferedwriter_methods, /* tp_methods */
2544 bufferedwriter_members, /* tp_members */
2545 bufferedwriter_getset, /* tp_getset */
2546 0, /* tp_base */
2547 0, /* tp_dict */
2548 0, /* tp_descr_get */
2549 0, /* tp_descr_set */
2550 offsetof(buffered, dict), /* tp_dictoffset */
2551 _io_BufferedWriter___init__, /* tp_init */
2552 0, /* tp_alloc */
2553 PyType_GenericNew, /* tp_new */
2554 0, /* tp_free */
2555 0, /* tp_is_gc */
2556 0, /* tp_bases */
2557 0, /* tp_mro */
2558 0, /* tp_cache */
2559 0, /* tp_subclasses */
2560 0, /* tp_weaklist */
2561 0, /* tp_del */
2562 0, /* tp_version_tag */
2563 0, /* tp_finalize */
2564};
2565
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567static PyMethodDef bufferedrwpair_methods[] = {
2568 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2569 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2570 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2571 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002572 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002573
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002574 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2575 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002576
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002577 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2578 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2581 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582
2583 {NULL, NULL}
2584};
2585
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002586static PyGetSetDef bufferedrwpair_getset[] = {
2587 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002588 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002589};
2590
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002591PyTypeObject PyBufferedRWPair_Type = {
2592 PyVarObject_HEAD_INIT(NULL, 0)
2593 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002594 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002595 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002596 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002597 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002598 0, /*tp_getattr*/
2599 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002600 0, /*tp_as_async*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002601 0, /*tp_repr*/
2602 0, /*tp_as_number*/
2603 0, /*tp_as_sequence*/
2604 0, /*tp_as_mapping*/
2605 0, /*tp_hash */
2606 0, /*tp_call*/
2607 0, /*tp_str*/
2608 0, /*tp_getattro*/
2609 0, /*tp_setattro*/
2610 0, /*tp_as_buffer*/
2611 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002612 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002613 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002614 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2615 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002617 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002618 0, /* tp_iter */
2619 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002620 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002621 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623 0, /* tp_base */
2624 0, /* tp_dict */
2625 0, /* tp_descr_get */
2626 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002627 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002628 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629 0, /* tp_alloc */
2630 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002631 0, /* tp_free */
2632 0, /* tp_is_gc */
2633 0, /* tp_bases */
2634 0, /* tp_mro */
2635 0, /* tp_cache */
2636 0, /* tp_subclasses */
2637 0, /* tp_weaklist */
2638 0, /* tp_del */
2639 0, /* tp_version_tag */
2640 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002641};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002642
2643
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002644static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002645 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002646 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2647 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2648 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2649 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2650 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2651 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2652 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002653 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002654
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002655 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002656
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002657 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002658 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002659 _IO__BUFFERED_TRUNCATE_METHODDEF
2660 _IO__BUFFERED_READ_METHODDEF
2661 _IO__BUFFERED_READ1_METHODDEF
2662 _IO__BUFFERED_READINTO_METHODDEF
2663 _IO__BUFFERED_READINTO1_METHODDEF
2664 _IO__BUFFERED_READLINE_METHODDEF
2665 _IO__BUFFERED_PEEK_METHODDEF
2666 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002667 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002668 {NULL, NULL}
2669};
2670
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002671static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002672 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002673 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002674 {NULL}
2675};
2676
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002677static PyGetSetDef bufferedrandom_getset[] = {
2678 {"closed", (getter)buffered_closed_get, NULL, NULL},
2679 {"name", (getter)buffered_name_get, NULL, NULL},
2680 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002681 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002682};
2683
2684
2685PyTypeObject PyBufferedRandom_Type = {
2686 PyVarObject_HEAD_INIT(NULL, 0)
2687 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002688 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002689 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002690 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002691 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002692 0, /*tp_getattr*/
2693 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002694 0, /*tp_as_async*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002695 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002696 0, /*tp_as_number*/
2697 0, /*tp_as_sequence*/
2698 0, /*tp_as_mapping*/
2699 0, /*tp_hash */
2700 0, /*tp_call*/
2701 0, /*tp_str*/
2702 0, /*tp_getattro*/
2703 0, /*tp_setattro*/
2704 0, /*tp_as_buffer*/
2705 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002706 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002707 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002708 (traverseproc)buffered_traverse, /* tp_traverse */
2709 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002710 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002711 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002712 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002713 (iternextfunc)buffered_iternext, /* tp_iternext */
2714 bufferedrandom_methods, /* tp_methods */
2715 bufferedrandom_members, /* tp_members */
2716 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002717 0, /* tp_base */
2718 0, /*tp_dict*/
2719 0, /* tp_descr_get */
2720 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002721 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002722 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002723 0, /* tp_alloc */
2724 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002725 0, /* tp_free */
2726 0, /* tp_is_gc */
2727 0, /* tp_bases */
2728 0, /* tp_mro */
2729 0, /* tp_cache */
2730 0, /* tp_subclasses */
2731 0, /* tp_weaklist */
2732 0, /* tp_del */
2733 0, /* tp_version_tag */
2734 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002735};