blob: ba966f568b399a40391cb5b92e158d27abed43ba [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) \
Miss Islington (bot)22212072021-10-01 13:30:15 -0700344 if (IS_CLOSED(self) & (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000345 PyErr_SetString(PyExc_ValueError, error_msg); \
346 return NULL; \
Miss Islington (bot)22212072021-10-01 13:30:15 -0700347 } \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000348
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000349#define VALID_READ_BUFFER(self) \
350 (self->readable && self->read_end != -1)
351
352#define VALID_WRITE_BUFFER(self) \
353 (self->writable && self->write_end != -1)
354
355#define ADJUST_POSITION(self, _new_pos) \
356 do { \
357 self->pos = _new_pos; \
358 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
359 self->read_end = self->pos; \
360 } while(0)
361
362#define READAHEAD(self) \
363 ((self->readable && VALID_READ_BUFFER(self)) \
364 ? (self->read_end - self->pos) : 0)
365
366#define RAW_OFFSET(self) \
367 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
368 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
369
370#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000371 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000372
373#define MINUS_LAST_BLOCK(self, size) \
374 (self->buffer_mask ? \
375 (size & ~self->buffer_mask) : \
376 (self->buffer_size * (size / self->buffer_size)))
377
378
379static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000380buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000381{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200382 self->finalizing = 1;
383 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000384 return;
385 _PyObject_GC_UNTRACK(self);
386 self->ok = 0;
387 if (self->weakreflist != NULL)
388 PyObject_ClearWeakRefs((PyObject *)self);
389 Py_CLEAR(self->raw);
390 if (self->buffer) {
391 PyMem_Free(self->buffer);
392 self->buffer = NULL;
393 }
394 if (self->lock) {
395 PyThread_free_lock(self->lock);
396 self->lock = NULL;
397 }
398 Py_CLEAR(self->dict);
399 Py_TYPE(self)->tp_free((PyObject *)self);
400}
401
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200402static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200403buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200404{
405 Py_ssize_t res;
406
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200407 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200408 if (self->buffer)
409 res += self->buffer_size;
410 return PyLong_FromSsize_t(res);
411}
412
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000413static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000414buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000415{
416 Py_VISIT(self->raw);
417 Py_VISIT(self->dict);
418 return 0;
419}
420
421static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000422buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000423{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000424 self->ok = 0;
425 Py_CLEAR(self->raw);
426 Py_CLEAR(self->dict);
427 return 0;
428}
429
Antoine Pitroue033e062010-10-29 10:38:18 +0000430/* Because this can call arbitrary code, it shouldn't be called when
431 the refcount is 0 (that is, not directly from tp_dealloc unless
432 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000433static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000434buffered_dealloc_warn(buffered *self, PyObject *source)
435{
436 if (self->ok && self->raw) {
437 PyObject *r;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200438 r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn,
439 source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000440 if (r)
441 Py_DECREF(r);
442 else
443 PyErr_Clear();
444 }
445 Py_RETURN_NONE;
446}
447
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000448/*
449 * _BufferedIOMixin methods
450 * This is not a class, just a collection of methods that will be reused
451 * by BufferedReader and BufferedWriter
452 */
453
454/* Flush and close */
455
456static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000457buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000458{
459 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100460 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461}
462
463static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000464buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000465{
466 int closed;
467 PyObject *res;
468 CHECK_INITIALIZED_INT(self)
469 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
470 if (res == NULL)
471 return -1;
472 closed = PyObject_IsTrue(res);
473 Py_DECREF(res);
474 return closed;
475}
476
477static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000478buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000479{
480 CHECK_INITIALIZED(self)
481 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
482}
483
484static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000485buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000486{
Benjamin Peterson68623612012-12-20 11:53:11 -0600487 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000488 int r;
489
490 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000491 if (!ENTER_BUFFERED(self))
492 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000493
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000494 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000495 if (r < 0)
496 goto end;
497 if (r > 0) {
498 res = Py_None;
499 Py_INCREF(res);
500 goto end;
501 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000502
Antoine Pitrou796564c2013-07-30 19:59:21 +0200503 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000504 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
505 if (r)
506 Py_DECREF(r);
507 else
508 PyErr_Clear();
509 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510 /* flush() will most probably re-take the lock, so drop it first */
511 LEAVE_BUFFERED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100512 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000513 if (!ENTER_BUFFERED(self))
514 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600515 if (res == NULL)
516 PyErr_Fetch(&exc, &val, &tb);
517 else
518 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519
Petr Viktorinffd97532020-02-11 17:46:57 +0100520 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000521
Jesus Ceadc469452012-10-04 12:37:56 +0200522 if (self->buffer) {
523 PyMem_Free(self->buffer);
524 self->buffer = NULL;
525 }
526
Benjamin Peterson68623612012-12-20 11:53:11 -0600527 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300528 _PyErr_ChainExceptions(exc, val, tb);
529 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600530 }
531
Miss Islington (bot)22212072021-10-01 13:30:15 -0700532 self->read_end = 0;
533 self->pos = 0;
534
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000535end:
536 LEAVE_BUFFERED(self)
537 return res;
538}
539
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000540/* detach */
541
542static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200543buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000544{
545 PyObject *raw, *res;
546 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100547 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000548 if (res == NULL)
549 return NULL;
550 Py_DECREF(res);
551 raw = self->raw;
552 self->raw = NULL;
553 self->detached = 1;
554 self->ok = 0;
555 return raw;
556}
557
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000558/* Inquiries */
559
560static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200561buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562{
563 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100564 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565}
566
567static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200568buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100571 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572}
573
574static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200575buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576{
577 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100578 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579}
580
581static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000582buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583{
584 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200585 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586}
587
588static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000589buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590{
591 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200592 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593}
594
595/* Lower-level APIs */
596
597static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200598buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100601 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200605buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100608 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611/* Forward decls */
612static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100613_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000617_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000619_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200621_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000623_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200628static Py_ssize_t
629_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630
631/*
632 * Helpers
633 */
634
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100635/* Sets the current error to BlockingIOError */
636static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200637_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100638{
639 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200640 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100641 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
642 errno, msg, written);
643 if (err)
644 PyErr_SetObject(PyExc_BlockingIOError, err);
645 Py_XDECREF(err);
646}
647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648/* Returns the address of the `written` member if a BlockingIOError was
649 raised, NULL otherwise. The error is always re-raised. */
650static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652{
653 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200654 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655
656 PyErr_Fetch(&t, &v, &tb);
657 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
658 PyErr_Restore(t, v, tb);
659 return NULL;
660 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200661 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662 /* TODO: sanity check (err->written >= 0) */
663 PyErr_Restore(t, v, tb);
664 return &err->written;
665}
666
667static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000668_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000671 PyObject *res;
Petr Viktorinffd97532020-02-11 17:46:57 +0100672 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673 if (res == NULL)
674 return -1;
675 n = PyNumber_AsOff_t(res, PyExc_ValueError);
676 Py_DECREF(res);
677 if (n < 0) {
678 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300679 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000680 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200681 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 return -1;
683 }
684 self->abs_pos = n;
685 return n;
686}
687
688static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000689_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690{
691 PyObject *res, *posobj, *whenceobj;
692 Py_off_t n;
693
694 posobj = PyLong_FromOff_t(target);
695 if (posobj == NULL)
696 return -1;
697 whenceobj = PyLong_FromLong(whence);
698 if (whenceobj == NULL) {
699 Py_DECREF(posobj);
700 return -1;
701 }
702 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
703 posobj, whenceobj, NULL);
704 Py_DECREF(posobj);
705 Py_DECREF(whenceobj);
706 if (res == NULL)
707 return -1;
708 n = PyNumber_AsOff_t(res, PyExc_ValueError);
709 Py_DECREF(res);
710 if (n < 0) {
711 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300712 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000713 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200714 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715 return -1;
716 }
717 self->abs_pos = n;
718 return n;
719}
720
721static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000722_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723{
724 Py_ssize_t n;
725 if (self->buffer_size <= 0) {
726 PyErr_SetString(PyExc_ValueError,
727 "buffer size must be strictly positive");
728 return -1;
729 }
730 if (self->buffer)
731 PyMem_Free(self->buffer);
732 self->buffer = PyMem_Malloc(self->buffer_size);
733 if (self->buffer == NULL) {
734 PyErr_NoMemory();
735 return -1;
736 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000737 if (self->lock)
738 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000739 self->lock = PyThread_allocate_lock();
740 if (self->lock == NULL) {
741 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
742 return -1;
743 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000744 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000745 /* Find out whether buffer_size is a power of 2 */
746 /* XXX is this optimization useful? */
747 for (n = self->buffer_size - 1; n & 1; n >>= 1)
748 ;
749 if (n == 0)
750 self->buffer_mask = self->buffer_size - 1;
751 else
752 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000753 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 PyErr_Clear();
755 return 0;
756}
757
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300758/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000759 clears the error indicator), 0 otherwise.
760 Should only be called when PyErr_Occurred() is true.
761*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700762int
763_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000764{
765 static PyObject *eintr_int = NULL;
766 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300767 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000768
769 if (eintr_int == NULL) {
770 eintr_int = PyLong_FromLong(EINTR);
771 assert(eintr_int != NULL);
772 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300773 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000774 return 0;
775 PyErr_Fetch(&typ, &val, &tb);
776 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300777 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000778 assert(env_err != NULL);
779 if (env_err->myerrno != NULL &&
780 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
781 Py_DECREF(typ);
782 Py_DECREF(val);
783 Py_XDECREF(tb);
784 return 1;
785 }
786 /* This silences any error set by PyObject_RichCompareBool() */
787 PyErr_Restore(typ, val, tb);
788 return 0;
789}
790
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000791/*
792 * Shared methods and wrappers
793 */
794
795static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200796buffered_flush_and_rewind_unlocked(buffered *self)
797{
798 PyObject *res;
799
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100800 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200801 if (res == NULL)
802 return NULL;
803 Py_DECREF(res);
804
805 if (self->readable) {
806 /* Rewind the raw stream so that its position corresponds to
807 the current logical position. */
808 Py_off_t n;
809 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
810 _bufferedreader_reset_buf(self);
811 if (n == -1)
812 return NULL;
813 }
814 Py_RETURN_NONE;
815}
816
817static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000818buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819{
820 PyObject *res;
821
822 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000823 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000824
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000825 if (!ENTER_BUFFERED(self))
826 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200827 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000828 LEAVE_BUFFERED(self)
829
830 return res;
831}
832
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300833/*[clinic input]
834_io._Buffered.peek
835 size: Py_ssize_t = 0
836 /
837
838[clinic start generated code]*/
839
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000840static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300841_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
842/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000844 PyObject *res = NULL;
845
846 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300847 CHECK_CLOSED(self, "peek of closed file")
848
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000849 if (!ENTER_BUFFERED(self))
850 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851
852 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200853 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000854 if (res == NULL)
855 goto end;
856 Py_CLEAR(res);
857 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200858 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859
860end:
861 LEAVE_BUFFERED(self)
862 return res;
863}
864
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300865/*[clinic input]
866_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300867 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300868 /
869[clinic start generated code]*/
870
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300872_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300873/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000874{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875 PyObject *res;
876
877 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000878 if (n < -1) {
879 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000880 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881 return NULL;
882 }
883
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000884 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000886 if (n == -1) {
887 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000888 if (!ENTER_BUFFERED(self))
889 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000890 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000891 }
892 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000893 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200894 if (res != Py_None)
895 return res;
896 Py_DECREF(res);
897 if (!ENTER_BUFFERED(self))
898 return NULL;
899 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000900 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901
Antoine Pitroue05565e2011-08-20 14:39:23 +0200902 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903 return res;
904}
905
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300906/*[clinic input]
907_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000908 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300909 /
910[clinic start generated code]*/
911
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300913_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000914/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300916 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 PyObject *res = NULL;
918
919 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000921 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300923
924 CHECK_CLOSED(self, "read of closed file")
925
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000926 if (n == 0)
927 return PyBytes_FromStringAndSize(NULL, 0);
928
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929 /* Return up to n bytes. If at least one byte is buffered, we
930 only return buffered bytes. Otherwise, we do one raw read. */
931
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
933 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100934 n = Py_MIN(have, n);
935 res = _bufferedreader_read_fast(self, n);
936 assert(res != Py_None);
937 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100939 res = PyBytes_FromStringAndSize(NULL, n);
940 if (res == NULL)
941 return NULL;
942 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200943 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100944 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200945 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000946 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100947 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
948 LEAVE_BUFFERED(self)
949 if (r == -1) {
950 Py_DECREF(res);
951 return NULL;
952 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 if (r == -2)
954 r = 0;
955 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100956 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 return res;
958}
959
960static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300961_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200963 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964 PyObject *res = NULL;
965
966 CHECK_INITIALIZED(self)
Philipp Gesangcb1c0742020-02-04 22:25:16 +0100967 CHECK_CLOSED(self, "readinto of closed file")
Antoine Pitrou3486a982011-05-12 01:57:53 +0200968
Antoine Pitrou3486a982011-05-12 01:57:53 +0200969 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
970 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300971 if (n >= buffer->len) {
972 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
973 self->pos += buffer->len;
974 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200975 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300976 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200977 self->pos += n;
978 written = n;
979 }
980
981 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300982 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200985 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986 if (res == NULL)
987 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000989 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200990
991 _bufferedreader_reset_buf(self);
992 self->pos = 0;
993
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300994 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995 remaining > 0;
996 written += n, remaining -= n) {
997 /* If remaining bytes is larger than internal buffer size, copy
998 * directly into caller's buffer. */
999 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001000 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001001 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001003
1004 /* In readinto1 mode, we do not want to fill the internal
1005 buffer if we already have some data to return */
1006 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001007 n = _bufferedreader_fill_buffer(self);
1008 if (n > 0) {
1009 if (n > remaining)
1010 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001011 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001012 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001013 self->pos += n;
1014 continue; /* short circuit */
1015 }
1016 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001017 else
1018 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001019
Antoine Pitrou3486a982011-05-12 01:57:53 +02001020 if (n == 0 || (n == -2 && written > 0))
1021 break;
1022 if (n < 0) {
1023 if (n == -2) {
1024 Py_INCREF(Py_None);
1025 res = Py_None;
1026 }
1027 goto end;
1028 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001029
Benjamin Petersona96fea02014-06-22 14:17:44 -07001030 /* At most one read in readinto1 mode */
1031 if (readinto1) {
1032 written += n;
1033 break;
1034 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001035 }
1036 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001037
1038end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001039 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001040 return res;
1041}
1042
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001043/*[clinic input]
1044_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001045 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001046 /
1047[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001048
1049static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001050_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001051/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001052{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001053 return _buffered_readinto_generic(self, buffer, 0);
1054}
1055
1056/*[clinic input]
1057_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001058 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001059 /
1060[clinic start generated code]*/
1061
1062static PyObject *
1063_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001064/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001065{
1066 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001067}
1068
1069
1070static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001071_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001072{
1073 PyObject *res = NULL;
1074 PyObject *chunks = NULL;
1075 Py_ssize_t n, written = 0;
1076 const char *start, *s, *end;
1077
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001078 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001080 /* First, try to find a line in the buffer. This can run unlocked because
1081 the calls to the C API are simple enough that they can't trigger
1082 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001083 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1084 if (limit >= 0 && n > limit)
1085 n = limit;
1086 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087 s = memchr(start, '\n', n);
1088 if (s != NULL) {
1089 res = PyBytes_FromStringAndSize(start, s - start + 1);
1090 if (res != NULL)
1091 self->pos += s - start + 1;
1092 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001093 }
1094 if (n == limit) {
1095 res = PyBytes_FromStringAndSize(start, n);
1096 if (res != NULL)
1097 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001098 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099 }
1100
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001101 if (!ENTER_BUFFERED(self))
1102 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001103
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001104 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105 chunks = PyList_New(0);
1106 if (chunks == NULL)
1107 goto end;
1108 if (n > 0) {
1109 res = PyBytes_FromStringAndSize(start, n);
1110 if (res == NULL)
1111 goto end;
1112 if (PyList_Append(chunks, res) < 0) {
1113 Py_CLEAR(res);
1114 goto end;
1115 }
1116 Py_CLEAR(res);
1117 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001118 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 if (limit >= 0)
1120 limit -= n;
1121 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001122 if (self->writable) {
1123 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1124 if (r == NULL)
1125 goto end;
1126 Py_DECREF(r);
1127 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128
1129 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001130 _bufferedreader_reset_buf(self);
1131 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132 if (n == -1)
1133 goto end;
1134 if (n <= 0)
1135 break;
1136 if (limit >= 0 && n > limit)
1137 n = limit;
1138 start = self->buffer;
1139 end = start + n;
1140 s = start;
1141 while (s < end) {
1142 if (*s++ == '\n') {
1143 res = PyBytes_FromStringAndSize(start, s - start);
1144 if (res == NULL)
1145 goto end;
1146 self->pos = s - start;
1147 goto found;
1148 }
1149 }
1150 res = PyBytes_FromStringAndSize(start, n);
1151 if (res == NULL)
1152 goto end;
1153 if (n == limit) {
1154 self->pos = n;
1155 break;
1156 }
1157 if (PyList_Append(chunks, res) < 0) {
1158 Py_CLEAR(res);
1159 goto end;
1160 }
1161 Py_CLEAR(res);
1162 written += n;
1163 if (limit >= 0)
1164 limit -= n;
1165 }
1166found:
1167 if (res != NULL && PyList_Append(chunks, res) < 0) {
1168 Py_CLEAR(res);
1169 goto end;
1170 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001171 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172
1173end:
1174 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001175end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176 Py_XDECREF(chunks);
1177 return res;
1178}
1179
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001180/*[clinic input]
1181_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001182 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001183 /
1184[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001186static PyObject *
1187_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001188/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001189{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001191 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192}
1193
1194
1195static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001196buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197{
1198 Py_off_t pos;
1199
1200 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001201 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202 if (pos == -1)
1203 return NULL;
1204 pos -= RAW_OFFSET(self);
1205 /* TODO: sanity check (pos >= 0) */
1206 return PyLong_FromOff_t(pos);
1207}
1208
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001209/*[clinic input]
1210_io._Buffered.seek
1211 target as targetobj: object
1212 whence: int = 0
1213 /
1214[clinic start generated code]*/
1215
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001216static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001217_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1218/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219{
1220 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001221 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222
1223 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001224
1225 /* Do some error checking instead of trusting OS 'seek()'
1226 ** error detection, just in case.
1227 */
1228 if ((whence < 0 || whence >2)
1229#ifdef SEEK_HOLE
1230 && (whence != SEEK_HOLE)
1231#endif
1232#ifdef SEEK_DATA
1233 && (whence != SEEK_DATA)
1234#endif
1235 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001237 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238 return NULL;
1239 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001240
1241 CHECK_CLOSED(self, "seek of closed file")
1242
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001243 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1244 return NULL;
1245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1247 if (target == -1 && PyErr_Occurred())
1248 return NULL;
1249
Jesus Cea94363612012-06-22 18:32:07 +02001250 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1251 buffer. Other whence values must be managed without this optimization.
1252 Some Operating Systems can provide additional values, like
1253 SEEK_HOLE/SEEK_DATA. */
1254 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001255 Py_off_t current, avail;
1256 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001257 so as to return quickly if possible. Also, we needn't take the
1258 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001259 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001260 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1261 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262 current = RAW_TELL(self);
1263 avail = READAHEAD(self);
1264 if (avail > 0) {
1265 Py_off_t offset;
1266 if (whence == 0)
1267 offset = target - (current - RAW_OFFSET(self));
1268 else
1269 offset = target;
1270 if (offset >= -self->pos && offset <= avail) {
1271 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001272 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 }
1274 }
1275 }
1276
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001277 if (!ENTER_BUFFERED(self))
1278 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001279
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001280 /* Fallback: invoke raw seek() method and clear buffer */
1281 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001282 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 if (res == NULL)
1284 goto end;
1285 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286 }
1287
1288 /* TODO: align on block boundary and read buffer if needed? */
1289 if (whence == 1)
1290 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001291 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 if (n == -1)
1293 goto end;
1294 self->raw_pos = -1;
1295 res = PyLong_FromOff_t(n);
1296 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001297 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298
1299end:
1300 LEAVE_BUFFERED(self)
1301 return res;
1302}
1303
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001304/*[clinic input]
1305_io._Buffered.truncate
1306 pos: object = None
1307 /
1308[clinic start generated code]*/
1309
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001311_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1312/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 PyObject *res = NULL;
1315
1316 CHECK_INITIALIZED(self)
Berker Peksagfd5116c2020-02-21 20:57:26 +03001317 CHECK_CLOSED(self, "truncate of closed file")
1318 if (!self->writable) {
1319 return bufferediobase_unsupported("truncate");
1320 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001321 if (!ENTER_BUFFERED(self))
1322 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001323
Berker Peksagfd5116c2020-02-21 20:57:26 +03001324 res = buffered_flush_and_rewind_unlocked(self);
1325 if (res == NULL) {
1326 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001327 }
Berker Peksagfd5116c2020-02-21 20:57:26 +03001328 Py_CLEAR(res);
1329
Petr Viktorinffd97532020-02-11 17:46:57 +01001330 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331 if (res == NULL)
1332 goto end;
1333 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001334 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 PyErr_Clear();
1336
1337end:
1338 LEAVE_BUFFERED(self)
1339 return res;
1340}
1341
1342static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001343buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001344{
1345 PyObject *line;
1346 PyTypeObject *tp;
1347
1348 CHECK_INITIALIZED(self);
1349
1350 tp = Py_TYPE(self);
1351 if (tp == &PyBufferedReader_Type ||
1352 tp == &PyBufferedRandom_Type) {
1353 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001354 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355 }
1356 else {
Petr Viktorinffd97532020-02-11 17:46:57 +01001357 line = PyObject_CallMethodNoArgs((PyObject *)self,
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001358 _PyIO_str_readline);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001360 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361 "readline() should have returned a bytes object, "
1362 "not '%.200s'", Py_TYPE(line)->tp_name);
1363 Py_DECREF(line);
1364 return NULL;
1365 }
1366 }
1367
1368 if (line == NULL)
1369 return NULL;
1370
1371 if (PyBytes_GET_SIZE(line) == 0) {
1372 /* Reached EOF or would have blocked */
1373 Py_DECREF(line);
1374 return NULL;
1375 }
1376
1377 return line;
1378}
1379
Antoine Pitrou716c4442009-05-23 19:04:03 +00001380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001381buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001382{
1383 PyObject *nameobj, *res;
1384
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001385 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1386 if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001387 return NULL;
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001388 }
1389 /* Ignore ValueError raised if the underlying stream was detached */
1390 PyErr_Clear();
1391 }
1392 if (nameobj == NULL) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001393 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1394 }
1395 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001396 int status = Py_ReprEnter((PyObject *)self);
1397 res = NULL;
1398 if (status == 0) {
1399 res = PyUnicode_FromFormat("<%s name=%R>",
1400 Py_TYPE(self)->tp_name, nameobj);
1401 Py_ReprLeave((PyObject *)self);
1402 }
1403 else if (status > 0) {
1404 PyErr_Format(PyExc_RuntimeError,
1405 "reentrant call inside %s.__repr__",
1406 Py_TYPE(self)->tp_name);
1407 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001408 Py_DECREF(nameobj);
1409 }
1410 return res;
1411}
1412
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001413/*
1414 * class BufferedReader
1415 */
1416
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001417static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001418{
1419 self->read_end = -1;
1420}
1421
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001422/*[clinic input]
1423_io.BufferedReader.__init__
1424 raw: object
1425 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001426
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001427Create a new buffered reader using the given readable raw IO object.
1428[clinic start generated code]*/
1429
1430static int
1431_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1432 Py_ssize_t buffer_size)
1433/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1434{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001436 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001438 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001439 return -1;
1440
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001442 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443 self->buffer_size = buffer_size;
1444 self->readable = 1;
1445 self->writable = 0;
1446
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001447 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001449 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450
Andy Lesterdffe4c02020-03-04 07:15:20 -06001451 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
1452 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001453
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454 self->ok = 1;
1455 return 0;
1456}
1457
1458static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001459_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001460{
1461 Py_buffer buf;
1462 PyObject *memobj, *res;
1463 Py_ssize_t n;
1464 /* NOTE: the buffer needn't be released as its object is NULL. */
1465 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1466 return -1;
1467 memobj = PyMemoryView_FromBuffer(&buf);
1468 if (memobj == NULL)
1469 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001470 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1471 occurs so we needn't do it ourselves.
1472 We then retry reading, ignoring the signal if no handler has
1473 raised (see issue #10956).
1474 */
1475 do {
Petr Viktorinffd97532020-02-11 17:46:57 +01001476 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj);
Gregory P. Smith51359922012-06-23 23:55:39 -07001477 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001478 Py_DECREF(memobj);
1479 if (res == NULL)
1480 return -1;
1481 if (res == Py_None) {
1482 /* Non-blocking stream would have blocked. Special return code! */
1483 Py_DECREF(res);
1484 return -2;
1485 }
1486 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1487 Py_DECREF(res);
David Szotten86663562020-06-16 00:53:57 +01001488
1489 if (n == -1 && PyErr_Occurred()) {
1490 _PyErr_FormatFromCause(
1491 PyExc_OSError,
1492 "raw readinto() failed"
1493 );
1494 return -1;
1495 }
1496
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001497 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001498 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001499 "raw readinto() returned invalid length %zd "
1500 "(should have been between 0 and %zd)", n, len);
1501 return -1;
1502 }
1503 if (n > 0 && self->abs_pos != -1)
1504 self->abs_pos += n;
1505 return n;
1506}
1507
1508static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001509_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001510{
1511 Py_ssize_t start, len, n;
1512 if (VALID_READ_BUFFER(self))
1513 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1514 else
1515 start = 0;
1516 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001517 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001518 if (n <= 0)
1519 return n;
1520 self->read_end = start + n;
1521 self->raw_pos = start + n;
1522 return n;
1523}
1524
1525static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001526_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001527{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001528 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001529 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001530
1531 /* First copy what we have in the current buffer. */
1532 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1533 if (current_size) {
1534 data = PyBytes_FromStringAndSize(
1535 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001536 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001538 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001539 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001540 /* We're going past the buffer's bounds, flush it */
1541 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001542 tmp = buffered_flush_and_rewind_unlocked(self);
1543 if (tmp == NULL)
1544 goto cleanup;
1545 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001546 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001547 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001548
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001549 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1550 goto cleanup;
1551 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001552 if (readall) {
1553 tmp = _PyObject_CallNoArg(readall);
1554 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001555 if (tmp == NULL)
1556 goto cleanup;
1557 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001558 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001559 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001560 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001561 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001562 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001563 } else {
1564 if (tmp != Py_None) {
1565 PyBytes_Concat(&data, tmp);
1566 }
1567 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001568 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001569 goto cleanup;
1570 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001571
1572 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001573 if (chunks == NULL)
1574 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001575
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001576 while (1) {
1577 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001578 if (PyList_Append(chunks, data) < 0)
1579 goto cleanup;
1580 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001582
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 /* Read until EOF or until read() would block. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001584 data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001585 if (data == NULL)
1586 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001587 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001588 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001589 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001590 }
1591 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1592 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001593 res = data;
1594 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595 }
1596 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001597 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1598 res = tmp;
1599 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001600 }
1601 }
1602 current_size += PyBytes_GET_SIZE(data);
1603 if (self->abs_pos != -1)
1604 self->abs_pos += PyBytes_GET_SIZE(data);
1605 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001606cleanup:
1607 /* res is either NULL or a borrowed ref */
1608 Py_XINCREF(res);
1609 Py_XDECREF(data);
1610 Py_XDECREF(tmp);
1611 Py_XDECREF(chunks);
1612 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001613}
1614
1615/* Read n bytes from the buffer if it can, otherwise return None.
1616 This function is simple enough that it can run unlocked. */
1617static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001618_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001619{
1620 Py_ssize_t current_size;
1621
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001622 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1623 if (n <= current_size) {
1624 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001625 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1626 if (res != NULL)
1627 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001628 return res;
1629 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001630 Py_RETURN_NONE;
1631}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001632
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001633/* Generic read function: read from the stream until enough bytes are read,
1634 * or until an EOF occurs or until read() would block.
1635 */
1636static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001637_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001638{
1639 PyObject *res = NULL;
1640 Py_ssize_t current_size, remaining, written;
1641 char *out;
1642
1643 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1644 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001645 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001646
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001647 res = PyBytes_FromStringAndSize(NULL, n);
1648 if (res == NULL)
1649 goto error;
1650 out = PyBytes_AS_STRING(res);
1651 remaining = n;
1652 written = 0;
1653 if (current_size > 0) {
1654 memcpy(out, self->buffer + self->pos, current_size);
1655 remaining -= current_size;
1656 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001657 self->pos += current_size;
1658 }
1659 /* Flush the write buffer if necessary */
1660 if (self->writable) {
1661 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1662 if (r == NULL)
1663 goto error;
1664 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001665 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001666 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001667 while (remaining > 0) {
1668 /* We want to read a whole block at the end into buffer.
1669 If we had readv() we could do this in one pass. */
1670 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1671 if (r == 0)
1672 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001673 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001674 if (r == -1)
1675 goto error;
1676 if (r == 0 || r == -2) {
1677 /* EOF occurred or read() would block. */
1678 if (r == 0 || written > 0) {
1679 if (_PyBytes_Resize(&res, written))
1680 goto error;
1681 return res;
1682 }
1683 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001684 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685 }
1686 remaining -= r;
1687 written += r;
1688 }
1689 assert(remaining <= self->buffer_size);
1690 self->pos = 0;
1691 self->raw_pos = 0;
1692 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001693 /* NOTE: when the read is satisfied, we avoid issuing any additional
1694 reads, which could block indefinitely (e.g. on a socket).
1695 See issue #9550. */
1696 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001697 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001698 if (r == -1)
1699 goto error;
1700 if (r == 0 || r == -2) {
1701 /* EOF occurred or read() would block. */
1702 if (r == 0 || written > 0) {
1703 if (_PyBytes_Resize(&res, written))
1704 goto error;
1705 return res;
1706 }
1707 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001708 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001709 }
1710 if (remaining > r) {
1711 memcpy(out + written, self->buffer + self->pos, r);
1712 written += r;
1713 self->pos += r;
1714 remaining -= r;
1715 }
1716 else if (remaining > 0) {
1717 memcpy(out + written, self->buffer + self->pos, remaining);
1718 written += remaining;
1719 self->pos += remaining;
1720 remaining = 0;
1721 }
1722 if (remaining == 0)
1723 break;
1724 }
1725
1726 return res;
1727
1728error:
1729 Py_XDECREF(res);
1730 return NULL;
1731}
1732
1733static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001734_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001735{
1736 Py_ssize_t have, r;
1737
1738 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1739 /* Constraints:
1740 1. we don't want to advance the file position.
1741 2. we don't want to lose block alignment, so we can't shift the buffer
1742 to make some place.
1743 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1744 */
1745 if (have > 0) {
1746 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1747 }
1748
1749 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001750 _bufferedreader_reset_buf(self);
1751 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001752 if (r == -1)
1753 return NULL;
1754 if (r == -2)
1755 r = 0;
1756 self->pos = 0;
1757 return PyBytes_FromStringAndSize(self->buffer, r);
1758}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759
1760
Benjamin Peterson59406a92009-03-26 17:10:29 +00001761
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762/*
1763 * class BufferedWriter
1764 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001765static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001766_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767{
1768 self->write_pos = 0;
1769 self->write_end = -1;
1770}
1771
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001772/*[clinic input]
1773_io.BufferedWriter.__init__
1774 raw: object
1775 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001777A buffer for a writeable sequential RawIO object.
1778
1779The constructor creates a BufferedWriter for the given writeable raw
1780stream. If the buffer_size is not given, it defaults to
1781DEFAULT_BUFFER_SIZE.
1782[clinic start generated code]*/
1783
1784static int
1785_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1786 Py_ssize_t buffer_size)
1787/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1788{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001790 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001792 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 return -1;
1794
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001796 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797 self->readable = 0;
1798 self->writable = 1;
1799
1800 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001801 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001803 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 self->pos = 0;
1805
Andy Lesterdffe4c02020-03-04 07:15:20 -06001806 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
1807 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001808
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 self->ok = 1;
1810 return 0;
1811}
1812
1813static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001814_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815{
1816 Py_buffer buf;
1817 PyObject *memobj, *res;
1818 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001819 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 /* NOTE: the buffer needn't be released as its object is NULL. */
1821 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1822 return -1;
1823 memobj = PyMemoryView_FromBuffer(&buf);
1824 if (memobj == NULL)
1825 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001826 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1827 occurs so we needn't do it ourselves.
1828 We then retry writing, ignoring the signal if no handler has
1829 raised (see issue #10956).
1830 */
1831 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001832 errno = 0;
Petr Viktorinffd97532020-02-11 17:46:57 +01001833 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001834 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001835 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 Py_DECREF(memobj);
1837 if (res == NULL)
1838 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001839 if (res == Py_None) {
1840 /* Non-blocking stream would have blocked. Special return code!
1841 Being paranoid we reset errno in case it is changed by code
1842 triggered by a decref. errno is used by _set_BlockingIOError(). */
1843 Py_DECREF(res);
1844 errno = errnum;
1845 return -2;
1846 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1848 Py_DECREF(res);
1849 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001850 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851 "raw write() returned invalid length %zd "
1852 "(should have been between 0 and %zd)", n, len);
1853 return -1;
1854 }
1855 if (n > 0 && self->abs_pos != -1)
1856 self->abs_pos += n;
1857 return n;
1858}
1859
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001860static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001861_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862{
1863 Py_ssize_t written = 0;
1864 Py_off_t n, rewind;
1865
1866 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1867 goto end;
1868 /* First, rewind */
1869 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1870 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001871 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872 if (n < 0) {
1873 goto error;
1874 }
1875 self->raw_pos -= rewind;
1876 }
1877 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001878 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001879 self->buffer + self->write_pos,
1880 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1881 Py_off_t, Py_ssize_t));
1882 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001883 goto error;
1884 }
1885 else if (n == -2) {
1886 _set_BlockingIOError("write could not complete without blocking",
1887 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001888 goto error;
1889 }
1890 self->write_pos += n;
1891 self->raw_pos = self->write_pos;
1892 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001893 /* Partial writes can return successfully when interrupted by a
1894 signal (see write(2)). We must run signal handlers before
1895 blocking another time, possibly indefinitely. */
1896 if (PyErr_CheckSignals() < 0)
1897 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898 }
1899
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900
1901end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301902 /* This ensures that after return from this function,
1903 VALID_WRITE_BUFFER(self) returns false.
1904
1905 This is a required condition because when a tell() is called
1906 after flushing and if VALID_READ_BUFFER(self) is false, we need
1907 VALID_WRITE_BUFFER(self) to be false to have
1908 RAW_OFFSET(self) == 0.
1909
1910 Issue: https://bugs.python.org/issue32228 */
1911 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912 Py_RETURN_NONE;
1913
1914error:
1915 return NULL;
1916}
1917
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001918/*[clinic input]
1919_io.BufferedWriter.write
1920 buffer: Py_buffer
1921 /
1922[clinic start generated code]*/
1923
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001925_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1926/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001927{
1928 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001929 Py_ssize_t written, avail, remaining;
1930 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001931
1932 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001934 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001935 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936
benfogle9703f092017-11-10 16:03:40 -05001937 /* Issue #31976: Check for closed file after acquiring the lock. Another
1938 thread could be holding the lock while closing the file. */
1939 if (IS_CLOSED(self)) {
1940 PyErr_SetString(PyExc_ValueError, "write to closed file");
1941 goto error;
1942 }
1943
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 /* Fast path: the data to write can be fully buffered. */
1945 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1946 self->pos = 0;
1947 self->raw_pos = 0;
1948 }
1949 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001950 if (buffer->len <= avail) {
1951 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001952 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001953 self->write_pos = self->pos;
1954 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001955 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001956 if (self->pos > self->write_end)
1957 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001958 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001959 goto end;
1960 }
1961
1962 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001963 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001965 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966 if (w == NULL)
1967 goto error;
1968 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001969 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 /* Make some place by shifting the buffer. */
1971 assert(VALID_WRITE_BUFFER(self));
1972 memmove(self->buffer, self->buffer + self->write_pos,
1973 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1974 Py_off_t, Py_ssize_t));
1975 self->write_end -= self->write_pos;
1976 self->raw_pos -= self->write_pos;
1977 self->pos -= self->write_pos;
1978 self->write_pos = 0;
1979 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1980 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001981 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982 /* Everything can be buffered */
1983 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001984 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1985 self->write_end += buffer->len;
1986 self->pos += buffer->len;
1987 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988 goto end;
1989 }
1990 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001991 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001992 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001993 self->pos += avail;
1994 /* XXX Modifying the existing exception e using the pointer w
1995 will change e.characters_written but not e.args[2].
1996 Therefore we just replace with a new error. */
1997 _set_BlockingIOError("write could not complete without blocking",
1998 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 goto error;
2000 }
2001 Py_CLEAR(res);
2002
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002003 /* Adjust the raw stream position if it is away from the logical stream
2004 position. This happens if the read buffer has been filled but not
2005 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2006 the raw stream by itself).
2007 Fixes issue #6629.
2008 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002009 offset = RAW_OFFSET(self);
2010 if (offset != 0) {
2011 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002012 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002013 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002014 }
2015
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002016 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002017 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 written = 0;
2019 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002020 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002021 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002023 goto error;
2024 } else if (n == -2) {
2025 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 if (remaining > self->buffer_size) {
2027 /* Can't buffer everything, still buffer as much as possible */
2028 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002029 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 self->raw_pos = 0;
2031 ADJUST_POSITION(self, self->buffer_size);
2032 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002033 written += self->buffer_size;
2034 _set_BlockingIOError("write could not complete without "
2035 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002036 goto error;
2037 }
2038 PyErr_Clear();
2039 break;
2040 }
2041 written += n;
2042 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002043 /* Partial writes can return successfully when interrupted by a
2044 signal (see write(2)). We must run signal handlers before
2045 blocking another time, possibly indefinitely. */
2046 if (PyErr_CheckSignals() < 0)
2047 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048 }
2049 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002050 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002052 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002053 written += remaining;
2054 }
2055 self->write_pos = 0;
2056 /* TODO: sanity check (remaining >= 0) */
2057 self->write_end = remaining;
2058 ADJUST_POSITION(self, remaining);
2059 self->raw_pos = 0;
2060
2061end:
2062 res = PyLong_FromSsize_t(written);
2063
2064error:
2065 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 return res;
2067}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068
2069
2070
2071/*
2072 * BufferedRWPair
2073 */
2074
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075/* XXX The usefulness of this (compared to having two separate IO objects) is
2076 * questionable.
2077 */
2078
2079typedef struct {
2080 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002081 buffered *reader;
2082 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083 PyObject *dict;
2084 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002085} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002087/*[clinic input]
2088_io.BufferedRWPair.__init__
2089 reader: object
2090 writer: object
2091 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2092 /
2093
2094A buffered reader and writer object together.
2095
2096A buffered reader object and buffered writer object put together to
2097form a sequential IO object that can read and write. This is typically
2098used with a socket or two-way pipe.
2099
2100reader and writer are RawIOBase objects that are readable and
2101writeable respectively. If the buffer_size is omitted it defaults to
2102DEFAULT_BUFFER_SIZE.
2103[clinic start generated code]*/
2104
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002105static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002106_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2107 PyObject *writer, Py_ssize_t buffer_size)
2108/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113 return -1;
2114
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002115 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002116 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002117 if (self->reader == NULL)
2118 return -1;
2119
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002121 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002122 if (self->writer == NULL) {
2123 Py_CLEAR(self->reader);
2124 return -1;
2125 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002126
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002127 return 0;
2128}
2129
2130static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002132{
2133 Py_VISIT(self->dict);
2134 return 0;
2135}
2136
2137static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002138bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139{
2140 Py_CLEAR(self->reader);
2141 Py_CLEAR(self->writer);
2142 Py_CLEAR(self->dict);
2143 return 0;
2144}
2145
2146static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002147bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148{
2149 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002150 if (self->weakreflist != NULL)
2151 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152 Py_CLEAR(self->reader);
2153 Py_CLEAR(self->writer);
2154 Py_CLEAR(self->dict);
2155 Py_TYPE(self)->tp_free((PyObject *) self);
2156}
2157
2158static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002159_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002161 PyObject *func, *ret;
2162 if (self == NULL) {
2163 PyErr_SetString(PyExc_ValueError,
2164 "I/O operation on uninitialized object");
2165 return NULL;
2166 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002168 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002170 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 return NULL;
2172 }
2173
2174 ret = PyObject_CallObject(func, args);
2175 Py_DECREF(func);
2176 return ret;
2177}
2178
2179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002182 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183}
2184
2185static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002188 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189}
2190
2191static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002194 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195}
2196
2197static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002198bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002199{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002200 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002201}
2202
2203static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002204bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2205{
2206 return _forward_call(self->reader, &PyId_readinto1, args);
2207}
2208
2209static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002212 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213}
2214
2215static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002216bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217{
jdemeyerfc512e32018-08-02 13:14:54 +02002218 return _forward_call(self->writer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219}
2220
2221static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002222bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
jdemeyerfc512e32018-08-02 13:14:54 +02002224 return _forward_call(self->reader, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225}
2226
2227static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002228bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229{
jdemeyerfc512e32018-08-02 13:14:54 +02002230 return _forward_call(self->writer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002231}
2232
2233static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002234bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002236 PyObject *exc = NULL, *val, *tb;
jdemeyerfc512e32018-08-02 13:14:54 +02002237 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002239 PyErr_Fetch(&exc, &val, &tb);
2240 else
2241 Py_DECREF(ret);
jdemeyerfc512e32018-08-02 13:14:54 +02002242 ret = _forward_call(self->reader, &PyId_close, NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002243 if (exc != NULL) {
2244 _PyErr_ChainExceptions(exc, val, tb);
2245 Py_CLEAR(ret);
2246 }
2247 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002248}
2249
2250static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002251bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002252{
jdemeyerfc512e32018-08-02 13:14:54 +02002253 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254
2255 if (ret != Py_False) {
2256 /* either True or exception */
2257 return ret;
2258 }
2259 Py_DECREF(ret);
2260
jdemeyerfc512e32018-08-02 13:14:54 +02002261 return _forward_call(self->reader, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262}
2263
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002264static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002265bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002266{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002267 if (self->writer == NULL) {
2268 PyErr_SetString(PyExc_RuntimeError,
2269 "the BufferedRWPair object is being garbage-collected");
2270 return NULL;
2271 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002272 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2273}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002274
2275
2276
2277/*
2278 * BufferedRandom
2279 */
2280
2281/*[clinic input]
2282_io.BufferedRandom.__init__
2283 raw: object
2284 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2285
2286A buffered interface to random access streams.
2287
2288The constructor creates a reader and writer for a seekable stream,
2289raw, given in the first argument. If the buffer_size is omitted it
2290defaults to DEFAULT_BUFFER_SIZE.
2291[clinic start generated code]*/
2292
2293static int
2294_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2295 Py_ssize_t buffer_size)
2296/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2297{
2298 self->ok = 0;
2299 self->detached = 0;
2300
2301 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2302 return -1;
2303 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2304 return -1;
2305 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2306 return -1;
2307
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002308 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002309 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002310 self->buffer_size = buffer_size;
2311 self->readable = 1;
2312 self->writable = 1;
2313
2314 if (_buffered_init(self) < 0)
2315 return -1;
2316 _bufferedreader_reset_buf(self);
2317 _bufferedwriter_reset_buf(self);
2318 self->pos = 0;
2319
Andy Lesterdffe4c02020-03-04 07:15:20 -06002320 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
2321 Py_IS_TYPE(raw, &PyFileIO_Type));
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002322
2323 self->ok = 1;
2324 return 0;
2325}
2326
2327#include "clinic/bufferedio.c.h"
2328
2329
2330static PyMethodDef bufferediobase_methods[] = {
2331 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2332 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2333 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2334 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2335 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2336 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2337 {NULL, NULL}
2338};
2339
2340PyTypeObject PyBufferedIOBase_Type = {
2341 PyVarObject_HEAD_INIT(NULL, 0)
2342 "_io._BufferedIOBase", /*tp_name*/
2343 0, /*tp_basicsize*/
2344 0, /*tp_itemsize*/
2345 0, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002346 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002347 0, /*tp_getattr*/
2348 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002349 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002350 0, /*tp_repr*/
2351 0, /*tp_as_number*/
2352 0, /*tp_as_sequence*/
2353 0, /*tp_as_mapping*/
2354 0, /*tp_hash */
2355 0, /*tp_call*/
2356 0, /*tp_str*/
2357 0, /*tp_getattro*/
2358 0, /*tp_setattro*/
2359 0, /*tp_as_buffer*/
Antoine Pitrouada319b2019-05-29 22:12:38 +02002360 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002361 bufferediobase_doc, /* tp_doc */
2362 0, /* tp_traverse */
2363 0, /* tp_clear */
2364 0, /* tp_richcompare */
2365 0, /* tp_weaklistoffset */
2366 0, /* tp_iter */
2367 0, /* tp_iternext */
2368 bufferediobase_methods, /* tp_methods */
2369 0, /* tp_members */
2370 0, /* tp_getset */
2371 &PyIOBase_Type, /* tp_base */
2372 0, /* tp_dict */
2373 0, /* tp_descr_get */
2374 0, /* tp_descr_set */
2375 0, /* tp_dictoffset */
2376 0, /* tp_init */
2377 0, /* tp_alloc */
2378 0, /* tp_new */
2379 0, /* tp_free */
2380 0, /* tp_is_gc */
2381 0, /* tp_bases */
2382 0, /* tp_mro */
2383 0, /* tp_cache */
2384 0, /* tp_subclasses */
2385 0, /* tp_weaklist */
2386 0, /* tp_del */
2387 0, /* tp_version_tag */
2388 0, /* tp_finalize */
2389};
2390
2391
2392static PyMethodDef bufferedreader_methods[] = {
2393 /* BufferedIOMixin methods */
2394 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2395 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2396 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2397 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2398 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002399 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2400 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2401 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002402
2403 _IO__BUFFERED_READ_METHODDEF
2404 _IO__BUFFERED_PEEK_METHODDEF
2405 _IO__BUFFERED_READ1_METHODDEF
2406 _IO__BUFFERED_READINTO_METHODDEF
2407 _IO__BUFFERED_READINTO1_METHODDEF
2408 _IO__BUFFERED_READLINE_METHODDEF
2409 _IO__BUFFERED_SEEK_METHODDEF
2410 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2411 _IO__BUFFERED_TRUNCATE_METHODDEF
2412 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2413 {NULL, NULL}
2414};
2415
2416static PyMemberDef bufferedreader_members[] = {
2417 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2418 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2419 {NULL}
2420};
2421
2422static PyGetSetDef bufferedreader_getset[] = {
2423 {"closed", (getter)buffered_closed_get, NULL, NULL},
2424 {"name", (getter)buffered_name_get, NULL, NULL},
2425 {"mode", (getter)buffered_mode_get, NULL, NULL},
2426 {NULL}
2427};
2428
2429
2430PyTypeObject PyBufferedReader_Type = {
2431 PyVarObject_HEAD_INIT(NULL, 0)
2432 "_io.BufferedReader", /*tp_name*/
2433 sizeof(buffered), /*tp_basicsize*/
2434 0, /*tp_itemsize*/
2435 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002436 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002437 0, /*tp_getattr*/
2438 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002439 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002440 (reprfunc)buffered_repr, /*tp_repr*/
2441 0, /*tp_as_number*/
2442 0, /*tp_as_sequence*/
2443 0, /*tp_as_mapping*/
2444 0, /*tp_hash */
2445 0, /*tp_call*/
2446 0, /*tp_str*/
2447 0, /*tp_getattro*/
2448 0, /*tp_setattro*/
2449 0, /*tp_as_buffer*/
2450 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002451 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002452 _io_BufferedReader___init____doc__, /* tp_doc */
2453 (traverseproc)buffered_traverse, /* tp_traverse */
2454 (inquiry)buffered_clear, /* tp_clear */
2455 0, /* tp_richcompare */
2456 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2457 0, /* tp_iter */
2458 (iternextfunc)buffered_iternext, /* tp_iternext */
2459 bufferedreader_methods, /* tp_methods */
2460 bufferedreader_members, /* tp_members */
2461 bufferedreader_getset, /* tp_getset */
2462 0, /* tp_base */
2463 0, /* tp_dict */
2464 0, /* tp_descr_get */
2465 0, /* tp_descr_set */
2466 offsetof(buffered, dict), /* tp_dictoffset */
2467 _io_BufferedReader___init__, /* tp_init */
2468 0, /* tp_alloc */
2469 PyType_GenericNew, /* tp_new */
2470 0, /* tp_free */
2471 0, /* tp_is_gc */
2472 0, /* tp_bases */
2473 0, /* tp_mro */
2474 0, /* tp_cache */
2475 0, /* tp_subclasses */
2476 0, /* tp_weaklist */
2477 0, /* tp_del */
2478 0, /* tp_version_tag */
2479 0, /* tp_finalize */
2480};
2481
2482
2483static PyMethodDef bufferedwriter_methods[] = {
2484 /* BufferedIOMixin methods */
2485 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2486 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2487 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002488 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2489 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2490 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2491 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002492
2493 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2494 _IO__BUFFERED_TRUNCATE_METHODDEF
2495 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2496 _IO__BUFFERED_SEEK_METHODDEF
2497 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2498 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2499 {NULL, NULL}
2500};
2501
2502static PyMemberDef bufferedwriter_members[] = {
2503 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2504 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2505 {NULL}
2506};
2507
2508static PyGetSetDef bufferedwriter_getset[] = {
2509 {"closed", (getter)buffered_closed_get, NULL, NULL},
2510 {"name", (getter)buffered_name_get, NULL, NULL},
2511 {"mode", (getter)buffered_mode_get, NULL, NULL},
2512 {NULL}
2513};
2514
2515
2516PyTypeObject PyBufferedWriter_Type = {
2517 PyVarObject_HEAD_INIT(NULL, 0)
2518 "_io.BufferedWriter", /*tp_name*/
2519 sizeof(buffered), /*tp_basicsize*/
2520 0, /*tp_itemsize*/
2521 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002522 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002523 0, /*tp_getattr*/
2524 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002525 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002526 (reprfunc)buffered_repr, /*tp_repr*/
2527 0, /*tp_as_number*/
2528 0, /*tp_as_sequence*/
2529 0, /*tp_as_mapping*/
2530 0, /*tp_hash */
2531 0, /*tp_call*/
2532 0, /*tp_str*/
2533 0, /*tp_getattro*/
2534 0, /*tp_setattro*/
2535 0, /*tp_as_buffer*/
2536 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002537 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002538 _io_BufferedWriter___init____doc__, /* tp_doc */
2539 (traverseproc)buffered_traverse, /* tp_traverse */
2540 (inquiry)buffered_clear, /* tp_clear */
2541 0, /* tp_richcompare */
2542 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2543 0, /* tp_iter */
2544 0, /* tp_iternext */
2545 bufferedwriter_methods, /* tp_methods */
2546 bufferedwriter_members, /* tp_members */
2547 bufferedwriter_getset, /* tp_getset */
2548 0, /* tp_base */
2549 0, /* tp_dict */
2550 0, /* tp_descr_get */
2551 0, /* tp_descr_set */
2552 offsetof(buffered, dict), /* tp_dictoffset */
2553 _io_BufferedWriter___init__, /* tp_init */
2554 0, /* tp_alloc */
2555 PyType_GenericNew, /* tp_new */
2556 0, /* tp_free */
2557 0, /* tp_is_gc */
2558 0, /* tp_bases */
2559 0, /* tp_mro */
2560 0, /* tp_cache */
2561 0, /* tp_subclasses */
2562 0, /* tp_weaklist */
2563 0, /* tp_del */
2564 0, /* tp_version_tag */
2565 0, /* tp_finalize */
2566};
2567
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002568
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002569static PyMethodDef bufferedrwpair_methods[] = {
2570 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2571 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2572 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2573 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002574 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002576 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2577 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002578
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002579 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2580 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002581
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002582 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2583 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002584
2585 {NULL, NULL}
2586};
2587
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002588static PyGetSetDef bufferedrwpair_getset[] = {
2589 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002590 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002591};
2592
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002593PyTypeObject PyBufferedRWPair_Type = {
2594 PyVarObject_HEAD_INIT(NULL, 0)
2595 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002596 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002597 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002598 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002599 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002600 0, /*tp_getattr*/
2601 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002602 0, /*tp_as_async*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002603 0, /*tp_repr*/
2604 0, /*tp_as_number*/
2605 0, /*tp_as_sequence*/
2606 0, /*tp_as_mapping*/
2607 0, /*tp_hash */
2608 0, /*tp_call*/
2609 0, /*tp_str*/
2610 0, /*tp_getattro*/
2611 0, /*tp_setattro*/
2612 0, /*tp_as_buffer*/
2613 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002614 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002615 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002616 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2617 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002618 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002619 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002620 0, /* tp_iter */
2621 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002624 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002625 0, /* tp_base */
2626 0, /* tp_dict */
2627 0, /* tp_descr_get */
2628 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002629 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002630 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002631 0, /* tp_alloc */
2632 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002633 0, /* tp_free */
2634 0, /* tp_is_gc */
2635 0, /* tp_bases */
2636 0, /* tp_mro */
2637 0, /* tp_cache */
2638 0, /* tp_subclasses */
2639 0, /* tp_weaklist */
2640 0, /* tp_del */
2641 0, /* tp_version_tag */
2642 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002643};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002644
2645
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002646static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002648 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2649 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2650 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2651 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2652 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2653 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2654 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002655 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002656
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002657 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002658
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002659 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002660 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002661 _IO__BUFFERED_TRUNCATE_METHODDEF
2662 _IO__BUFFERED_READ_METHODDEF
2663 _IO__BUFFERED_READ1_METHODDEF
2664 _IO__BUFFERED_READINTO_METHODDEF
2665 _IO__BUFFERED_READINTO1_METHODDEF
2666 _IO__BUFFERED_READLINE_METHODDEF
2667 _IO__BUFFERED_PEEK_METHODDEF
2668 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002669 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002670 {NULL, NULL}
2671};
2672
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002673static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002674 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002675 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002676 {NULL}
2677};
2678
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002679static PyGetSetDef bufferedrandom_getset[] = {
2680 {"closed", (getter)buffered_closed_get, NULL, NULL},
2681 {"name", (getter)buffered_name_get, NULL, NULL},
2682 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002683 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002684};
2685
2686
2687PyTypeObject PyBufferedRandom_Type = {
2688 PyVarObject_HEAD_INIT(NULL, 0)
2689 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002690 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002691 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002692 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002693 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002694 0, /*tp_getattr*/
2695 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002696 0, /*tp_as_async*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002697 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002698 0, /*tp_as_number*/
2699 0, /*tp_as_sequence*/
2700 0, /*tp_as_mapping*/
2701 0, /*tp_hash */
2702 0, /*tp_call*/
2703 0, /*tp_str*/
2704 0, /*tp_getattro*/
2705 0, /*tp_setattro*/
2706 0, /*tp_as_buffer*/
2707 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002708 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002709 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002710 (traverseproc)buffered_traverse, /* tp_traverse */
2711 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002712 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002713 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002714 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002715 (iternextfunc)buffered_iternext, /* tp_iternext */
2716 bufferedrandom_methods, /* tp_methods */
2717 bufferedrandom_members, /* tp_members */
2718 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719 0, /* tp_base */
2720 0, /*tp_dict*/
2721 0, /* tp_descr_get */
2722 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002723 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002724 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002725 0, /* tp_alloc */
2726 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002727 0, /* tp_free */
2728 0, /* tp_is_gc */
2729 0, /* tp_bases */
2730 0, /* tp_mro */
2731 0, /* tp_cache */
2732 0, /* tp_subclasses */
2733 0, /* tp_weaklist */
2734 0, /* tp_del */
2735 0, /* tp_version_tag */
2736 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002737};