blob: 4a4a1992dbbb7a5061420db3a4f984ff5a53d675 [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 Stinnerd943d192021-10-12 08:38:19 +020012#include "pycore_call.h" // _PyObject_CallNoArgs()
Victor Stinnerbcda8f12018-11-21 22:27:47 +010013#include "pycore_object.h"
Victor Stinner4a21e572020-04-15 02:35:41 +020014#include "structmember.h" // PyMemberDef
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000015#include "_iomodule.h"
16
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030017/*[clinic input]
18module _io
19class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
20class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
21class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
22class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
23class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
24class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
25[clinic start generated code]*/
26/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
27
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000028/*
29 * BufferedIOBase class, inherits from IOBase.
30 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000031PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000032 "Base class for buffered IO objects.\n"
33 "\n"
34 "The main difference with RawIOBase is that the read() method\n"
35 "supports omitting the size argument, and does not have a default\n"
36 "implementation that defers to readinto().\n"
37 "\n"
38 "In addition, read(), readinto() and write() may raise\n"
39 "BlockingIOError if the underlying raw stream is in non-blocking\n"
40 "mode and not ready; unlike their raw counterparts, they will never\n"
41 "return None.\n"
42 "\n"
43 "A typical implementation should not inherit from a RawIOBase\n"
44 "implementation, but wrap one.\n"
45 );
46
47static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030048_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000049{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000050 Py_ssize_t len;
51 PyObject *data;
52
Eric Snow81c72042022-02-08 13:39:07 -070053 PyObject *attr = readinto1
54 ? &_Py_ID(read1)
55 : &_Py_ID(read);
56 data = _PyObject_CallMethod(self, attr, "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000057 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030058 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000059
60 if (!PyBytes_Check(data)) {
61 Py_DECREF(data);
62 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030063 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064 }
65
Serhiy Storchakafff9a312017-03-21 08:53:25 +020066 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030067 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030068 PyErr_Format(PyExc_ValueError,
69 "read() returned too much data: "
70 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030071 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030072 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030073 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030074 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030075 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000076
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 Py_DECREF(data);
78
79 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080}
81
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030082/*[clinic input]
83_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070084 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030085 /
86[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -070087
88static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030089_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -070090/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -070091{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030092 return _bufferediobase_readinto_generic(self, buffer, 0);
93}
94
95/*[clinic input]
96_io._BufferedIOBase.readinto1
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]*/
100
101static PyObject *
102_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700103/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300104{
105 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700106}
107
108static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000109bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000110{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100111 _PyIO_State *state = IO_STATE();
112 if (state != NULL)
113 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000114 return NULL;
115}
116
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300117/*[clinic input]
118_io._BufferedIOBase.detach
119
120Disconnect this buffer from its underlying raw stream and return it.
121
122After the raw stream has been detached, the buffer is in an unusable
123state.
124[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000125
126static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300127_io__BufferedIOBase_detach_impl(PyObject *self)
128/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000129{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000130 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000131}
132
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000133PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000134 "Read and return up to n bytes.\n"
135 "\n"
136 "If the argument is omitted, None, or negative, reads and\n"
137 "returns all data until EOF.\n"
138 "\n"
139 "If the argument is positive, and the underlying raw stream is\n"
140 "not 'interactive', multiple raw reads may be issued to satisfy\n"
141 "the byte count (unless EOF is reached first). But for\n"
142 "interactive raw streams (as well as sockets and pipes), at most\n"
143 "one raw read will be issued, and a short result does not imply\n"
144 "that EOF is imminent.\n"
145 "\n"
146 "Returns an empty bytes object on EOF.\n"
147 "\n"
148 "Returns None if the underlying raw stream was open in non-blocking\n"
149 "mode and no data is available at the moment.\n");
150
151static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000152bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000153{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000154 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000155}
156
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000157PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000158 "Read and return up to n bytes, with at most one read() call\n"
159 "to the underlying raw stream. A short result does not imply\n"
160 "that EOF is imminent.\n"
161 "\n"
162 "Returns an empty bytes object on EOF.\n");
163
164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000166{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000168}
169
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000170PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171 "Write the given buffer to the IO stream.\n"
172 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000173 "Returns the number of bytes written, which is always the length of b\n"
174 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000175 "\n"
176 "Raises BlockingIOError if the buffer is full and the\n"
177 "underlying raw stream cannot accept more data at the moment.\n");
178
179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000180bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000182 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000183}
184
185
Antoine Pitrou317def92017-12-13 01:39:26 +0100186typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000187 PyObject_HEAD
188
189 PyObject *raw;
190 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000191 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000192 int readable;
193 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200194 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200195
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000196 /* True if this is a vanilla Buffered object (rather than a user derived
197 class) *and* the raw stream is a vanilla FileIO object. */
198 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000199
200 /* Absolute position inside the raw stream (-1 if unknown). */
201 Py_off_t abs_pos;
202
203 /* A static buffer of size `buffer_size` */
204 char *buffer;
205 /* Current logical position in the buffer. */
206 Py_off_t pos;
207 /* Position of the raw stream in the buffer. */
208 Py_off_t raw_pos;
209
210 /* Just after the last buffered byte in the buffer, or -1 if the buffer
211 isn't ready for reading. */
212 Py_off_t read_end;
213
214 /* Just after the last byte actually written */
215 Py_off_t write_pos;
216 /* Just after the last byte waiting to be written, or -1 if the buffer
217 isn't ready for writing. */
218 Py_off_t write_end;
219
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000220 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200221 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000222
223 Py_ssize_t buffer_size;
224 Py_ssize_t buffer_mask;
225
226 PyObject *dict;
227 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000228} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000229
230/*
231 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200232
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000233 * BufferedReader, BufferedWriter and BufferedRandom try to share most
234 methods (this is helped by the members `readable` and `writable`, which
235 are initialized in the respective constructors)
236 * They also share a single buffer for reading and writing. This enables
237 interleaved reads and writes without flushing. It also makes the logic
238 a bit trickier to get right.
239 * The absolute position of the raw stream is cached, if possible, in the
240 `abs_pos` member. It must be updated every time an operation is done
241 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000242 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000243 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000244 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
245 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000246
247 NOTE: we should try to maintain block alignment of reads and writes to the
248 raw stream (according to the buffer size), but for now it is only done
249 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200250
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251*/
252
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000253/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000254
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000255static int
256_enter_buffered_busy(buffered *self)
257{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200258 int relax_locking;
259 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000260 if (self->owner == PyThread_get_thread_ident()) {
261 PyErr_Format(PyExc_RuntimeError,
262 "reentrant call inside %R", self);
263 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000264 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600265 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000266 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200267 if (!relax_locking)
268 st = PyThread_acquire_lock(self->lock, 1);
269 else {
270 /* When finalizing, we don't want a deadlock to happen with daemon
271 * threads abruptly shut down while they owned the lock.
272 * Therefore, only wait for a grace period (1 s.).
273 * Note that non-daemon threads have already exited here, so this
274 * shouldn't affect carefully written threaded I/O code.
275 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700276 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200277 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000278 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200279 if (relax_locking && st != PY_LOCK_ACQUIRED) {
Victor Stinner87d3b9d2020-03-25 19:27:36 +0100280 PyObject *ascii = PyObject_ASCII((PyObject*)self);
281 _Py_FatalErrorFormat(__func__,
282 "could not acquire lock for %s at interpreter "
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200283 "shutdown, possibly due to daemon threads",
Victor Stinner87d3b9d2020-03-25 19:27:36 +0100284 ascii ? PyUnicode_AsUTF8(ascii) : "<ascii(self) failed>");
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200285 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000286 return 1;
287}
288
289#define ENTER_BUFFERED(self) \
290 ( (PyThread_acquire_lock(self->lock, 0) ? \
291 1 : _enter_buffered_busy(self)) \
292 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000293
294#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000295 do { \
296 self->owner = 0; \
297 PyThread_release_lock(self->lock); \
298 } while(0);
299
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000300#define CHECK_INITIALIZED(self) \
301 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000302 if (self->detached) { \
303 PyErr_SetString(PyExc_ValueError, \
304 "raw stream has been detached"); \
305 } else { \
306 PyErr_SetString(PyExc_ValueError, \
307 "I/O operation on uninitialized object"); \
308 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000309 return NULL; \
310 }
311
312#define CHECK_INITIALIZED_INT(self) \
313 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000314 if (self->detached) { \
315 PyErr_SetString(PyExc_ValueError, \
316 "raw stream has been detached"); \
317 } else { \
318 PyErr_SetString(PyExc_ValueError, \
319 "I/O operation on uninitialized object"); \
320 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000321 return -1; \
322 }
323
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000324#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500325 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000326 (self->fast_closed_checks \
327 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500328 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000329
330#define CHECK_CLOSED(self, error_msg) \
Christian Heimes774ef282022-06-20 13:34:40 +0200331 if (IS_CLOSED(self) && (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000332 PyErr_SetString(PyExc_ValueError, error_msg); \
333 return NULL; \
AngstyDucka4503982021-10-02 04:11:08 +0800334 } \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000335
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336#define VALID_READ_BUFFER(self) \
337 (self->readable && self->read_end != -1)
338
339#define VALID_WRITE_BUFFER(self) \
340 (self->writable && self->write_end != -1)
341
342#define ADJUST_POSITION(self, _new_pos) \
343 do { \
344 self->pos = _new_pos; \
345 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
346 self->read_end = self->pos; \
347 } while(0)
348
349#define READAHEAD(self) \
350 ((self->readable && VALID_READ_BUFFER(self)) \
351 ? (self->read_end - self->pos) : 0)
352
353#define RAW_OFFSET(self) \
354 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
355 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
356
357#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000358 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000359
360#define MINUS_LAST_BLOCK(self, size) \
361 (self->buffer_mask ? \
362 (size & ~self->buffer_mask) : \
363 (self->buffer_size * (size / self->buffer_size)))
364
365
366static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000367buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000368{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200369 self->finalizing = 1;
370 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000371 return;
372 _PyObject_GC_UNTRACK(self);
373 self->ok = 0;
374 if (self->weakreflist != NULL)
375 PyObject_ClearWeakRefs((PyObject *)self);
376 Py_CLEAR(self->raw);
377 if (self->buffer) {
378 PyMem_Free(self->buffer);
379 self->buffer = NULL;
380 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000381 if (self->lock) {
382 PyThread_free_lock(self->lock);
383 self->lock = NULL;
384 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385 Py_CLEAR(self->dict);
386 Py_TYPE(self)->tp_free((PyObject *)self);
387}
388
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200389static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200390buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200391{
392 Py_ssize_t res;
393
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200394 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200395 if (self->buffer)
396 res += self->buffer_size;
397 return PyLong_FromSsize_t(res);
398}
399
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000400static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000401buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000402{
403 Py_VISIT(self->raw);
404 Py_VISIT(self->dict);
405 return 0;
406}
407
408static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000409buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000410{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000411 self->ok = 0;
412 Py_CLEAR(self->raw);
413 Py_CLEAR(self->dict);
414 return 0;
415}
416
Antoine Pitroue033e062010-10-29 10:38:18 +0000417/* Because this can call arbitrary code, it shouldn't be called when
418 the refcount is 0 (that is, not directly from tp_dealloc unless
419 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000420static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000421buffered_dealloc_warn(buffered *self, PyObject *source)
422{
423 if (self->ok && self->raw) {
424 PyObject *r;
Eric Snow81c72042022-02-08 13:39:07 -0700425 r = PyObject_CallMethodOneArg(self->raw, &_Py_ID(_dealloc_warn), source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000426 if (r)
427 Py_DECREF(r);
428 else
429 PyErr_Clear();
430 }
431 Py_RETURN_NONE;
432}
433
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000434/*
435 * _BufferedIOMixin methods
436 * This is not a class, just a collection of methods that will be reused
437 * by BufferedReader and BufferedWriter
438 */
439
440/* Flush and close */
441
442static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000443buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000444{
445 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700446 return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(flush));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000447}
448
449static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000450buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000451{
452 int closed;
453 PyObject *res;
454 CHECK_INITIALIZED_INT(self)
Eric Snow1f455362022-02-22 17:23:51 -0700455 res = PyObject_GetAttr(self->raw, &_Py_ID(closed));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456 if (res == NULL)
457 return -1;
458 closed = PyObject_IsTrue(res);
459 Py_DECREF(res);
460 return closed;
461}
462
463static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000464buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000465{
466 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700467 return PyObject_GetAttr(self->raw, &_Py_ID(closed));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000468}
469
470static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000471buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000472{
Benjamin Peterson68623612012-12-20 11:53:11 -0600473 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000474 int r;
475
476 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000477 if (!ENTER_BUFFERED(self))
478 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000479
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000480 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481 if (r < 0)
482 goto end;
483 if (r > 0) {
484 res = Py_None;
485 Py_INCREF(res);
486 goto end;
487 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000488
Antoine Pitrou796564c2013-07-30 19:59:21 +0200489 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000490 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
491 if (r)
492 Py_DECREF(r);
493 else
494 PyErr_Clear();
495 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 /* flush() will most probably re-take the lock, so drop it first */
497 LEAVE_BUFFERED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700498 res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000499 if (!ENTER_BUFFERED(self))
500 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600501 if (res == NULL)
502 PyErr_Fetch(&exc, &val, &tb);
503 else
504 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505
Eric Snow1f455362022-02-22 17:23:51 -0700506 res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(close));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507
Jesus Ceadc469452012-10-04 12:37:56 +0200508 if (self->buffer) {
509 PyMem_Free(self->buffer);
510 self->buffer = NULL;
511 }
512
Benjamin Peterson68623612012-12-20 11:53:11 -0600513 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300514 _PyErr_ChainExceptions(exc, val, tb);
515 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600516 }
517
AngstyDucka4503982021-10-02 04:11:08 +0800518 self->read_end = 0;
519 self->pos = 0;
520
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000521end:
522 LEAVE_BUFFERED(self)
523 return res;
524}
525
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000526/* detach */
527
528static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200529buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000530{
531 PyObject *raw, *res;
532 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700533 res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000534 if (res == NULL)
535 return NULL;
536 Py_DECREF(res);
537 raw = self->raw;
538 self->raw = NULL;
539 self->detached = 1;
540 self->ok = 0;
541 return raw;
542}
543
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000544/* Inquiries */
545
546static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200547buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000548{
549 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700550 return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(seekable));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551}
552
553static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200554buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000555{
556 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700557 return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(readable));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000558}
559
560static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200561buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562{
563 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700564 return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565}
566
567static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000568buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 CHECK_INITIALIZED(self)
Eric Snow81c72042022-02-08 13:39:07 -0700571 return PyObject_GetAttr(self->raw, &_Py_ID(name));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572}
573
574static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000575buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576{
577 CHECK_INITIALIZED(self)
Eric Snow81c72042022-02-08 13:39:07 -0700578 return PyObject_GetAttr(self->raw, &_Py_ID(mode));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579}
580
581/* Lower-level APIs */
582
583static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200584buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700587 return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(fileno));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000588}
589
590static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200591buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
Eric Snow1f455362022-02-22 17:23:51 -0700594 return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(isatty));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000595}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000596
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597/* Forward decls */
598static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100599_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000601_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000603_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200607_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000611_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200614static Py_ssize_t
615_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616
617/*
618 * Helpers
619 */
620
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100621/* Sets the current error to BlockingIOError */
622static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200623_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100624{
625 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200626 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100627 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
628 errno, msg, written);
629 if (err)
630 PyErr_SetObject(PyExc_BlockingIOError, err);
631 Py_XDECREF(err);
632}
633
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000634/* Returns the address of the `written` member if a BlockingIOError was
635 raised, NULL otherwise. The error is always re-raised. */
636static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000637_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000638{
639 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200640 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641
642 PyErr_Fetch(&t, &v, &tb);
643 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
644 PyErr_Restore(t, v, tb);
645 return NULL;
646 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200647 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648 /* TODO: sanity check (err->written >= 0) */
649 PyErr_Restore(t, v, tb);
650 return &err->written;
651}
652
653static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000654_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000657 PyObject *res;
Eric Snow1f455362022-02-22 17:23:51 -0700658 res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(tell));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000659 if (res == NULL)
660 return -1;
661 n = PyNumber_AsOff_t(res, PyExc_ValueError);
662 Py_DECREF(res);
663 if (n < 0) {
664 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300665 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000666 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200667 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668 return -1;
669 }
670 self->abs_pos = n;
671 return n;
672}
673
674static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000675_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000676{
677 PyObject *res, *posobj, *whenceobj;
678 Py_off_t n;
679
680 posobj = PyLong_FromOff_t(target);
681 if (posobj == NULL)
682 return -1;
683 whenceobj = PyLong_FromLong(whence);
684 if (whenceobj == NULL) {
685 Py_DECREF(posobj);
686 return -1;
687 }
Eric Snow1f455362022-02-22 17:23:51 -0700688 res = PyObject_CallMethodObjArgs(self->raw, &_Py_ID(seek),
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689 posobj, whenceobj, NULL);
690 Py_DECREF(posobj);
691 Py_DECREF(whenceobj);
692 if (res == NULL)
693 return -1;
694 n = PyNumber_AsOff_t(res, PyExc_ValueError);
695 Py_DECREF(res);
696 if (n < 0) {
697 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300698 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000699 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200700 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000701 return -1;
702 }
703 self->abs_pos = n;
704 return n;
705}
706
707static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000708_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709{
710 Py_ssize_t n;
711 if (self->buffer_size <= 0) {
712 PyErr_SetString(PyExc_ValueError,
713 "buffer size must be strictly positive");
714 return -1;
715 }
716 if (self->buffer)
717 PyMem_Free(self->buffer);
718 self->buffer = PyMem_Malloc(self->buffer_size);
719 if (self->buffer == NULL) {
720 PyErr_NoMemory();
721 return -1;
722 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000723 if (self->lock)
724 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000725 self->lock = PyThread_allocate_lock();
726 if (self->lock == NULL) {
727 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
728 return -1;
729 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000730 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731 /* Find out whether buffer_size is a power of 2 */
732 /* XXX is this optimization useful? */
733 for (n = self->buffer_size - 1; n & 1; n >>= 1)
734 ;
735 if (n == 0)
736 self->buffer_mask = self->buffer_size - 1;
737 else
738 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000739 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740 PyErr_Clear();
741 return 0;
742}
743
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300744/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000745 clears the error indicator), 0 otherwise.
746 Should only be called when PyErr_Occurred() is true.
747*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700748int
749_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000750{
751 static PyObject *eintr_int = NULL;
752 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300753 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000754
755 if (eintr_int == NULL) {
756 eintr_int = PyLong_FromLong(EINTR);
757 assert(eintr_int != NULL);
758 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300759 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000760 return 0;
761 PyErr_Fetch(&typ, &val, &tb);
762 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300763 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000764 assert(env_err != NULL);
765 if (env_err->myerrno != NULL &&
766 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
767 Py_DECREF(typ);
768 Py_DECREF(val);
769 Py_XDECREF(tb);
770 return 1;
771 }
772 /* This silences any error set by PyObject_RichCompareBool() */
773 PyErr_Restore(typ, val, tb);
774 return 0;
775}
776
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000777/*
778 * Shared methods and wrappers
779 */
780
781static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200782buffered_flush_and_rewind_unlocked(buffered *self)
783{
784 PyObject *res;
785
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100786 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200787 if (res == NULL)
788 return NULL;
789 Py_DECREF(res);
790
791 if (self->readable) {
792 /* Rewind the raw stream so that its position corresponds to
793 the current logical position. */
794 Py_off_t n;
795 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
796 _bufferedreader_reset_buf(self);
797 if (n == -1)
798 return NULL;
799 }
800 Py_RETURN_NONE;
801}
802
803static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000804buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000805{
806 PyObject *res;
807
808 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000809 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000810
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000811 if (!ENTER_BUFFERED(self))
812 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200813 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000814 LEAVE_BUFFERED(self)
815
816 return res;
817}
818
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300819/*[clinic input]
820_io._Buffered.peek
821 size: Py_ssize_t = 0
822 /
823
824[clinic start generated code]*/
825
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000826static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300827_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
828/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000829{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000830 PyObject *res = NULL;
831
832 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300833 CHECK_CLOSED(self, "peek of closed file")
834
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000835 if (!ENTER_BUFFERED(self))
836 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000837
838 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200839 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000840 if (res == NULL)
841 goto end;
842 Py_CLEAR(res);
843 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200844 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000845
846end:
847 LEAVE_BUFFERED(self)
848 return res;
849}
850
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300851/*[clinic input]
852_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300853 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300854 /
855[clinic start generated code]*/
856
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000857static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300858_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300859/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000861 PyObject *res;
862
863 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864 if (n < -1) {
865 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000866 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000867 return NULL;
868 }
869
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000870 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000872 if (n == -1) {
873 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000874 if (!ENTER_BUFFERED(self))
875 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000876 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000877 }
878 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000879 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200880 if (res != Py_None)
881 return res;
882 Py_DECREF(res);
883 if (!ENTER_BUFFERED(self))
884 return NULL;
885 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000886 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887
Antoine Pitroue05565e2011-08-20 14:39:23 +0200888 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889 return res;
890}
891
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300892/*[clinic input]
893_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000894 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300895 /
896[clinic start generated code]*/
897
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000898static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300899_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000900/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300902 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903 PyObject *res = NULL;
904
905 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000906 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000907 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000908 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300909
910 CHECK_CLOSED(self, "read of closed file")
911
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912 if (n == 0)
913 return PyBytes_FromStringAndSize(NULL, 0);
914
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915 /* Return up to n bytes. If at least one byte is buffered, we
916 only return buffered bytes. Otherwise, we do one raw read. */
917
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000918 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
919 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100920 n = Py_MIN(have, n);
921 res = _bufferedreader_read_fast(self, n);
922 assert(res != Py_None);
923 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100925 res = PyBytes_FromStringAndSize(NULL, n);
926 if (res == NULL)
927 return NULL;
928 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200929 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100930 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200931 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000932 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100933 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
934 LEAVE_BUFFERED(self)
935 if (r == -1) {
936 Py_DECREF(res);
937 return NULL;
938 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 if (r == -2)
940 r = 0;
941 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100942 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943 return res;
944}
945
946static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300947_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200949 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950 PyObject *res = NULL;
951
952 CHECK_INITIALIZED(self)
Philipp Gesangcb1c0742020-02-04 22:25:16 +0100953 CHECK_CLOSED(self, "readinto of closed file")
Antoine Pitrou3486a982011-05-12 01:57:53 +0200954
Antoine Pitrou3486a982011-05-12 01:57:53 +0200955 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
956 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300957 if (n >= buffer->len) {
958 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
959 self->pos += buffer->len;
960 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200961 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300962 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200963 self->pos += n;
964 written = n;
965 }
966
967 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300968 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200969
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000970 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200971 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 if (res == NULL)
973 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200974 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000975 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200976
977 _bufferedreader_reset_buf(self);
978 self->pos = 0;
979
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300980 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200981 remaining > 0;
982 written += n, remaining -= n) {
983 /* If remaining bytes is larger than internal buffer size, copy
984 * directly into caller's buffer. */
985 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300986 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200987 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988 }
Benjamin Petersona96fea02014-06-22 14:17:44 -0700989
990 /* In readinto1 mode, we do not want to fill the internal
991 buffer if we already have some data to return */
992 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +0200993 n = _bufferedreader_fill_buffer(self);
994 if (n > 0) {
995 if (n > remaining)
996 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300997 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +0200998 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200999 self->pos += n;
1000 continue; /* short circuit */
1001 }
1002 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001003 else
1004 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001005
Antoine Pitrou3486a982011-05-12 01:57:53 +02001006 if (n == 0 || (n == -2 && written > 0))
1007 break;
1008 if (n < 0) {
1009 if (n == -2) {
1010 Py_INCREF(Py_None);
1011 res = Py_None;
1012 }
1013 goto end;
1014 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001015
Benjamin Petersona96fea02014-06-22 14:17:44 -07001016 /* At most one read in readinto1 mode */
1017 if (readinto1) {
1018 written += n;
1019 break;
1020 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 }
1022 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001023
1024end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001025 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001026 return res;
1027}
1028
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001029/*[clinic input]
1030_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001031 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001032 /
1033[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001034
1035static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001036_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001037/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001038{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001039 return _buffered_readinto_generic(self, buffer, 0);
1040}
1041
1042/*[clinic input]
1043_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001044 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001045 /
1046[clinic start generated code]*/
1047
1048static PyObject *
1049_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001050/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001051{
1052 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001053}
1054
1055
1056static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001057_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058{
1059 PyObject *res = NULL;
1060 PyObject *chunks = NULL;
Benjamin Peterson19a6c412021-10-26 16:22:34 -07001061 Py_ssize_t n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001062 const char *start, *s, *end;
1063
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001064 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001066 /* First, try to find a line in the buffer. This can run unlocked because
1067 the calls to the C API are simple enough that they can't trigger
1068 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001069 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1070 if (limit >= 0 && n > limit)
1071 n = limit;
1072 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001073 s = memchr(start, '\n', n);
1074 if (s != NULL) {
1075 res = PyBytes_FromStringAndSize(start, s - start + 1);
1076 if (res != NULL)
1077 self->pos += s - start + 1;
1078 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079 }
1080 if (n == limit) {
1081 res = PyBytes_FromStringAndSize(start, n);
1082 if (res != NULL)
1083 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001084 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001085 }
1086
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001087 if (!ENTER_BUFFERED(self))
1088 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001091 chunks = PyList_New(0);
1092 if (chunks == NULL)
1093 goto end;
1094 if (n > 0) {
1095 res = PyBytes_FromStringAndSize(start, n);
1096 if (res == NULL)
1097 goto end;
1098 if (PyList_Append(chunks, res) < 0) {
1099 Py_CLEAR(res);
1100 goto end;
1101 }
1102 Py_CLEAR(res);
Antoine Pitroue05565e2011-08-20 14:39:23 +02001103 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001104 if (limit >= 0)
1105 limit -= n;
1106 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001107 if (self->writable) {
1108 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1109 if (r == NULL)
1110 goto end;
1111 Py_DECREF(r);
1112 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113
1114 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001115 _bufferedreader_reset_buf(self);
1116 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001117 if (n == -1)
1118 goto end;
1119 if (n <= 0)
1120 break;
1121 if (limit >= 0 && n > limit)
1122 n = limit;
1123 start = self->buffer;
1124 end = start + n;
1125 s = start;
1126 while (s < end) {
1127 if (*s++ == '\n') {
1128 res = PyBytes_FromStringAndSize(start, s - start);
1129 if (res == NULL)
1130 goto end;
1131 self->pos = s - start;
1132 goto found;
1133 }
1134 }
1135 res = PyBytes_FromStringAndSize(start, n);
1136 if (res == NULL)
1137 goto end;
1138 if (n == limit) {
1139 self->pos = n;
1140 break;
1141 }
1142 if (PyList_Append(chunks, res) < 0) {
1143 Py_CLEAR(res);
1144 goto end;
1145 }
1146 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147 if (limit >= 0)
1148 limit -= n;
1149 }
1150found:
1151 if (res != NULL && PyList_Append(chunks, res) < 0) {
1152 Py_CLEAR(res);
1153 goto end;
1154 }
Eric Snow1f455362022-02-22 17:23:51 -07001155 Py_XSETREF(res, _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001156
1157end:
1158 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001159end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001160 Py_XDECREF(chunks);
1161 return res;
1162}
1163
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001164/*[clinic input]
1165_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001166 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001167 /
1168[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001169
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001170static PyObject *
1171_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001172/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001173{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001175 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176}
1177
1178
1179static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001180buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001181{
1182 Py_off_t pos;
1183
1184 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001185 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186 if (pos == -1)
1187 return NULL;
1188 pos -= RAW_OFFSET(self);
1189 /* TODO: sanity check (pos >= 0) */
1190 return PyLong_FromOff_t(pos);
1191}
1192
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001193/*[clinic input]
1194_io._Buffered.seek
1195 target as targetobj: object
1196 whence: int = 0
1197 /
1198[clinic start generated code]*/
1199
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001200static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001201_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1202/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001203{
1204 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001205 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206
1207 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001208
1209 /* Do some error checking instead of trusting OS 'seek()'
1210 ** error detection, just in case.
1211 */
1212 if ((whence < 0 || whence >2)
1213#ifdef SEEK_HOLE
1214 && (whence != SEEK_HOLE)
1215#endif
1216#ifdef SEEK_DATA
1217 && (whence != SEEK_DATA)
1218#endif
1219 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001221 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222 return NULL;
1223 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001224
1225 CHECK_CLOSED(self, "seek of closed file")
1226
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001227 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1228 return NULL;
1229
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1231 if (target == -1 && PyErr_Occurred())
1232 return NULL;
1233
Jesus Cea94363612012-06-22 18:32:07 +02001234 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1235 buffer. Other whence values must be managed without this optimization.
1236 Some Operating Systems can provide additional values, like
1237 SEEK_HOLE/SEEK_DATA. */
1238 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239 Py_off_t current, avail;
1240 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001241 so as to return quickly if possible. Also, we needn't take the
1242 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001244 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1245 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 current = RAW_TELL(self);
1247 avail = READAHEAD(self);
1248 if (avail > 0) {
1249 Py_off_t offset;
1250 if (whence == 0)
1251 offset = target - (current - RAW_OFFSET(self));
1252 else
1253 offset = target;
1254 if (offset >= -self->pos && offset <= avail) {
1255 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001256 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001257 }
1258 }
1259 }
1260
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001261 if (!ENTER_BUFFERED(self))
1262 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001263
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 /* Fallback: invoke raw seek() method and clear buffer */
1265 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001266 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001267 if (res == NULL)
1268 goto end;
1269 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270 }
1271
1272 /* TODO: align on block boundary and read buffer if needed? */
1273 if (whence == 1)
1274 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001275 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001276 if (n == -1)
1277 goto end;
1278 self->raw_pos = -1;
1279 res = PyLong_FromOff_t(n);
1280 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001281 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282
1283end:
1284 LEAVE_BUFFERED(self)
1285 return res;
1286}
1287
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001288/*[clinic input]
1289_io._Buffered.truncate
1290 pos: object = None
1291 /
1292[clinic start generated code]*/
1293
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001294static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001295_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1296/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001297{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298 PyObject *res = NULL;
1299
1300 CHECK_INITIALIZED(self)
Berker Peksagfd5116c2020-02-21 20:57:26 +03001301 CHECK_CLOSED(self, "truncate of closed file")
1302 if (!self->writable) {
1303 return bufferediobase_unsupported("truncate");
1304 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001305 if (!ENTER_BUFFERED(self))
1306 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307
Berker Peksagfd5116c2020-02-21 20:57:26 +03001308 res = buffered_flush_and_rewind_unlocked(self);
1309 if (res == NULL) {
1310 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311 }
Berker Peksagfd5116c2020-02-21 20:57:26 +03001312 Py_CLEAR(res);
1313
Eric Snow1f455362022-02-22 17:23:51 -07001314 res = PyObject_CallMethodOneArg(self->raw, &_Py_ID(truncate), pos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001315 if (res == NULL)
1316 goto end;
1317 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001318 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319 PyErr_Clear();
1320
1321end:
1322 LEAVE_BUFFERED(self)
1323 return res;
1324}
1325
1326static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001327buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328{
1329 PyObject *line;
1330 PyTypeObject *tp;
1331
1332 CHECK_INITIALIZED(self);
1333
1334 tp = Py_TYPE(self);
1335 if (tp == &PyBufferedReader_Type ||
1336 tp == &PyBufferedRandom_Type) {
1337 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001338 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339 }
1340 else {
Petr Viktorinffd97532020-02-11 17:46:57 +01001341 line = PyObject_CallMethodNoArgs((PyObject *)self,
Eric Snow1f455362022-02-22 17:23:51 -07001342 &_Py_ID(readline));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001344 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001345 "readline() should have returned a bytes object, "
1346 "not '%.200s'", Py_TYPE(line)->tp_name);
1347 Py_DECREF(line);
1348 return NULL;
1349 }
1350 }
1351
1352 if (line == NULL)
1353 return NULL;
1354
1355 if (PyBytes_GET_SIZE(line) == 0) {
1356 /* Reached EOF or would have blocked */
1357 Py_DECREF(line);
1358 return NULL;
1359 }
1360
1361 return line;
1362}
1363
Antoine Pitrou716c4442009-05-23 19:04:03 +00001364static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001365buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001366{
1367 PyObject *nameobj, *res;
1368
Eric Snow81c72042022-02-08 13:39:07 -07001369 if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) {
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001370 if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001371 return NULL;
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001372 }
1373 /* Ignore ValueError raised if the underlying stream was detached */
1374 PyErr_Clear();
1375 }
1376 if (nameobj == NULL) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001377 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1378 }
1379 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001380 int status = Py_ReprEnter((PyObject *)self);
1381 res = NULL;
1382 if (status == 0) {
1383 res = PyUnicode_FromFormat("<%s name=%R>",
1384 Py_TYPE(self)->tp_name, nameobj);
1385 Py_ReprLeave((PyObject *)self);
1386 }
1387 else if (status > 0) {
1388 PyErr_Format(PyExc_RuntimeError,
1389 "reentrant call inside %s.__repr__",
1390 Py_TYPE(self)->tp_name);
1391 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001392 Py_DECREF(nameobj);
1393 }
1394 return res;
1395}
1396
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001397/*
1398 * class BufferedReader
1399 */
1400
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001401static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001402{
1403 self->read_end = -1;
1404}
1405
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001406/*[clinic input]
1407_io.BufferedReader.__init__
1408 raw: object
1409 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001410
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001411Create a new buffered reader using the given readable raw IO object.
1412[clinic start generated code]*/
1413
1414static int
1415_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1416 Py_ssize_t buffer_size)
1417/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1418{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001419 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001420 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001421
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001422 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001423 return -1;
1424
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001425 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001426 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001427 self->buffer_size = buffer_size;
1428 self->readable = 1;
1429 self->writable = 0;
1430
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001431 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001432 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001433 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001434
Andy Lesterdffe4c02020-03-04 07:15:20 -06001435 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
1436 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001437
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438 self->ok = 1;
1439 return 0;
1440}
1441
1442static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001443_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001444{
1445 Py_buffer buf;
1446 PyObject *memobj, *res;
1447 Py_ssize_t n;
1448 /* NOTE: the buffer needn't be released as its object is NULL. */
1449 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1450 return -1;
1451 memobj = PyMemoryView_FromBuffer(&buf);
1452 if (memobj == NULL)
1453 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001454 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1455 occurs so we needn't do it ourselves.
1456 We then retry reading, ignoring the signal if no handler has
1457 raised (see issue #10956).
1458 */
1459 do {
Eric Snow1f455362022-02-22 17:23:51 -07001460 res = PyObject_CallMethodOneArg(self->raw, &_Py_ID(readinto), memobj);
Gregory P. Smith51359922012-06-23 23:55:39 -07001461 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462 Py_DECREF(memobj);
1463 if (res == NULL)
1464 return -1;
1465 if (res == Py_None) {
1466 /* Non-blocking stream would have blocked. Special return code! */
1467 Py_DECREF(res);
1468 return -2;
1469 }
1470 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1471 Py_DECREF(res);
David Szotten86663562020-06-16 00:53:57 +01001472
1473 if (n == -1 && PyErr_Occurred()) {
1474 _PyErr_FormatFromCause(
1475 PyExc_OSError,
1476 "raw readinto() failed"
1477 );
1478 return -1;
1479 }
1480
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001481 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001482 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001483 "raw readinto() returned invalid length %zd "
1484 "(should have been between 0 and %zd)", n, len);
1485 return -1;
1486 }
1487 if (n > 0 && self->abs_pos != -1)
1488 self->abs_pos += n;
1489 return n;
1490}
1491
1492static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001493_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001494{
1495 Py_ssize_t start, len, n;
1496 if (VALID_READ_BUFFER(self))
1497 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1498 else
1499 start = 0;
1500 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001501 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001502 if (n <= 0)
1503 return n;
1504 self->read_end = start + n;
1505 self->raw_pos = start + n;
1506 return n;
1507}
1508
1509static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001510_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001511{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001512 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001513 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001514
1515 /* First copy what we have in the current buffer. */
1516 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1517 if (current_size) {
1518 data = PyBytes_FromStringAndSize(
1519 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001520 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001521 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001522 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001523 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001524 /* We're going past the buffer's bounds, flush it */
1525 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001526 tmp = buffered_flush_and_rewind_unlocked(self);
1527 if (tmp == NULL)
1528 goto cleanup;
1529 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001530 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001531 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001532
Eric Snow1f455362022-02-22 17:23:51 -07001533 if (_PyObject_LookupAttr(self->raw, &_Py_ID(readall), &readall) < 0) {
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001534 goto cleanup;
1535 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001536 if (readall) {
Victor Stinnerce3489c2021-10-12 00:42:23 +02001537 tmp = _PyObject_CallNoArgs(readall);
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001538 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001539 if (tmp == NULL)
1540 goto cleanup;
1541 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001542 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001543 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001544 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001545 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001546 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001547 } else {
1548 if (tmp != Py_None) {
1549 PyBytes_Concat(&data, tmp);
1550 }
1551 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001552 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001553 goto cleanup;
1554 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001555
1556 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 if (chunks == NULL)
1558 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001559
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001560 while (1) {
1561 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001562 if (PyList_Append(chunks, data) < 0)
1563 goto cleanup;
1564 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001565 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001566
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567 /* Read until EOF or until read() would block. */
Eric Snow1f455362022-02-22 17:23:51 -07001568 data = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(read));
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 if (data == NULL)
1570 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001571 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001573 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001574 }
1575 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1576 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001577 res = data;
1578 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001579 }
1580 else {
Eric Snow1f455362022-02-22 17:23:51 -07001581 tmp = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001582 res = tmp;
1583 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001584 }
1585 }
1586 current_size += PyBytes_GET_SIZE(data);
1587 if (self->abs_pos != -1)
1588 self->abs_pos += PyBytes_GET_SIZE(data);
1589 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001590cleanup:
1591 /* res is either NULL or a borrowed ref */
1592 Py_XINCREF(res);
1593 Py_XDECREF(data);
1594 Py_XDECREF(tmp);
1595 Py_XDECREF(chunks);
1596 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001597}
1598
1599/* Read n bytes from the buffer if it can, otherwise return None.
1600 This function is simple enough that it can run unlocked. */
1601static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001602_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001603{
1604 Py_ssize_t current_size;
1605
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1607 if (n <= current_size) {
1608 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1610 if (res != NULL)
1611 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001612 return res;
1613 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001614 Py_RETURN_NONE;
1615}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001616
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001617/* Generic read function: read from the stream until enough bytes are read,
1618 * or until an EOF occurs or until read() would block.
1619 */
1620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001621_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001622{
1623 PyObject *res = NULL;
1624 Py_ssize_t current_size, remaining, written;
1625 char *out;
1626
1627 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1628 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001630
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001631 res = PyBytes_FromStringAndSize(NULL, n);
1632 if (res == NULL)
1633 goto error;
1634 out = PyBytes_AS_STRING(res);
1635 remaining = n;
1636 written = 0;
1637 if (current_size > 0) {
1638 memcpy(out, self->buffer + self->pos, current_size);
1639 remaining -= current_size;
1640 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001641 self->pos += current_size;
1642 }
1643 /* Flush the write buffer if necessary */
1644 if (self->writable) {
1645 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1646 if (r == NULL)
1647 goto error;
1648 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001649 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001650 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001651 while (remaining > 0) {
1652 /* We want to read a whole block at the end into buffer.
1653 If we had readv() we could do this in one pass. */
1654 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1655 if (r == 0)
1656 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001657 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001658 if (r == -1)
1659 goto error;
1660 if (r == 0 || r == -2) {
1661 /* EOF occurred or read() would block. */
1662 if (r == 0 || written > 0) {
1663 if (_PyBytes_Resize(&res, written))
1664 goto error;
1665 return res;
1666 }
1667 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001668 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001669 }
1670 remaining -= r;
1671 written += r;
1672 }
1673 assert(remaining <= self->buffer_size);
1674 self->pos = 0;
1675 self->raw_pos = 0;
1676 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001677 /* NOTE: when the read is satisfied, we avoid issuing any additional
1678 reads, which could block indefinitely (e.g. on a socket).
1679 See issue #9550. */
1680 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001681 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001682 if (r == -1)
1683 goto error;
1684 if (r == 0 || r == -2) {
1685 /* EOF occurred or read() would block. */
1686 if (r == 0 || written > 0) {
1687 if (_PyBytes_Resize(&res, written))
1688 goto error;
1689 return res;
1690 }
1691 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001692 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693 }
1694 if (remaining > r) {
1695 memcpy(out + written, self->buffer + self->pos, r);
1696 written += r;
1697 self->pos += r;
1698 remaining -= r;
1699 }
1700 else if (remaining > 0) {
1701 memcpy(out + written, self->buffer + self->pos, remaining);
1702 written += remaining;
1703 self->pos += remaining;
1704 remaining = 0;
1705 }
1706 if (remaining == 0)
1707 break;
1708 }
1709
1710 return res;
1711
1712error:
1713 Py_XDECREF(res);
1714 return NULL;
1715}
1716
1717static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001718_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719{
1720 Py_ssize_t have, r;
1721
1722 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1723 /* Constraints:
1724 1. we don't want to advance the file position.
1725 2. we don't want to lose block alignment, so we can't shift the buffer
1726 to make some place.
1727 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1728 */
1729 if (have > 0) {
1730 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1731 }
1732
1733 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001734 _bufferedreader_reset_buf(self);
1735 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001736 if (r == -1)
1737 return NULL;
1738 if (r == -2)
1739 r = 0;
1740 self->pos = 0;
1741 return PyBytes_FromStringAndSize(self->buffer, r);
1742}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743
1744
Benjamin Peterson59406a92009-03-26 17:10:29 +00001745
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746/*
1747 * class BufferedWriter
1748 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001749static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001750_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001751{
1752 self->write_pos = 0;
1753 self->write_end = -1;
1754}
1755
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001756/*[clinic input]
1757_io.BufferedWriter.__init__
1758 raw: object
1759 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001761A buffer for a writeable sequential RawIO object.
1762
1763The constructor creates a BufferedWriter for the given writeable raw
1764stream. If the buffer_size is not given, it defaults to
1765DEFAULT_BUFFER_SIZE.
1766[clinic start generated code]*/
1767
1768static int
1769_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1770 Py_ssize_t buffer_size)
1771/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1772{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001774 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001777 return -1;
1778
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001780 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781 self->readable = 0;
1782 self->writable = 1;
1783
1784 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001785 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 self->pos = 0;
1789
Andy Lesterdffe4c02020-03-04 07:15:20 -06001790 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
1791 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001792
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 self->ok = 1;
1794 return 0;
1795}
1796
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001798_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799{
1800 Py_buffer buf;
1801 PyObject *memobj, *res;
1802 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001803 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 /* NOTE: the buffer needn't be released as its object is NULL. */
1805 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1806 return -1;
1807 memobj = PyMemoryView_FromBuffer(&buf);
1808 if (memobj == NULL)
1809 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001810 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1811 occurs so we needn't do it ourselves.
1812 We then retry writing, ignoring the signal if no handler has
1813 raised (see issue #10956).
1814 */
1815 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001816 errno = 0;
Eric Snow1f455362022-02-22 17:23:51 -07001817 res = PyObject_CallMethodOneArg(self->raw, &_Py_ID(write), memobj);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001818 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001819 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 Py_DECREF(memobj);
1821 if (res == NULL)
1822 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001823 if (res == Py_None) {
1824 /* Non-blocking stream would have blocked. Special return code!
1825 Being paranoid we reset errno in case it is changed by code
1826 triggered by a decref. errno is used by _set_BlockingIOError(). */
1827 Py_DECREF(res);
1828 errno = errnum;
1829 return -2;
1830 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1832 Py_DECREF(res);
1833 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001834 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 "raw write() returned invalid length %zd "
1836 "(should have been between 0 and %zd)", n, len);
1837 return -1;
1838 }
1839 if (n > 0 && self->abs_pos != -1)
1840 self->abs_pos += n;
1841 return n;
1842}
1843
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001845_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847 Py_off_t n, rewind;
1848
1849 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1850 goto end;
1851 /* First, rewind */
1852 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1853 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001854 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001855 if (n < 0) {
1856 goto error;
1857 }
1858 self->raw_pos -= rewind;
1859 }
1860 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001861 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862 self->buffer + self->write_pos,
1863 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1864 Py_off_t, Py_ssize_t));
1865 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001866 goto error;
1867 }
1868 else if (n == -2) {
1869 _set_BlockingIOError("write could not complete without blocking",
1870 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001871 goto error;
1872 }
1873 self->write_pos += n;
1874 self->raw_pos = self->write_pos;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001875 /* Partial writes can return successfully when interrupted by a
1876 signal (see write(2)). We must run signal handlers before
1877 blocking another time, possibly indefinitely. */
1878 if (PyErr_CheckSignals() < 0)
1879 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880 }
1881
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001882
1883end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301884 /* This ensures that after return from this function,
1885 VALID_WRITE_BUFFER(self) returns false.
1886
1887 This is a required condition because when a tell() is called
1888 after flushing and if VALID_READ_BUFFER(self) is false, we need
1889 VALID_WRITE_BUFFER(self) to be false to have
1890 RAW_OFFSET(self) == 0.
1891
1892 Issue: https://bugs.python.org/issue32228 */
1893 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001894 Py_RETURN_NONE;
1895
1896error:
1897 return NULL;
1898}
1899
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001900/*[clinic input]
1901_io.BufferedWriter.write
1902 buffer: Py_buffer
1903 /
1904[clinic start generated code]*/
1905
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001907_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1908/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001909{
1910 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001911 Py_ssize_t written, avail, remaining;
1912 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913
1914 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001916 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001917 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918
benfogle9703f092017-11-10 16:03:40 -05001919 /* Issue #31976: Check for closed file after acquiring the lock. Another
1920 thread could be holding the lock while closing the file. */
1921 if (IS_CLOSED(self)) {
1922 PyErr_SetString(PyExc_ValueError, "write to closed file");
1923 goto error;
1924 }
1925
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926 /* Fast path: the data to write can be fully buffered. */
1927 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1928 self->pos = 0;
1929 self->raw_pos = 0;
1930 }
1931 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001932 if (buffer->len <= avail) {
1933 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001934 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935 self->write_pos = self->pos;
1936 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001937 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938 if (self->pos > self->write_end)
1939 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001940 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941 goto end;
1942 }
1943
1944 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001945 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001946 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001947 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 if (w == NULL)
1949 goto error;
1950 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 /* Make some place by shifting the buffer. */
1953 assert(VALID_WRITE_BUFFER(self));
1954 memmove(self->buffer, self->buffer + self->write_pos,
1955 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1956 Py_off_t, Py_ssize_t));
1957 self->write_end -= self->write_pos;
1958 self->raw_pos -= self->write_pos;
1959 self->pos -= self->write_pos;
1960 self->write_pos = 0;
1961 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1962 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001963 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 /* Everything can be buffered */
1965 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001966 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1967 self->write_end += buffer->len;
1968 self->pos += buffer->len;
1969 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 goto end;
1971 }
1972 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001973 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001974 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001975 self->pos += avail;
1976 /* XXX Modifying the existing exception e using the pointer w
1977 will change e.characters_written but not e.args[2].
1978 Therefore we just replace with a new error. */
1979 _set_BlockingIOError("write could not complete without blocking",
1980 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981 goto error;
1982 }
1983 Py_CLEAR(res);
1984
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001985 /* Adjust the raw stream position if it is away from the logical stream
1986 position. This happens if the read buffer has been filled but not
1987 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1988 the raw stream by itself).
1989 Fixes issue #6629.
1990 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001991 offset = RAW_OFFSET(self);
1992 if (offset != 0) {
1993 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001994 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001995 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001996 }
1997
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001999 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000 written = 0;
2001 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002002 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002003 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002005 goto error;
2006 } else if (n == -2) {
2007 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 if (remaining > self->buffer_size) {
2009 /* Can't buffer everything, still buffer as much as possible */
2010 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002011 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 self->raw_pos = 0;
2013 ADJUST_POSITION(self, self->buffer_size);
2014 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002015 written += self->buffer_size;
2016 _set_BlockingIOError("write could not complete without "
2017 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 goto error;
2019 }
2020 PyErr_Clear();
2021 break;
2022 }
2023 written += n;
2024 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002025 /* Partial writes can return successfully when interrupted by a
2026 signal (see write(2)). We must run signal handlers before
2027 blocking another time, possibly indefinitely. */
2028 if (PyErr_CheckSignals() < 0)
2029 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 }
2031 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002032 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002034 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035 written += remaining;
2036 }
2037 self->write_pos = 0;
2038 /* TODO: sanity check (remaining >= 0) */
2039 self->write_end = remaining;
2040 ADJUST_POSITION(self, remaining);
2041 self->raw_pos = 0;
2042
2043end:
2044 res = PyLong_FromSsize_t(written);
2045
2046error:
2047 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048 return res;
2049}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002050
2051
2052
2053/*
2054 * BufferedRWPair
2055 */
2056
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002057/* XXX The usefulness of this (compared to having two separate IO objects) is
2058 * questionable.
2059 */
2060
2061typedef struct {
2062 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002063 buffered *reader;
2064 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002065 PyObject *dict;
2066 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002067} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002069/*[clinic input]
2070_io.BufferedRWPair.__init__
2071 reader: object
2072 writer: object
2073 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2074 /
2075
2076A buffered reader and writer object together.
2077
2078A buffered reader object and buffered writer object put together to
2079form a sequential IO object that can read and write. This is typically
2080used with a socket or two-way pipe.
2081
2082reader and writer are RawIOBase objects that are readable and
2083writeable respectively. If the buffer_size is omitted it defaults to
2084DEFAULT_BUFFER_SIZE.
2085[clinic start generated code]*/
2086
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002087static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002088_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2089 PyObject *writer, Py_ssize_t buffer_size)
2090/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002091{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002092 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002093 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002094 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095 return -1;
2096
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002097 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002098 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002099 if (self->reader == NULL)
2100 return -1;
2101
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002102 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002103 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104 if (self->writer == NULL) {
2105 Py_CLEAR(self->reader);
2106 return -1;
2107 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002108
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 return 0;
2110}
2111
2112static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002113bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002114{
2115 Py_VISIT(self->dict);
2116 return 0;
2117}
2118
2119static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121{
2122 Py_CLEAR(self->reader);
2123 Py_CLEAR(self->writer);
2124 Py_CLEAR(self->dict);
2125 return 0;
2126}
2127
2128static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130{
2131 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002132 if (self->weakreflist != NULL)
2133 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002134 Py_CLEAR(self->reader);
2135 Py_CLEAR(self->writer);
2136 Py_CLEAR(self->dict);
2137 Py_TYPE(self)->tp_free((PyObject *) self);
2138}
2139
2140static PyObject *
Eric Snow81c72042022-02-08 13:39:07 -07002141_forward_call(buffered *self, PyObject *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002142{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002143 PyObject *func, *ret;
2144 if (self == NULL) {
2145 PyErr_SetString(PyExc_ValueError,
2146 "I/O operation on uninitialized object");
2147 return NULL;
2148 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149
Eric Snow81c72042022-02-08 13:39:07 -07002150 func = PyObject_GetAttr((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151 if (func == NULL) {
Eric Snow81c72042022-02-08 13:39:07 -07002152 PyErr_SetObject(PyExc_AttributeError, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 return NULL;
2154 }
2155
2156 ret = PyObject_CallObject(func, args);
2157 Py_DECREF(func);
2158 return ret;
2159}
2160
2161static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002162bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002163{
Eric Snow81c72042022-02-08 13:39:07 -07002164 return _forward_call(self->reader, &_Py_ID(read), args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165}
2166
2167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169{
Eric Snow81c72042022-02-08 13:39:07 -07002170 return _forward_call(self->reader, &_Py_ID(peek), args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171}
2172
2173static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002174bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175{
Eric Snow81c72042022-02-08 13:39:07 -07002176 return _forward_call(self->reader, &_Py_ID(read1), args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177}
2178
2179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002181{
Eric Snow81c72042022-02-08 13:39:07 -07002182 return _forward_call(self->reader, &_Py_ID(readinto), args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002183}
2184
2185static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002186bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2187{
Eric Snow81c72042022-02-08 13:39:07 -07002188 return _forward_call(self->reader, &_Py_ID(readinto1), args);
Benjamin Petersona96fea02014-06-22 14:17:44 -07002189}
2190
2191static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193{
Eric Snow81c72042022-02-08 13:39:07 -07002194 return _forward_call(self->writer, &_Py_ID(write), args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195}
2196
2197static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002198bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199{
Eric Snow81c72042022-02-08 13:39:07 -07002200 return _forward_call(self->writer, &_Py_ID(flush), NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201}
2202
2203static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002204bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205{
Eric Snow81c72042022-02-08 13:39:07 -07002206 return _forward_call(self->reader, &_Py_ID(readable), NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207}
2208
2209static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002210bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211{
Eric Snow81c72042022-02-08 13:39:07 -07002212 return _forward_call(self->writer, &_Py_ID(writable), NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213}
2214
2215static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002216bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002218 PyObject *exc = NULL, *val, *tb;
Eric Snow81c72042022-02-08 13:39:07 -07002219 PyObject *ret = _forward_call(self->writer, &_Py_ID(close), NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002221 PyErr_Fetch(&exc, &val, &tb);
2222 else
2223 Py_DECREF(ret);
Eric Snow81c72042022-02-08 13:39:07 -07002224 ret = _forward_call(self->reader, &_Py_ID(close), NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002225 if (exc != NULL) {
2226 _PyErr_ChainExceptions(exc, val, tb);
2227 Py_CLEAR(ret);
2228 }
2229 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230}
2231
2232static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002233bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234{
Eric Snow81c72042022-02-08 13:39:07 -07002235 PyObject *ret = _forward_call(self->writer, &_Py_ID(isatty), NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236
2237 if (ret != Py_False) {
2238 /* either True or exception */
2239 return ret;
2240 }
2241 Py_DECREF(ret);
2242
Eric Snow81c72042022-02-08 13:39:07 -07002243 return _forward_call(self->reader, &_Py_ID(isatty), NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244}
2245
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002246static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002247bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002248{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002249 if (self->writer == NULL) {
2250 PyErr_SetString(PyExc_RuntimeError,
2251 "the BufferedRWPair object is being garbage-collected");
2252 return NULL;
2253 }
Eric Snow1f455362022-02-22 17:23:51 -07002254 return PyObject_GetAttr((PyObject *) self->writer, &_Py_ID(closed));
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002255}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002256
2257
2258
2259/*
2260 * BufferedRandom
2261 */
2262
2263/*[clinic input]
2264_io.BufferedRandom.__init__
2265 raw: object
2266 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2267
2268A buffered interface to random access streams.
2269
2270The constructor creates a reader and writer for a seekable stream,
2271raw, given in the first argument. If the buffer_size is omitted it
2272defaults to DEFAULT_BUFFER_SIZE.
2273[clinic start generated code]*/
2274
2275static int
2276_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2277 Py_ssize_t buffer_size)
2278/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2279{
2280 self->ok = 0;
2281 self->detached = 0;
2282
2283 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2284 return -1;
2285 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2286 return -1;
2287 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2288 return -1;
2289
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002290 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002291 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002292 self->buffer_size = buffer_size;
2293 self->readable = 1;
2294 self->writable = 1;
2295
2296 if (_buffered_init(self) < 0)
2297 return -1;
2298 _bufferedreader_reset_buf(self);
2299 _bufferedwriter_reset_buf(self);
2300 self->pos = 0;
2301
Andy Lesterdffe4c02020-03-04 07:15:20 -06002302 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
2303 Py_IS_TYPE(raw, &PyFileIO_Type));
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002304
2305 self->ok = 1;
2306 return 0;
2307}
2308
2309#include "clinic/bufferedio.c.h"
2310
2311
2312static PyMethodDef bufferediobase_methods[] = {
2313 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2314 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2315 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2316 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2317 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2318 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2319 {NULL, NULL}
2320};
2321
2322PyTypeObject PyBufferedIOBase_Type = {
2323 PyVarObject_HEAD_INIT(NULL, 0)
2324 "_io._BufferedIOBase", /*tp_name*/
2325 0, /*tp_basicsize*/
2326 0, /*tp_itemsize*/
2327 0, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002328 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002329 0, /*tp_getattr*/
2330 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002331 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002332 0, /*tp_repr*/
2333 0, /*tp_as_number*/
2334 0, /*tp_as_sequence*/
2335 0, /*tp_as_mapping*/
2336 0, /*tp_hash */
2337 0, /*tp_call*/
2338 0, /*tp_str*/
2339 0, /*tp_getattro*/
2340 0, /*tp_setattro*/
2341 0, /*tp_as_buffer*/
Antoine Pitrouada319b2019-05-29 22:12:38 +02002342 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002343 bufferediobase_doc, /* tp_doc */
2344 0, /* tp_traverse */
2345 0, /* tp_clear */
2346 0, /* tp_richcompare */
2347 0, /* tp_weaklistoffset */
2348 0, /* tp_iter */
2349 0, /* tp_iternext */
2350 bufferediobase_methods, /* tp_methods */
2351 0, /* tp_members */
2352 0, /* tp_getset */
2353 &PyIOBase_Type, /* tp_base */
2354 0, /* tp_dict */
2355 0, /* tp_descr_get */
2356 0, /* tp_descr_set */
2357 0, /* tp_dictoffset */
2358 0, /* tp_init */
2359 0, /* tp_alloc */
2360 0, /* tp_new */
2361 0, /* tp_free */
2362 0, /* tp_is_gc */
2363 0, /* tp_bases */
2364 0, /* tp_mro */
2365 0, /* tp_cache */
2366 0, /* tp_subclasses */
2367 0, /* tp_weaklist */
2368 0, /* tp_del */
2369 0, /* tp_version_tag */
2370 0, /* tp_finalize */
2371};
2372
2373
2374static PyMethodDef bufferedreader_methods[] = {
2375 /* BufferedIOMixin methods */
2376 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2377 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2378 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2379 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2380 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002381 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2382 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2383 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002384
2385 _IO__BUFFERED_READ_METHODDEF
2386 _IO__BUFFERED_PEEK_METHODDEF
2387 _IO__BUFFERED_READ1_METHODDEF
2388 _IO__BUFFERED_READINTO_METHODDEF
2389 _IO__BUFFERED_READINTO1_METHODDEF
2390 _IO__BUFFERED_READLINE_METHODDEF
2391 _IO__BUFFERED_SEEK_METHODDEF
2392 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2393 _IO__BUFFERED_TRUNCATE_METHODDEF
2394 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2395 {NULL, NULL}
2396};
2397
2398static PyMemberDef bufferedreader_members[] = {
2399 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2400 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2401 {NULL}
2402};
2403
2404static PyGetSetDef bufferedreader_getset[] = {
2405 {"closed", (getter)buffered_closed_get, NULL, NULL},
2406 {"name", (getter)buffered_name_get, NULL, NULL},
2407 {"mode", (getter)buffered_mode_get, NULL, NULL},
2408 {NULL}
2409};
2410
2411
2412PyTypeObject PyBufferedReader_Type = {
2413 PyVarObject_HEAD_INIT(NULL, 0)
2414 "_io.BufferedReader", /*tp_name*/
2415 sizeof(buffered), /*tp_basicsize*/
2416 0, /*tp_itemsize*/
2417 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002418 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002419 0, /*tp_getattr*/
2420 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002421 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002422 (reprfunc)buffered_repr, /*tp_repr*/
2423 0, /*tp_as_number*/
2424 0, /*tp_as_sequence*/
2425 0, /*tp_as_mapping*/
2426 0, /*tp_hash */
2427 0, /*tp_call*/
2428 0, /*tp_str*/
2429 0, /*tp_getattro*/
2430 0, /*tp_setattro*/
2431 0, /*tp_as_buffer*/
2432 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002433 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002434 _io_BufferedReader___init____doc__, /* tp_doc */
2435 (traverseproc)buffered_traverse, /* tp_traverse */
2436 (inquiry)buffered_clear, /* tp_clear */
2437 0, /* tp_richcompare */
2438 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2439 0, /* tp_iter */
2440 (iternextfunc)buffered_iternext, /* tp_iternext */
2441 bufferedreader_methods, /* tp_methods */
2442 bufferedreader_members, /* tp_members */
2443 bufferedreader_getset, /* tp_getset */
2444 0, /* tp_base */
2445 0, /* tp_dict */
2446 0, /* tp_descr_get */
2447 0, /* tp_descr_set */
2448 offsetof(buffered, dict), /* tp_dictoffset */
2449 _io_BufferedReader___init__, /* tp_init */
2450 0, /* tp_alloc */
2451 PyType_GenericNew, /* tp_new */
2452 0, /* tp_free */
2453 0, /* tp_is_gc */
2454 0, /* tp_bases */
2455 0, /* tp_mro */
2456 0, /* tp_cache */
2457 0, /* tp_subclasses */
2458 0, /* tp_weaklist */
2459 0, /* tp_del */
2460 0, /* tp_version_tag */
2461 0, /* tp_finalize */
2462};
2463
2464
2465static PyMethodDef bufferedwriter_methods[] = {
2466 /* BufferedIOMixin methods */
2467 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2468 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2469 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002470 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2471 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2472 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2473 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002474
2475 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2476 _IO__BUFFERED_TRUNCATE_METHODDEF
2477 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2478 _IO__BUFFERED_SEEK_METHODDEF
2479 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2480 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2481 {NULL, NULL}
2482};
2483
2484static PyMemberDef bufferedwriter_members[] = {
2485 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2486 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2487 {NULL}
2488};
2489
2490static PyGetSetDef bufferedwriter_getset[] = {
2491 {"closed", (getter)buffered_closed_get, NULL, NULL},
2492 {"name", (getter)buffered_name_get, NULL, NULL},
2493 {"mode", (getter)buffered_mode_get, NULL, NULL},
2494 {NULL}
2495};
2496
2497
2498PyTypeObject PyBufferedWriter_Type = {
2499 PyVarObject_HEAD_INIT(NULL, 0)
2500 "_io.BufferedWriter", /*tp_name*/
2501 sizeof(buffered), /*tp_basicsize*/
2502 0, /*tp_itemsize*/
2503 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002504 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002505 0, /*tp_getattr*/
2506 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002507 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002508 (reprfunc)buffered_repr, /*tp_repr*/
2509 0, /*tp_as_number*/
2510 0, /*tp_as_sequence*/
2511 0, /*tp_as_mapping*/
2512 0, /*tp_hash */
2513 0, /*tp_call*/
2514 0, /*tp_str*/
2515 0, /*tp_getattro*/
2516 0, /*tp_setattro*/
2517 0, /*tp_as_buffer*/
2518 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002519 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002520 _io_BufferedWriter___init____doc__, /* tp_doc */
2521 (traverseproc)buffered_traverse, /* tp_traverse */
2522 (inquiry)buffered_clear, /* tp_clear */
2523 0, /* tp_richcompare */
2524 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2525 0, /* tp_iter */
2526 0, /* tp_iternext */
2527 bufferedwriter_methods, /* tp_methods */
2528 bufferedwriter_members, /* tp_members */
2529 bufferedwriter_getset, /* tp_getset */
2530 0, /* tp_base */
2531 0, /* tp_dict */
2532 0, /* tp_descr_get */
2533 0, /* tp_descr_set */
2534 offsetof(buffered, dict), /* tp_dictoffset */
2535 _io_BufferedWriter___init__, /* tp_init */
2536 0, /* tp_alloc */
2537 PyType_GenericNew, /* tp_new */
2538 0, /* tp_free */
2539 0, /* tp_is_gc */
2540 0, /* tp_bases */
2541 0, /* tp_mro */
2542 0, /* tp_cache */
2543 0, /* tp_subclasses */
2544 0, /* tp_weaklist */
2545 0, /* tp_del */
2546 0, /* tp_version_tag */
2547 0, /* tp_finalize */
2548};
2549
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002550
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002551static PyMethodDef bufferedrwpair_methods[] = {
2552 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2553 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2554 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2555 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002556 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002557
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002558 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2559 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002561 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2562 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002563
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002564 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2565 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002567 {NULL, NULL}
2568};
2569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570static PyGetSetDef bufferedrwpair_getset[] = {
2571 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002572 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002573};
2574
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575PyTypeObject PyBufferedRWPair_Type = {
2576 PyVarObject_HEAD_INIT(NULL, 0)
2577 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002578 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002581 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582 0, /*tp_getattr*/
2583 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002584 0, /*tp_as_async*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585 0, /*tp_repr*/
2586 0, /*tp_as_number*/
2587 0, /*tp_as_sequence*/
2588 0, /*tp_as_mapping*/
2589 0, /*tp_hash */
2590 0, /*tp_call*/
2591 0, /*tp_str*/
2592 0, /*tp_getattro*/
2593 0, /*tp_setattro*/
2594 0, /*tp_as_buffer*/
2595 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002596 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002597 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002598 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2599 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002600 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002602 0, /* tp_iter */
2603 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002604 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002605 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002606 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002607 0, /* tp_base */
2608 0, /* tp_dict */
2609 0, /* tp_descr_get */
2610 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002611 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002612 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613 0, /* tp_alloc */
2614 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002615 0, /* tp_free */
2616 0, /* tp_is_gc */
2617 0, /* tp_bases */
2618 0, /* tp_mro */
2619 0, /* tp_cache */
2620 0, /* tp_subclasses */
2621 0, /* tp_weaklist */
2622 0, /* tp_del */
2623 0, /* tp_version_tag */
2624 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002625};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002626
2627
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002628static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002630 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2631 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2632 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2633 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2634 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2635 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2636 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002637 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002638
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002639 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002640
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002641 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002642 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002643 _IO__BUFFERED_TRUNCATE_METHODDEF
2644 _IO__BUFFERED_READ_METHODDEF
2645 _IO__BUFFERED_READ1_METHODDEF
2646 _IO__BUFFERED_READINTO_METHODDEF
2647 _IO__BUFFERED_READINTO1_METHODDEF
2648 _IO__BUFFERED_READLINE_METHODDEF
2649 _IO__BUFFERED_PEEK_METHODDEF
2650 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002651 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002652 {NULL, NULL}
2653};
2654
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002655static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002656 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002657 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002658 {NULL}
2659};
2660
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002661static PyGetSetDef bufferedrandom_getset[] = {
2662 {"closed", (getter)buffered_closed_get, NULL, NULL},
2663 {"name", (getter)buffered_name_get, NULL, NULL},
2664 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002665 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002666};
2667
2668
2669PyTypeObject PyBufferedRandom_Type = {
2670 PyVarObject_HEAD_INIT(NULL, 0)
2671 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002672 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002673 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002674 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002675 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002676 0, /*tp_getattr*/
2677 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002678 0, /*tp_as_async*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002679 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002680 0, /*tp_as_number*/
2681 0, /*tp_as_sequence*/
2682 0, /*tp_as_mapping*/
2683 0, /*tp_hash */
2684 0, /*tp_call*/
2685 0, /*tp_str*/
2686 0, /*tp_getattro*/
2687 0, /*tp_setattro*/
2688 0, /*tp_as_buffer*/
2689 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002690 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002691 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002692 (traverseproc)buffered_traverse, /* tp_traverse */
2693 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002694 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002695 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002696 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002697 (iternextfunc)buffered_iternext, /* tp_iternext */
2698 bufferedrandom_methods, /* tp_methods */
2699 bufferedrandom_members, /* tp_members */
2700 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002701 0, /* tp_base */
2702 0, /*tp_dict*/
2703 0, /* tp_descr_get */
2704 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002705 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002706 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002707 0, /* tp_alloc */
2708 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002709 0, /* tp_free */
2710 0, /* tp_is_gc */
2711 0, /* tp_bases */
2712 0, /* tp_mro */
2713 0, /* tp_cache */
2714 0, /* tp_subclasses */
2715 0, /* tp_weaklist */
2716 0, /* tp_del */
2717 0, /* tp_version_tag */
2718 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719};