blob: 6e76db42c3a602fb19fc75abcddde6d9ff335ace [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +010012#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +010013#include "pycore_pystate.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000014#include "structmember.h"
15#include "pythread.h"
16#include "_iomodule.h"
17
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030018/*[clinic input]
19module _io
20class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
21class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
22class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
23class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
24class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
25class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
26[clinic start generated code]*/
27/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
28
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020029_Py_IDENTIFIER(close);
30_Py_IDENTIFIER(_dealloc_warn);
31_Py_IDENTIFIER(flush);
32_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020033_Py_IDENTIFIER(mode);
34_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020035_Py_IDENTIFIER(peek);
36_Py_IDENTIFIER(read);
37_Py_IDENTIFIER(read1);
38_Py_IDENTIFIER(readable);
39_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070040_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020041_Py_IDENTIFIER(writable);
42_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020043
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000044/*
45 * BufferedIOBase class, inherits from IOBase.
46 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000047PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000048 "Base class for buffered IO objects.\n"
49 "\n"
50 "The main difference with RawIOBase is that the read() method\n"
51 "supports omitting the size argument, and does not have a default\n"
52 "implementation that defers to readinto().\n"
53 "\n"
54 "In addition, read(), readinto() and write() may raise\n"
55 "BlockingIOError if the underlying raw stream is in non-blocking\n"
56 "mode and not ready; unlike their raw counterparts, they will never\n"
57 "return None.\n"
58 "\n"
59 "A typical implementation should not inherit from a RawIOBase\n"
60 "implementation, but wrap one.\n"
61 );
62
63static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030064_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000065{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000066 Py_ssize_t len;
67 PyObject *data;
68
Benjamin Petersona96fea02014-06-22 14:17:44 -070069 data = _PyObject_CallMethodId(self,
70 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030071 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000072 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030073 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000074
75 if (!PyBytes_Check(data)) {
76 Py_DECREF(data);
77 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030078 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000079 }
80
Serhiy Storchakafff9a312017-03-21 08:53:25 +020081 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030082 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030083 PyErr_Format(PyExc_ValueError,
84 "read() returned too much data: "
85 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030086 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030087 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030088 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030089 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030090 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000091
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000092 Py_DECREF(data);
93
94 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000095}
96
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030097/*[clinic input]
98_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070099 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300100 /
101[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700102
103static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300104_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700105/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700106{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300107 return _bufferediobase_readinto_generic(self, buffer, 0);
108}
109
110/*[clinic input]
111_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700112 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300113 /
114[clinic start generated code]*/
115
116static PyObject *
117_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700118/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300119{
120 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700121}
122
123static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000124bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000125{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100126 _PyIO_State *state = IO_STATE();
127 if (state != NULL)
128 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000129 return NULL;
130}
131
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300132/*[clinic input]
133_io._BufferedIOBase.detach
134
135Disconnect this buffer from its underlying raw stream and return it.
136
137After the raw stream has been detached, the buffer is in an unusable
138state.
139[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000140
141static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300142_io__BufferedIOBase_detach_impl(PyObject *self)
143/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000144{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000145 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000146}
147
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000148PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149 "Read and return up to n bytes.\n"
150 "\n"
151 "If the argument is omitted, None, or negative, reads and\n"
152 "returns all data until EOF.\n"
153 "\n"
154 "If the argument is positive, and the underlying raw stream is\n"
155 "not 'interactive', multiple raw reads may be issued to satisfy\n"
156 "the byte count (unless EOF is reached first). But for\n"
157 "interactive raw streams (as well as sockets and pipes), at most\n"
158 "one raw read will be issued, and a short result does not imply\n"
159 "that EOF is imminent.\n"
160 "\n"
161 "Returns an empty bytes object on EOF.\n"
162 "\n"
163 "Returns None if the underlying raw stream was open in non-blocking\n"
164 "mode and no data is available at the moment.\n");
165
166static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000168{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000169 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000170}
171
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000172PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000173 "Read and return up to n bytes, with at most one read() call\n"
174 "to the underlying raw stream. A short result does not imply\n"
175 "that EOF is imminent.\n"
176 "\n"
177 "Returns an empty bytes object on EOF.\n");
178
179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000180bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000182 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000183}
184
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000185PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000186 "Write the given buffer to the IO stream.\n"
187 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000188 "Returns the number of bytes written, which is always the length of b\n"
189 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000190 "\n"
191 "Raises BlockingIOError if the buffer is full and the\n"
192 "underlying raw stream cannot accept more data at the moment.\n");
193
194static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000195bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000197 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000198}
199
200
Antoine Pitrou317def92017-12-13 01:39:26 +0100201typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000202 PyObject_HEAD
203
204 PyObject *raw;
205 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000206 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000207 int readable;
208 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200209 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200210
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000211 /* True if this is a vanilla Buffered object (rather than a user derived
212 class) *and* the raw stream is a vanilla FileIO object. */
213 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000214
215 /* Absolute position inside the raw stream (-1 if unknown). */
216 Py_off_t abs_pos;
217
218 /* A static buffer of size `buffer_size` */
219 char *buffer;
220 /* Current logical position in the buffer. */
221 Py_off_t pos;
222 /* Position of the raw stream in the buffer. */
223 Py_off_t raw_pos;
224
225 /* Just after the last buffered byte in the buffer, or -1 if the buffer
226 isn't ready for reading. */
227 Py_off_t read_end;
228
229 /* Just after the last byte actually written */
230 Py_off_t write_pos;
231 /* Just after the last byte waiting to be written, or -1 if the buffer
232 isn't ready for writing. */
233 Py_off_t write_end;
234
235 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200236 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000237
238 Py_ssize_t buffer_size;
239 Py_ssize_t buffer_mask;
240
241 PyObject *dict;
242 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000243} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000244
245/*
246 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200247
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000248 * BufferedReader, BufferedWriter and BufferedRandom try to share most
249 methods (this is helped by the members `readable` and `writable`, which
250 are initialized in the respective constructors)
251 * They also share a single buffer for reading and writing. This enables
252 interleaved reads and writes without flushing. It also makes the logic
253 a bit trickier to get right.
254 * The absolute position of the raw stream is cached, if possible, in the
255 `abs_pos` member. It must be updated every time an operation is done
256 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000257 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000258 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000259 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
260 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000261
262 NOTE: we should try to maintain block alignment of reads and writes to the
263 raw stream (according to the buffer size), but for now it is only done
264 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200265
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000266*/
267
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000268/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000269
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000270static int
271_enter_buffered_busy(buffered *self)
272{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200273 int relax_locking;
274 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000275 if (self->owner == PyThread_get_thread_ident()) {
276 PyErr_Format(PyExc_RuntimeError,
277 "reentrant call inside %R", self);
278 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000279 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600280 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000281 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200282 if (!relax_locking)
283 st = PyThread_acquire_lock(self->lock, 1);
284 else {
285 /* When finalizing, we don't want a deadlock to happen with daemon
286 * threads abruptly shut down while they owned the lock.
287 * Therefore, only wait for a grace period (1 s.).
288 * Note that non-daemon threads have already exited here, so this
289 * shouldn't affect carefully written threaded I/O code.
290 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700291 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200292 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000293 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200294 if (relax_locking && st != PY_LOCK_ACQUIRED) {
Victor Stinner87d3b9d2020-03-25 19:27:36 +0100295 PyObject *ascii = PyObject_ASCII((PyObject*)self);
296 _Py_FatalErrorFormat(__func__,
297 "could not acquire lock for %s at interpreter "
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200298 "shutdown, possibly due to daemon threads",
Victor Stinner87d3b9d2020-03-25 19:27:36 +0100299 ascii ? PyUnicode_AsUTF8(ascii) : "<ascii(self) failed>");
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200300 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000301 return 1;
302}
303
304#define ENTER_BUFFERED(self) \
305 ( (PyThread_acquire_lock(self->lock, 0) ? \
306 1 : _enter_buffered_busy(self)) \
307 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000308
309#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000310 do { \
311 self->owner = 0; \
312 PyThread_release_lock(self->lock); \
313 } while(0);
314
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000315#define CHECK_INITIALIZED(self) \
316 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000317 if (self->detached) { \
318 PyErr_SetString(PyExc_ValueError, \
319 "raw stream has been detached"); \
320 } else { \
321 PyErr_SetString(PyExc_ValueError, \
322 "I/O operation on uninitialized object"); \
323 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000324 return NULL; \
325 }
326
327#define CHECK_INITIALIZED_INT(self) \
328 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000329 if (self->detached) { \
330 PyErr_SetString(PyExc_ValueError, \
331 "raw stream has been detached"); \
332 } else { \
333 PyErr_SetString(PyExc_ValueError, \
334 "I/O operation on uninitialized object"); \
335 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336 return -1; \
337 }
338
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000339#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500340 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000341 (self->fast_closed_checks \
342 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500343 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000344
345#define CHECK_CLOSED(self, error_msg) \
346 if (IS_CLOSED(self)) { \
347 PyErr_SetString(PyExc_ValueError, error_msg); \
348 return NULL; \
349 }
350
351
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000352#define VALID_READ_BUFFER(self) \
353 (self->readable && self->read_end != -1)
354
355#define VALID_WRITE_BUFFER(self) \
356 (self->writable && self->write_end != -1)
357
358#define ADJUST_POSITION(self, _new_pos) \
359 do { \
360 self->pos = _new_pos; \
361 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
362 self->read_end = self->pos; \
363 } while(0)
364
365#define READAHEAD(self) \
366 ((self->readable && VALID_READ_BUFFER(self)) \
367 ? (self->read_end - self->pos) : 0)
368
369#define RAW_OFFSET(self) \
370 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
371 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
372
373#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000374 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000375
376#define MINUS_LAST_BLOCK(self, size) \
377 (self->buffer_mask ? \
378 (size & ~self->buffer_mask) : \
379 (self->buffer_size * (size / self->buffer_size)))
380
381
382static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000383buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000384{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200385 self->finalizing = 1;
386 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387 return;
388 _PyObject_GC_UNTRACK(self);
389 self->ok = 0;
390 if (self->weakreflist != NULL)
391 PyObject_ClearWeakRefs((PyObject *)self);
392 Py_CLEAR(self->raw);
393 if (self->buffer) {
394 PyMem_Free(self->buffer);
395 self->buffer = NULL;
396 }
397 if (self->lock) {
398 PyThread_free_lock(self->lock);
399 self->lock = NULL;
400 }
401 Py_CLEAR(self->dict);
402 Py_TYPE(self)->tp_free((PyObject *)self);
403}
404
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200405static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200406buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200407{
408 Py_ssize_t res;
409
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200410 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200411 if (self->buffer)
412 res += self->buffer_size;
413 return PyLong_FromSsize_t(res);
414}
415
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000417buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000418{
419 Py_VISIT(self->raw);
420 Py_VISIT(self->dict);
421 return 0;
422}
423
424static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000425buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000426{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000427 self->ok = 0;
428 Py_CLEAR(self->raw);
429 Py_CLEAR(self->dict);
430 return 0;
431}
432
Antoine Pitroue033e062010-10-29 10:38:18 +0000433/* Because this can call arbitrary code, it shouldn't be called when
434 the refcount is 0 (that is, not directly from tp_dealloc unless
435 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000436static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000437buffered_dealloc_warn(buffered *self, PyObject *source)
438{
439 if (self->ok && self->raw) {
440 PyObject *r;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200441 r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn,
442 source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000443 if (r)
444 Py_DECREF(r);
445 else
446 PyErr_Clear();
447 }
448 Py_RETURN_NONE;
449}
450
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000451/*
452 * _BufferedIOMixin methods
453 * This is not a class, just a collection of methods that will be reused
454 * by BufferedReader and BufferedWriter
455 */
456
457/* Flush and close */
458
459static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000460buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461{
462 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100463 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464}
465
466static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000467buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000468{
469 int closed;
470 PyObject *res;
471 CHECK_INITIALIZED_INT(self)
472 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
473 if (res == NULL)
474 return -1;
475 closed = PyObject_IsTrue(res);
476 Py_DECREF(res);
477 return closed;
478}
479
480static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000481buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482{
483 CHECK_INITIALIZED(self)
484 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
485}
486
487static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000488buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489{
Benjamin Peterson68623612012-12-20 11:53:11 -0600490 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491 int r;
492
493 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000494 if (!ENTER_BUFFERED(self))
495 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498 if (r < 0)
499 goto end;
500 if (r > 0) {
501 res = Py_None;
502 Py_INCREF(res);
503 goto end;
504 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000505
Antoine Pitrou796564c2013-07-30 19:59:21 +0200506 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000507 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
508 if (r)
509 Py_DECREF(r);
510 else
511 PyErr_Clear();
512 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513 /* flush() will most probably re-take the lock, so drop it first */
514 LEAVE_BUFFERED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100515 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000516 if (!ENTER_BUFFERED(self))
517 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600518 if (res == NULL)
519 PyErr_Fetch(&exc, &val, &tb);
520 else
521 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522
Petr Viktorinffd97532020-02-11 17:46:57 +0100523 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000524
Jesus Ceadc469452012-10-04 12:37:56 +0200525 if (self->buffer) {
526 PyMem_Free(self->buffer);
527 self->buffer = NULL;
528 }
529
Benjamin Peterson68623612012-12-20 11:53:11 -0600530 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300531 _PyErr_ChainExceptions(exc, val, tb);
532 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600533 }
534
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000535end:
536 LEAVE_BUFFERED(self)
537 return res;
538}
539
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000540/* detach */
541
542static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200543buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000544{
545 PyObject *raw, *res;
546 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100547 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000548 if (res == NULL)
549 return NULL;
550 Py_DECREF(res);
551 raw = self->raw;
552 self->raw = NULL;
553 self->detached = 1;
554 self->ok = 0;
555 return raw;
556}
557
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000558/* Inquiries */
559
560static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200561buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562{
563 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100564 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565}
566
567static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200568buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100571 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572}
573
574static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200575buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576{
577 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100578 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579}
580
581static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000582buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583{
584 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200585 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586}
587
588static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000589buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590{
591 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200592 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593}
594
595/* Lower-level APIs */
596
597static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200598buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100601 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200605buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100608 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611/* Forward decls */
612static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100613_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000617_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000619_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200621_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000623_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200628static Py_ssize_t
629_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630
631/*
632 * Helpers
633 */
634
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100635/* Sets the current error to BlockingIOError */
636static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200637_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100638{
639 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200640 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100641 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
642 errno, msg, written);
643 if (err)
644 PyErr_SetObject(PyExc_BlockingIOError, err);
645 Py_XDECREF(err);
646}
647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648/* Returns the address of the `written` member if a BlockingIOError was
649 raised, NULL otherwise. The error is always re-raised. */
650static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652{
653 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200654 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655
656 PyErr_Fetch(&t, &v, &tb);
657 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
658 PyErr_Restore(t, v, tb);
659 return NULL;
660 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200661 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662 /* TODO: sanity check (err->written >= 0) */
663 PyErr_Restore(t, v, tb);
664 return &err->written;
665}
666
667static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000668_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000671 PyObject *res;
Petr Viktorinffd97532020-02-11 17:46:57 +0100672 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673 if (res == NULL)
674 return -1;
675 n = PyNumber_AsOff_t(res, PyExc_ValueError);
676 Py_DECREF(res);
677 if (n < 0) {
678 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300679 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000680 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200681 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 return -1;
683 }
684 self->abs_pos = n;
685 return n;
686}
687
688static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000689_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690{
691 PyObject *res, *posobj, *whenceobj;
692 Py_off_t n;
693
694 posobj = PyLong_FromOff_t(target);
695 if (posobj == NULL)
696 return -1;
697 whenceobj = PyLong_FromLong(whence);
698 if (whenceobj == NULL) {
699 Py_DECREF(posobj);
700 return -1;
701 }
702 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
703 posobj, whenceobj, NULL);
704 Py_DECREF(posobj);
705 Py_DECREF(whenceobj);
706 if (res == NULL)
707 return -1;
708 n = PyNumber_AsOff_t(res, PyExc_ValueError);
709 Py_DECREF(res);
710 if (n < 0) {
711 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300712 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000713 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200714 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715 return -1;
716 }
717 self->abs_pos = n;
718 return n;
719}
720
721static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000722_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723{
724 Py_ssize_t n;
725 if (self->buffer_size <= 0) {
726 PyErr_SetString(PyExc_ValueError,
727 "buffer size must be strictly positive");
728 return -1;
729 }
730 if (self->buffer)
731 PyMem_Free(self->buffer);
732 self->buffer = PyMem_Malloc(self->buffer_size);
733 if (self->buffer == NULL) {
734 PyErr_NoMemory();
735 return -1;
736 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000737 if (self->lock)
738 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000739 self->lock = PyThread_allocate_lock();
740 if (self->lock == NULL) {
741 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
742 return -1;
743 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000744 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000745 /* Find out whether buffer_size is a power of 2 */
746 /* XXX is this optimization useful? */
747 for (n = self->buffer_size - 1; n & 1; n >>= 1)
748 ;
749 if (n == 0)
750 self->buffer_mask = self->buffer_size - 1;
751 else
752 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000753 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 PyErr_Clear();
755 return 0;
756}
757
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300758/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000759 clears the error indicator), 0 otherwise.
760 Should only be called when PyErr_Occurred() is true.
761*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700762int
763_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000764{
765 static PyObject *eintr_int = NULL;
766 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300767 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000768
769 if (eintr_int == NULL) {
770 eintr_int = PyLong_FromLong(EINTR);
771 assert(eintr_int != NULL);
772 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300773 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000774 return 0;
775 PyErr_Fetch(&typ, &val, &tb);
776 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300777 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000778 assert(env_err != NULL);
779 if (env_err->myerrno != NULL &&
780 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
781 Py_DECREF(typ);
782 Py_DECREF(val);
783 Py_XDECREF(tb);
784 return 1;
785 }
786 /* This silences any error set by PyObject_RichCompareBool() */
787 PyErr_Restore(typ, val, tb);
788 return 0;
789}
790
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000791/*
792 * Shared methods and wrappers
793 */
794
795static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200796buffered_flush_and_rewind_unlocked(buffered *self)
797{
798 PyObject *res;
799
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100800 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200801 if (res == NULL)
802 return NULL;
803 Py_DECREF(res);
804
805 if (self->readable) {
806 /* Rewind the raw stream so that its position corresponds to
807 the current logical position. */
808 Py_off_t n;
809 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
810 _bufferedreader_reset_buf(self);
811 if (n == -1)
812 return NULL;
813 }
814 Py_RETURN_NONE;
815}
816
817static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000818buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819{
820 PyObject *res;
821
822 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000823 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000824
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000825 if (!ENTER_BUFFERED(self))
826 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200827 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000828 LEAVE_BUFFERED(self)
829
830 return res;
831}
832
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300833/*[clinic input]
834_io._Buffered.peek
835 size: Py_ssize_t = 0
836 /
837
838[clinic start generated code]*/
839
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000840static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300841_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
842/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000844 PyObject *res = NULL;
845
846 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300847 CHECK_CLOSED(self, "peek of closed file")
848
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000849 if (!ENTER_BUFFERED(self))
850 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851
852 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200853 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000854 if (res == NULL)
855 goto end;
856 Py_CLEAR(res);
857 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200858 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859
860end:
861 LEAVE_BUFFERED(self)
862 return res;
863}
864
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300865/*[clinic input]
866_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300867 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300868 /
869[clinic start generated code]*/
870
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300872_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300873/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000874{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875 PyObject *res;
876
877 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000878 if (n < -1) {
879 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000880 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881 return NULL;
882 }
883
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000884 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000886 if (n == -1) {
887 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000888 if (!ENTER_BUFFERED(self))
889 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000890 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000891 }
892 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000893 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200894 if (res != Py_None)
895 return res;
896 Py_DECREF(res);
897 if (!ENTER_BUFFERED(self))
898 return NULL;
899 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000900 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901
Antoine Pitroue05565e2011-08-20 14:39:23 +0200902 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903 return res;
904}
905
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300906/*[clinic input]
907_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000908 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300909 /
910[clinic start generated code]*/
911
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300913_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000914/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300916 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 PyObject *res = NULL;
918
919 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000921 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300923
924 CHECK_CLOSED(self, "read of closed file")
925
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000926 if (n == 0)
927 return PyBytes_FromStringAndSize(NULL, 0);
928
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929 /* Return up to n bytes. If at least one byte is buffered, we
930 only return buffered bytes. Otherwise, we do one raw read. */
931
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
933 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100934 n = Py_MIN(have, n);
935 res = _bufferedreader_read_fast(self, n);
936 assert(res != Py_None);
937 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100939 res = PyBytes_FromStringAndSize(NULL, n);
940 if (res == NULL)
941 return NULL;
942 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200943 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100944 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200945 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000946 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100947 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
948 LEAVE_BUFFERED(self)
949 if (r == -1) {
950 Py_DECREF(res);
951 return NULL;
952 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 if (r == -2)
954 r = 0;
955 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100956 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 return res;
958}
959
960static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300961_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200963 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964 PyObject *res = NULL;
965
966 CHECK_INITIALIZED(self)
Philipp Gesangcb1c0742020-02-04 22:25:16 +0100967 CHECK_CLOSED(self, "readinto of closed file")
Antoine Pitrou3486a982011-05-12 01:57:53 +0200968
Antoine Pitrou3486a982011-05-12 01:57:53 +0200969 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
970 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300971 if (n >= buffer->len) {
972 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
973 self->pos += buffer->len;
974 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200975 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300976 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200977 self->pos += n;
978 written = n;
979 }
980
981 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300982 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200985 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986 if (res == NULL)
987 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000989 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200990
991 _bufferedreader_reset_buf(self);
992 self->pos = 0;
993
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300994 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995 remaining > 0;
996 written += n, remaining -= n) {
997 /* If remaining bytes is larger than internal buffer size, copy
998 * directly into caller's buffer. */
999 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001000 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001001 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001003
1004 /* In readinto1 mode, we do not want to fill the internal
1005 buffer if we already have some data to return */
1006 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001007 n = _bufferedreader_fill_buffer(self);
1008 if (n > 0) {
1009 if (n > remaining)
1010 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001011 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001012 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001013 self->pos += n;
1014 continue; /* short circuit */
1015 }
1016 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001017 else
1018 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001019
Antoine Pitrou3486a982011-05-12 01:57:53 +02001020 if (n == 0 || (n == -2 && written > 0))
1021 break;
1022 if (n < 0) {
1023 if (n == -2) {
1024 Py_INCREF(Py_None);
1025 res = Py_None;
1026 }
1027 goto end;
1028 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001029
Benjamin Petersona96fea02014-06-22 14:17:44 -07001030 /* At most one read in readinto1 mode */
1031 if (readinto1) {
1032 written += n;
1033 break;
1034 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001035 }
1036 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001037
1038end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001039 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001040 return res;
1041}
1042
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001043/*[clinic input]
1044_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001045 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001046 /
1047[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001048
1049static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001050_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001051/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001052{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001053 return _buffered_readinto_generic(self, buffer, 0);
1054}
1055
1056/*[clinic input]
1057_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001058 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001059 /
1060[clinic start generated code]*/
1061
1062static PyObject *
1063_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001064/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001065{
1066 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001067}
1068
1069
1070static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001071_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001072{
1073 PyObject *res = NULL;
1074 PyObject *chunks = NULL;
1075 Py_ssize_t n, written = 0;
1076 const char *start, *s, *end;
1077
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001078 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001080 /* First, try to find a line in the buffer. This can run unlocked because
1081 the calls to the C API are simple enough that they can't trigger
1082 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001083 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1084 if (limit >= 0 && n > limit)
1085 n = limit;
1086 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087 s = memchr(start, '\n', n);
1088 if (s != NULL) {
1089 res = PyBytes_FromStringAndSize(start, s - start + 1);
1090 if (res != NULL)
1091 self->pos += s - start + 1;
1092 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001093 }
1094 if (n == limit) {
1095 res = PyBytes_FromStringAndSize(start, n);
1096 if (res != NULL)
1097 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001098 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099 }
1100
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001101 if (!ENTER_BUFFERED(self))
1102 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001103
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001104 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105 chunks = PyList_New(0);
1106 if (chunks == NULL)
1107 goto end;
1108 if (n > 0) {
1109 res = PyBytes_FromStringAndSize(start, n);
1110 if (res == NULL)
1111 goto end;
1112 if (PyList_Append(chunks, res) < 0) {
1113 Py_CLEAR(res);
1114 goto end;
1115 }
1116 Py_CLEAR(res);
1117 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001118 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 if (limit >= 0)
1120 limit -= n;
1121 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001122 if (self->writable) {
1123 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1124 if (r == NULL)
1125 goto end;
1126 Py_DECREF(r);
1127 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128
1129 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001130 _bufferedreader_reset_buf(self);
1131 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132 if (n == -1)
1133 goto end;
1134 if (n <= 0)
1135 break;
1136 if (limit >= 0 && n > limit)
1137 n = limit;
1138 start = self->buffer;
1139 end = start + n;
1140 s = start;
1141 while (s < end) {
1142 if (*s++ == '\n') {
1143 res = PyBytes_FromStringAndSize(start, s - start);
1144 if (res == NULL)
1145 goto end;
1146 self->pos = s - start;
1147 goto found;
1148 }
1149 }
1150 res = PyBytes_FromStringAndSize(start, n);
1151 if (res == NULL)
1152 goto end;
1153 if (n == limit) {
1154 self->pos = n;
1155 break;
1156 }
1157 if (PyList_Append(chunks, res) < 0) {
1158 Py_CLEAR(res);
1159 goto end;
1160 }
1161 Py_CLEAR(res);
1162 written += n;
1163 if (limit >= 0)
1164 limit -= n;
1165 }
1166found:
1167 if (res != NULL && PyList_Append(chunks, res) < 0) {
1168 Py_CLEAR(res);
1169 goto end;
1170 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001171 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172
1173end:
1174 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001175end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176 Py_XDECREF(chunks);
1177 return res;
1178}
1179
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001180/*[clinic input]
1181_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001182 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001183 /
1184[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001186static PyObject *
1187_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001188/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001189{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001191 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192}
1193
1194
1195static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001196buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197{
1198 Py_off_t pos;
1199
1200 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001201 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202 if (pos == -1)
1203 return NULL;
1204 pos -= RAW_OFFSET(self);
1205 /* TODO: sanity check (pos >= 0) */
1206 return PyLong_FromOff_t(pos);
1207}
1208
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001209/*[clinic input]
1210_io._Buffered.seek
1211 target as targetobj: object
1212 whence: int = 0
1213 /
1214[clinic start generated code]*/
1215
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001216static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001217_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1218/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219{
1220 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001221 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222
1223 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001224
1225 /* Do some error checking instead of trusting OS 'seek()'
1226 ** error detection, just in case.
1227 */
1228 if ((whence < 0 || whence >2)
1229#ifdef SEEK_HOLE
1230 && (whence != SEEK_HOLE)
1231#endif
1232#ifdef SEEK_DATA
1233 && (whence != SEEK_DATA)
1234#endif
1235 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001237 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238 return NULL;
1239 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001240
1241 CHECK_CLOSED(self, "seek of closed file")
1242
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001243 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1244 return NULL;
1245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1247 if (target == -1 && PyErr_Occurred())
1248 return NULL;
1249
Jesus Cea94363612012-06-22 18:32:07 +02001250 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1251 buffer. Other whence values must be managed without this optimization.
1252 Some Operating Systems can provide additional values, like
1253 SEEK_HOLE/SEEK_DATA. */
1254 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001255 Py_off_t current, avail;
1256 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001257 so as to return quickly if possible. Also, we needn't take the
1258 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001259 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001260 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1261 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262 current = RAW_TELL(self);
1263 avail = READAHEAD(self);
1264 if (avail > 0) {
1265 Py_off_t offset;
1266 if (whence == 0)
1267 offset = target - (current - RAW_OFFSET(self));
1268 else
1269 offset = target;
1270 if (offset >= -self->pos && offset <= avail) {
1271 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001272 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 }
1274 }
1275 }
1276
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001277 if (!ENTER_BUFFERED(self))
1278 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001279
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001280 /* Fallback: invoke raw seek() method and clear buffer */
1281 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001282 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 if (res == NULL)
1284 goto end;
1285 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286 }
1287
1288 /* TODO: align on block boundary and read buffer if needed? */
1289 if (whence == 1)
1290 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001291 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 if (n == -1)
1293 goto end;
1294 self->raw_pos = -1;
1295 res = PyLong_FromOff_t(n);
1296 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001297 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298
1299end:
1300 LEAVE_BUFFERED(self)
1301 return res;
1302}
1303
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001304/*[clinic input]
1305_io._Buffered.truncate
1306 pos: object = None
1307 /
1308[clinic start generated code]*/
1309
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001311_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1312/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 PyObject *res = NULL;
1315
1316 CHECK_INITIALIZED(self)
Berker Peksagfd5116c2020-02-21 20:57:26 +03001317 CHECK_CLOSED(self, "truncate of closed file")
1318 if (!self->writable) {
1319 return bufferediobase_unsupported("truncate");
1320 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001321 if (!ENTER_BUFFERED(self))
1322 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001323
Berker Peksagfd5116c2020-02-21 20:57:26 +03001324 res = buffered_flush_and_rewind_unlocked(self);
1325 if (res == NULL) {
1326 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001327 }
Berker Peksagfd5116c2020-02-21 20:57:26 +03001328 Py_CLEAR(res);
1329
Petr Viktorinffd97532020-02-11 17:46:57 +01001330 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331 if (res == NULL)
1332 goto end;
1333 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001334 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 PyErr_Clear();
1336
1337end:
1338 LEAVE_BUFFERED(self)
1339 return res;
1340}
1341
1342static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001343buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001344{
1345 PyObject *line;
1346 PyTypeObject *tp;
1347
1348 CHECK_INITIALIZED(self);
1349
1350 tp = Py_TYPE(self);
1351 if (tp == &PyBufferedReader_Type ||
1352 tp == &PyBufferedRandom_Type) {
1353 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001354 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355 }
1356 else {
Petr Viktorinffd97532020-02-11 17:46:57 +01001357 line = PyObject_CallMethodNoArgs((PyObject *)self,
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001358 _PyIO_str_readline);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001360 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361 "readline() should have returned a bytes object, "
1362 "not '%.200s'", Py_TYPE(line)->tp_name);
1363 Py_DECREF(line);
1364 return NULL;
1365 }
1366 }
1367
1368 if (line == NULL)
1369 return NULL;
1370
1371 if (PyBytes_GET_SIZE(line) == 0) {
1372 /* Reached EOF or would have blocked */
1373 Py_DECREF(line);
1374 return NULL;
1375 }
1376
1377 return line;
1378}
1379
Antoine Pitrou716c4442009-05-23 19:04:03 +00001380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001381buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001382{
1383 PyObject *nameobj, *res;
1384
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001385 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1386 if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001387 return NULL;
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001388 }
1389 /* Ignore ValueError raised if the underlying stream was detached */
1390 PyErr_Clear();
1391 }
1392 if (nameobj == NULL) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001393 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1394 }
1395 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001396 int status = Py_ReprEnter((PyObject *)self);
1397 res = NULL;
1398 if (status == 0) {
1399 res = PyUnicode_FromFormat("<%s name=%R>",
1400 Py_TYPE(self)->tp_name, nameobj);
1401 Py_ReprLeave((PyObject *)self);
1402 }
1403 else if (status > 0) {
1404 PyErr_Format(PyExc_RuntimeError,
1405 "reentrant call inside %s.__repr__",
1406 Py_TYPE(self)->tp_name);
1407 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001408 Py_DECREF(nameobj);
1409 }
1410 return res;
1411}
1412
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001413/*
1414 * class BufferedReader
1415 */
1416
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001417static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001418{
1419 self->read_end = -1;
1420}
1421
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001422/*[clinic input]
1423_io.BufferedReader.__init__
1424 raw: object
1425 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001426
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001427Create a new buffered reader using the given readable raw IO object.
1428[clinic start generated code]*/
1429
1430static int
1431_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1432 Py_ssize_t buffer_size)
1433/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1434{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001436 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001438 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001439 return -1;
1440
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001442 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443 self->buffer_size = buffer_size;
1444 self->readable = 1;
1445 self->writable = 0;
1446
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001447 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001449 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450
Andy Lesterdffe4c02020-03-04 07:15:20 -06001451 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
1452 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001453
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454 self->ok = 1;
1455 return 0;
1456}
1457
1458static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001459_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001460{
1461 Py_buffer buf;
1462 PyObject *memobj, *res;
1463 Py_ssize_t n;
1464 /* NOTE: the buffer needn't be released as its object is NULL. */
1465 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1466 return -1;
1467 memobj = PyMemoryView_FromBuffer(&buf);
1468 if (memobj == NULL)
1469 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001470 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1471 occurs so we needn't do it ourselves.
1472 We then retry reading, ignoring the signal if no handler has
1473 raised (see issue #10956).
1474 */
1475 do {
Petr Viktorinffd97532020-02-11 17:46:57 +01001476 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj);
Gregory P. Smith51359922012-06-23 23:55:39 -07001477 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001478 Py_DECREF(memobj);
1479 if (res == NULL)
1480 return -1;
1481 if (res == Py_None) {
1482 /* Non-blocking stream would have blocked. Special return code! */
1483 Py_DECREF(res);
1484 return -2;
1485 }
1486 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1487 Py_DECREF(res);
1488 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001489 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001490 "raw readinto() returned invalid length %zd "
1491 "(should have been between 0 and %zd)", n, len);
1492 return -1;
1493 }
1494 if (n > 0 && self->abs_pos != -1)
1495 self->abs_pos += n;
1496 return n;
1497}
1498
1499static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001500_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001501{
1502 Py_ssize_t start, len, n;
1503 if (VALID_READ_BUFFER(self))
1504 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1505 else
1506 start = 0;
1507 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001508 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001509 if (n <= 0)
1510 return n;
1511 self->read_end = start + n;
1512 self->raw_pos = start + n;
1513 return n;
1514}
1515
1516static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001517_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001518{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001519 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001520 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001521
1522 /* First copy what we have in the current buffer. */
1523 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1524 if (current_size) {
1525 data = PyBytes_FromStringAndSize(
1526 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001527 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001528 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001529 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001530 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001531 /* We're going past the buffer's bounds, flush it */
1532 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001533 tmp = buffered_flush_and_rewind_unlocked(self);
1534 if (tmp == NULL)
1535 goto cleanup;
1536 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001537 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001538 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001539
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001540 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1541 goto cleanup;
1542 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001543 if (readall) {
1544 tmp = _PyObject_CallNoArg(readall);
1545 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001546 if (tmp == NULL)
1547 goto cleanup;
1548 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001549 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001550 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001551 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001552 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001553 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001554 } else {
1555 if (tmp != Py_None) {
1556 PyBytes_Concat(&data, tmp);
1557 }
1558 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001559 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001560 goto cleanup;
1561 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001562
1563 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001564 if (chunks == NULL)
1565 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001566
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567 while (1) {
1568 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 if (PyList_Append(chunks, data) < 0)
1570 goto cleanup;
1571 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001573
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001574 /* Read until EOF or until read() would block. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001575 data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001576 if (data == NULL)
1577 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001579 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001580 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581 }
1582 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1583 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001584 res = data;
1585 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586 }
1587 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001588 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1589 res = tmp;
1590 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001591 }
1592 }
1593 current_size += PyBytes_GET_SIZE(data);
1594 if (self->abs_pos != -1)
1595 self->abs_pos += PyBytes_GET_SIZE(data);
1596 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001597cleanup:
1598 /* res is either NULL or a borrowed ref */
1599 Py_XINCREF(res);
1600 Py_XDECREF(data);
1601 Py_XDECREF(tmp);
1602 Py_XDECREF(chunks);
1603 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001604}
1605
1606/* Read n bytes from the buffer if it can, otherwise return None.
1607 This function is simple enough that it can run unlocked. */
1608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001609_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001610{
1611 Py_ssize_t current_size;
1612
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001613 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1614 if (n <= current_size) {
1615 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001616 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1617 if (res != NULL)
1618 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001619 return res;
1620 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001621 Py_RETURN_NONE;
1622}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001623
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001624/* Generic read function: read from the stream until enough bytes are read,
1625 * or until an EOF occurs or until read() would block.
1626 */
1627static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001628_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001629{
1630 PyObject *res = NULL;
1631 Py_ssize_t current_size, remaining, written;
1632 char *out;
1633
1634 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1635 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001636 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001637
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001638 res = PyBytes_FromStringAndSize(NULL, n);
1639 if (res == NULL)
1640 goto error;
1641 out = PyBytes_AS_STRING(res);
1642 remaining = n;
1643 written = 0;
1644 if (current_size > 0) {
1645 memcpy(out, self->buffer + self->pos, current_size);
1646 remaining -= current_size;
1647 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001648 self->pos += current_size;
1649 }
1650 /* Flush the write buffer if necessary */
1651 if (self->writable) {
1652 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1653 if (r == NULL)
1654 goto error;
1655 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001656 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001657 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001658 while (remaining > 0) {
1659 /* We want to read a whole block at the end into buffer.
1660 If we had readv() we could do this in one pass. */
1661 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1662 if (r == 0)
1663 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001664 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001665 if (r == -1)
1666 goto error;
1667 if (r == 0 || r == -2) {
1668 /* EOF occurred or read() would block. */
1669 if (r == 0 || written > 0) {
1670 if (_PyBytes_Resize(&res, written))
1671 goto error;
1672 return res;
1673 }
1674 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001675 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001676 }
1677 remaining -= r;
1678 written += r;
1679 }
1680 assert(remaining <= self->buffer_size);
1681 self->pos = 0;
1682 self->raw_pos = 0;
1683 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001684 /* NOTE: when the read is satisfied, we avoid issuing any additional
1685 reads, which could block indefinitely (e.g. on a socket).
1686 See issue #9550. */
1687 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001688 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001689 if (r == -1)
1690 goto error;
1691 if (r == 0 || r == -2) {
1692 /* EOF occurred or read() would block. */
1693 if (r == 0 || written > 0) {
1694 if (_PyBytes_Resize(&res, written))
1695 goto error;
1696 return res;
1697 }
1698 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001699 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700 }
1701 if (remaining > r) {
1702 memcpy(out + written, self->buffer + self->pos, r);
1703 written += r;
1704 self->pos += r;
1705 remaining -= r;
1706 }
1707 else if (remaining > 0) {
1708 memcpy(out + written, self->buffer + self->pos, remaining);
1709 written += remaining;
1710 self->pos += remaining;
1711 remaining = 0;
1712 }
1713 if (remaining == 0)
1714 break;
1715 }
1716
1717 return res;
1718
1719error:
1720 Py_XDECREF(res);
1721 return NULL;
1722}
1723
1724static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001725_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001726{
1727 Py_ssize_t have, r;
1728
1729 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1730 /* Constraints:
1731 1. we don't want to advance the file position.
1732 2. we don't want to lose block alignment, so we can't shift the buffer
1733 to make some place.
1734 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1735 */
1736 if (have > 0) {
1737 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1738 }
1739
1740 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001741 _bufferedreader_reset_buf(self);
1742 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743 if (r == -1)
1744 return NULL;
1745 if (r == -2)
1746 r = 0;
1747 self->pos = 0;
1748 return PyBytes_FromStringAndSize(self->buffer, r);
1749}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750
1751
Benjamin Peterson59406a92009-03-26 17:10:29 +00001752
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001753/*
1754 * class BufferedWriter
1755 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001756static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001757_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001758{
1759 self->write_pos = 0;
1760 self->write_end = -1;
1761}
1762
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001763/*[clinic input]
1764_io.BufferedWriter.__init__
1765 raw: object
1766 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001768A buffer for a writeable sequential RawIO object.
1769
1770The constructor creates a BufferedWriter for the given writeable raw
1771stream. If the buffer_size is not given, it defaults to
1772DEFAULT_BUFFER_SIZE.
1773[clinic start generated code]*/
1774
1775static int
1776_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1777 Py_ssize_t buffer_size)
1778/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1779{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001781 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001782
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001783 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 return -1;
1785
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001787 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 self->readable = 0;
1789 self->writable = 1;
1790
1791 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001792 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001794 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 self->pos = 0;
1796
Andy Lesterdffe4c02020-03-04 07:15:20 -06001797 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
1798 Py_IS_TYPE(raw, &PyFileIO_Type));
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001799
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 self->ok = 1;
1801 return 0;
1802}
1803
1804static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001805_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806{
1807 Py_buffer buf;
1808 PyObject *memobj, *res;
1809 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001810 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 /* NOTE: the buffer needn't be released as its object is NULL. */
1812 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1813 return -1;
1814 memobj = PyMemoryView_FromBuffer(&buf);
1815 if (memobj == NULL)
1816 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001817 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1818 occurs so we needn't do it ourselves.
1819 We then retry writing, ignoring the signal if no handler has
1820 raised (see issue #10956).
1821 */
1822 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001823 errno = 0;
Petr Viktorinffd97532020-02-11 17:46:57 +01001824 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001825 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001826 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 Py_DECREF(memobj);
1828 if (res == NULL)
1829 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001830 if (res == Py_None) {
1831 /* Non-blocking stream would have blocked. Special return code!
1832 Being paranoid we reset errno in case it is changed by code
1833 triggered by a decref. errno is used by _set_BlockingIOError(). */
1834 Py_DECREF(res);
1835 errno = errnum;
1836 return -2;
1837 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1839 Py_DECREF(res);
1840 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001841 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001842 "raw write() returned invalid length %zd "
1843 "(should have been between 0 and %zd)", n, len);
1844 return -1;
1845 }
1846 if (n > 0 && self->abs_pos != -1)
1847 self->abs_pos += n;
1848 return n;
1849}
1850
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001851static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001852_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001853{
1854 Py_ssize_t written = 0;
1855 Py_off_t n, rewind;
1856
1857 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1858 goto end;
1859 /* First, rewind */
1860 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1861 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001862 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863 if (n < 0) {
1864 goto error;
1865 }
1866 self->raw_pos -= rewind;
1867 }
1868 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001869 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001870 self->buffer + self->write_pos,
1871 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1872 Py_off_t, Py_ssize_t));
1873 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001874 goto error;
1875 }
1876 else if (n == -2) {
1877 _set_BlockingIOError("write could not complete without blocking",
1878 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001879 goto error;
1880 }
1881 self->write_pos += n;
1882 self->raw_pos = self->write_pos;
1883 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001884 /* Partial writes can return successfully when interrupted by a
1885 signal (see write(2)). We must run signal handlers before
1886 blocking another time, possibly indefinitely. */
1887 if (PyErr_CheckSignals() < 0)
1888 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 }
1890
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001891
1892end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301893 /* This ensures that after return from this function,
1894 VALID_WRITE_BUFFER(self) returns false.
1895
1896 This is a required condition because when a tell() is called
1897 after flushing and if VALID_READ_BUFFER(self) is false, we need
1898 VALID_WRITE_BUFFER(self) to be false to have
1899 RAW_OFFSET(self) == 0.
1900
1901 Issue: https://bugs.python.org/issue32228 */
1902 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001903 Py_RETURN_NONE;
1904
1905error:
1906 return NULL;
1907}
1908
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001909/*[clinic input]
1910_io.BufferedWriter.write
1911 buffer: Py_buffer
1912 /
1913[clinic start generated code]*/
1914
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001916_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1917/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918{
1919 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001920 Py_ssize_t written, avail, remaining;
1921 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001922
1923 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001925 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001926 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001927
benfogle9703f092017-11-10 16:03:40 -05001928 /* Issue #31976: Check for closed file after acquiring the lock. Another
1929 thread could be holding the lock while closing the file. */
1930 if (IS_CLOSED(self)) {
1931 PyErr_SetString(PyExc_ValueError, "write to closed file");
1932 goto error;
1933 }
1934
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935 /* Fast path: the data to write can be fully buffered. */
1936 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1937 self->pos = 0;
1938 self->raw_pos = 0;
1939 }
1940 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001941 if (buffer->len <= avail) {
1942 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001943 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 self->write_pos = self->pos;
1945 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001946 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947 if (self->pos > self->write_end)
1948 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001949 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001950 goto end;
1951 }
1952
1953 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001954 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001956 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957 if (w == NULL)
1958 goto error;
1959 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001960 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001961 /* Make some place by shifting the buffer. */
1962 assert(VALID_WRITE_BUFFER(self));
1963 memmove(self->buffer, self->buffer + self->write_pos,
1964 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1965 Py_off_t, Py_ssize_t));
1966 self->write_end -= self->write_pos;
1967 self->raw_pos -= self->write_pos;
1968 self->pos -= self->write_pos;
1969 self->write_pos = 0;
1970 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1971 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001972 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973 /* Everything can be buffered */
1974 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001975 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1976 self->write_end += buffer->len;
1977 self->pos += buffer->len;
1978 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001979 goto end;
1980 }
1981 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001982 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001984 self->pos += avail;
1985 /* XXX Modifying the existing exception e using the pointer w
1986 will change e.characters_written but not e.args[2].
1987 Therefore we just replace with a new error. */
1988 _set_BlockingIOError("write could not complete without blocking",
1989 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001990 goto error;
1991 }
1992 Py_CLEAR(res);
1993
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001994 /* Adjust the raw stream position if it is away from the logical stream
1995 position. This happens if the read buffer has been filled but not
1996 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1997 the raw stream by itself).
1998 Fixes issue #6629.
1999 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002000 offset = RAW_OFFSET(self);
2001 if (offset != 0) {
2002 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002003 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002004 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002005 }
2006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002008 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002009 written = 0;
2010 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002011 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002012 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002013 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002014 goto error;
2015 } else if (n == -2) {
2016 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 if (remaining > self->buffer_size) {
2018 /* Can't buffer everything, still buffer as much as possible */
2019 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002020 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002021 self->raw_pos = 0;
2022 ADJUST_POSITION(self, self->buffer_size);
2023 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002024 written += self->buffer_size;
2025 _set_BlockingIOError("write could not complete without "
2026 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002027 goto error;
2028 }
2029 PyErr_Clear();
2030 break;
2031 }
2032 written += n;
2033 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002034 /* Partial writes can return successfully when interrupted by a
2035 signal (see write(2)). We must run signal handlers before
2036 blocking another time, possibly indefinitely. */
2037 if (PyErr_CheckSignals() < 0)
2038 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002039 }
2040 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002041 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002042 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002043 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002044 written += remaining;
2045 }
2046 self->write_pos = 0;
2047 /* TODO: sanity check (remaining >= 0) */
2048 self->write_end = remaining;
2049 ADJUST_POSITION(self, remaining);
2050 self->raw_pos = 0;
2051
2052end:
2053 res = PyLong_FromSsize_t(written);
2054
2055error:
2056 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002057 return res;
2058}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059
2060
2061
2062/*
2063 * BufferedRWPair
2064 */
2065
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066/* XXX The usefulness of this (compared to having two separate IO objects) is
2067 * questionable.
2068 */
2069
2070typedef struct {
2071 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002072 buffered *reader;
2073 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074 PyObject *dict;
2075 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002076} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002077
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002078/*[clinic input]
2079_io.BufferedRWPair.__init__
2080 reader: object
2081 writer: object
2082 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2083 /
2084
2085A buffered reader and writer object together.
2086
2087A buffered reader object and buffered writer object put together to
2088form a sequential IO object that can read and write. This is typically
2089used with a socket or two-way pipe.
2090
2091reader and writer are RawIOBase objects that are readable and
2092writeable respectively. If the buffer_size is omitted it defaults to
2093DEFAULT_BUFFER_SIZE.
2094[clinic start generated code]*/
2095
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002097_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2098 PyObject *writer, Py_ssize_t buffer_size)
2099/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002100{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002101 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002102 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104 return -1;
2105
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002106 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002107 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108 if (self->reader == NULL)
2109 return -1;
2110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002111 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002112 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113 if (self->writer == NULL) {
2114 Py_CLEAR(self->reader);
2115 return -1;
2116 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002117
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118 return 0;
2119}
2120
2121static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002122bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123{
2124 Py_VISIT(self->dict);
2125 return 0;
2126}
2127
2128static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002129bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130{
2131 Py_CLEAR(self->reader);
2132 Py_CLEAR(self->writer);
2133 Py_CLEAR(self->dict);
2134 return 0;
2135}
2136
2137static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002138bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002139{
2140 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002141 if (self->weakreflist != NULL)
2142 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143 Py_CLEAR(self->reader);
2144 Py_CLEAR(self->writer);
2145 Py_CLEAR(self->dict);
2146 Py_TYPE(self)->tp_free((PyObject *) self);
2147}
2148
2149static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002150_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002152 PyObject *func, *ret;
2153 if (self == NULL) {
2154 PyErr_SetString(PyExc_ValueError,
2155 "I/O operation on uninitialized object");
2156 return NULL;
2157 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002158
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002159 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002161 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002162 return NULL;
2163 }
2164
2165 ret = PyObject_CallObject(func, args);
2166 Py_DECREF(func);
2167 return ret;
2168}
2169
2170static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002171bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002173 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002174}
2175
2176static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002177bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002179 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180}
2181
2182static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002183bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002185 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186}
2187
2188static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002189bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002190{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002191 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002192}
2193
2194static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002195bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2196{
2197 return _forward_call(self->reader, &PyId_readinto1, args);
2198}
2199
2200static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002201bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002203 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002204}
2205
2206static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002207bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208{
jdemeyerfc512e32018-08-02 13:14:54 +02002209 return _forward_call(self->writer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210}
2211
2212static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002213bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214{
jdemeyerfc512e32018-08-02 13:14:54 +02002215 return _forward_call(self->reader, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216}
2217
2218static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002219bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220{
jdemeyerfc512e32018-08-02 13:14:54 +02002221 return _forward_call(self->writer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222}
2223
2224static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002225bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002227 PyObject *exc = NULL, *val, *tb;
jdemeyerfc512e32018-08-02 13:14:54 +02002228 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002230 PyErr_Fetch(&exc, &val, &tb);
2231 else
2232 Py_DECREF(ret);
jdemeyerfc512e32018-08-02 13:14:54 +02002233 ret = _forward_call(self->reader, &PyId_close, NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002234 if (exc != NULL) {
2235 _PyErr_ChainExceptions(exc, val, tb);
2236 Py_CLEAR(ret);
2237 }
2238 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239}
2240
2241static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002242bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002243{
jdemeyerfc512e32018-08-02 13:14:54 +02002244 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245
2246 if (ret != Py_False) {
2247 /* either True or exception */
2248 return ret;
2249 }
2250 Py_DECREF(ret);
2251
jdemeyerfc512e32018-08-02 13:14:54 +02002252 return _forward_call(self->reader, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002253}
2254
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002255static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002256bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002257{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002258 if (self->writer == NULL) {
2259 PyErr_SetString(PyExc_RuntimeError,
2260 "the BufferedRWPair object is being garbage-collected");
2261 return NULL;
2262 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002263 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2264}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002265
2266
2267
2268/*
2269 * BufferedRandom
2270 */
2271
2272/*[clinic input]
2273_io.BufferedRandom.__init__
2274 raw: object
2275 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2276
2277A buffered interface to random access streams.
2278
2279The constructor creates a reader and writer for a seekable stream,
2280raw, given in the first argument. If the buffer_size is omitted it
2281defaults to DEFAULT_BUFFER_SIZE.
2282[clinic start generated code]*/
2283
2284static int
2285_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2286 Py_ssize_t buffer_size)
2287/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2288{
2289 self->ok = 0;
2290 self->detached = 0;
2291
2292 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2293 return -1;
2294 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2295 return -1;
2296 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2297 return -1;
2298
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002299 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002300 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002301 self->buffer_size = buffer_size;
2302 self->readable = 1;
2303 self->writable = 1;
2304
2305 if (_buffered_init(self) < 0)
2306 return -1;
2307 _bufferedreader_reset_buf(self);
2308 _bufferedwriter_reset_buf(self);
2309 self->pos = 0;
2310
Andy Lesterdffe4c02020-03-04 07:15:20 -06002311 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
2312 Py_IS_TYPE(raw, &PyFileIO_Type));
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002313
2314 self->ok = 1;
2315 return 0;
2316}
2317
2318#include "clinic/bufferedio.c.h"
2319
2320
2321static PyMethodDef bufferediobase_methods[] = {
2322 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2323 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2324 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2325 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2326 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2327 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2328 {NULL, NULL}
2329};
2330
2331PyTypeObject PyBufferedIOBase_Type = {
2332 PyVarObject_HEAD_INIT(NULL, 0)
2333 "_io._BufferedIOBase", /*tp_name*/
2334 0, /*tp_basicsize*/
2335 0, /*tp_itemsize*/
2336 0, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002337 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002338 0, /*tp_getattr*/
2339 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002340 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002341 0, /*tp_repr*/
2342 0, /*tp_as_number*/
2343 0, /*tp_as_sequence*/
2344 0, /*tp_as_mapping*/
2345 0, /*tp_hash */
2346 0, /*tp_call*/
2347 0, /*tp_str*/
2348 0, /*tp_getattro*/
2349 0, /*tp_setattro*/
2350 0, /*tp_as_buffer*/
Antoine Pitrouada319b2019-05-29 22:12:38 +02002351 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002352 bufferediobase_doc, /* tp_doc */
2353 0, /* tp_traverse */
2354 0, /* tp_clear */
2355 0, /* tp_richcompare */
2356 0, /* tp_weaklistoffset */
2357 0, /* tp_iter */
2358 0, /* tp_iternext */
2359 bufferediobase_methods, /* tp_methods */
2360 0, /* tp_members */
2361 0, /* tp_getset */
2362 &PyIOBase_Type, /* tp_base */
2363 0, /* tp_dict */
2364 0, /* tp_descr_get */
2365 0, /* tp_descr_set */
2366 0, /* tp_dictoffset */
2367 0, /* tp_init */
2368 0, /* tp_alloc */
2369 0, /* tp_new */
2370 0, /* tp_free */
2371 0, /* tp_is_gc */
2372 0, /* tp_bases */
2373 0, /* tp_mro */
2374 0, /* tp_cache */
2375 0, /* tp_subclasses */
2376 0, /* tp_weaklist */
2377 0, /* tp_del */
2378 0, /* tp_version_tag */
2379 0, /* tp_finalize */
2380};
2381
2382
2383static PyMethodDef bufferedreader_methods[] = {
2384 /* BufferedIOMixin methods */
2385 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2386 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2387 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2388 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2389 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002390 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2391 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2392 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002393
2394 _IO__BUFFERED_READ_METHODDEF
2395 _IO__BUFFERED_PEEK_METHODDEF
2396 _IO__BUFFERED_READ1_METHODDEF
2397 _IO__BUFFERED_READINTO_METHODDEF
2398 _IO__BUFFERED_READINTO1_METHODDEF
2399 _IO__BUFFERED_READLINE_METHODDEF
2400 _IO__BUFFERED_SEEK_METHODDEF
2401 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2402 _IO__BUFFERED_TRUNCATE_METHODDEF
2403 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2404 {NULL, NULL}
2405};
2406
2407static PyMemberDef bufferedreader_members[] = {
2408 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2409 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2410 {NULL}
2411};
2412
2413static PyGetSetDef bufferedreader_getset[] = {
2414 {"closed", (getter)buffered_closed_get, NULL, NULL},
2415 {"name", (getter)buffered_name_get, NULL, NULL},
2416 {"mode", (getter)buffered_mode_get, NULL, NULL},
2417 {NULL}
2418};
2419
2420
2421PyTypeObject PyBufferedReader_Type = {
2422 PyVarObject_HEAD_INIT(NULL, 0)
2423 "_io.BufferedReader", /*tp_name*/
2424 sizeof(buffered), /*tp_basicsize*/
2425 0, /*tp_itemsize*/
2426 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002427 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002428 0, /*tp_getattr*/
2429 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002430 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002431 (reprfunc)buffered_repr, /*tp_repr*/
2432 0, /*tp_as_number*/
2433 0, /*tp_as_sequence*/
2434 0, /*tp_as_mapping*/
2435 0, /*tp_hash */
2436 0, /*tp_call*/
2437 0, /*tp_str*/
2438 0, /*tp_getattro*/
2439 0, /*tp_setattro*/
2440 0, /*tp_as_buffer*/
2441 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002442 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002443 _io_BufferedReader___init____doc__, /* tp_doc */
2444 (traverseproc)buffered_traverse, /* tp_traverse */
2445 (inquiry)buffered_clear, /* tp_clear */
2446 0, /* tp_richcompare */
2447 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2448 0, /* tp_iter */
2449 (iternextfunc)buffered_iternext, /* tp_iternext */
2450 bufferedreader_methods, /* tp_methods */
2451 bufferedreader_members, /* tp_members */
2452 bufferedreader_getset, /* tp_getset */
2453 0, /* tp_base */
2454 0, /* tp_dict */
2455 0, /* tp_descr_get */
2456 0, /* tp_descr_set */
2457 offsetof(buffered, dict), /* tp_dictoffset */
2458 _io_BufferedReader___init__, /* tp_init */
2459 0, /* tp_alloc */
2460 PyType_GenericNew, /* tp_new */
2461 0, /* tp_free */
2462 0, /* tp_is_gc */
2463 0, /* tp_bases */
2464 0, /* tp_mro */
2465 0, /* tp_cache */
2466 0, /* tp_subclasses */
2467 0, /* tp_weaklist */
2468 0, /* tp_del */
2469 0, /* tp_version_tag */
2470 0, /* tp_finalize */
2471};
2472
2473
2474static PyMethodDef bufferedwriter_methods[] = {
2475 /* BufferedIOMixin methods */
2476 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2477 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2478 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002479 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2480 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2481 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2482 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002483
2484 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2485 _IO__BUFFERED_TRUNCATE_METHODDEF
2486 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2487 _IO__BUFFERED_SEEK_METHODDEF
2488 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2489 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2490 {NULL, NULL}
2491};
2492
2493static PyMemberDef bufferedwriter_members[] = {
2494 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2495 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2496 {NULL}
2497};
2498
2499static PyGetSetDef bufferedwriter_getset[] = {
2500 {"closed", (getter)buffered_closed_get, NULL, NULL},
2501 {"name", (getter)buffered_name_get, NULL, NULL},
2502 {"mode", (getter)buffered_mode_get, NULL, NULL},
2503 {NULL}
2504};
2505
2506
2507PyTypeObject PyBufferedWriter_Type = {
2508 PyVarObject_HEAD_INIT(NULL, 0)
2509 "_io.BufferedWriter", /*tp_name*/
2510 sizeof(buffered), /*tp_basicsize*/
2511 0, /*tp_itemsize*/
2512 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002513 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002514 0, /*tp_getattr*/
2515 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002516 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002517 (reprfunc)buffered_repr, /*tp_repr*/
2518 0, /*tp_as_number*/
2519 0, /*tp_as_sequence*/
2520 0, /*tp_as_mapping*/
2521 0, /*tp_hash */
2522 0, /*tp_call*/
2523 0, /*tp_str*/
2524 0, /*tp_getattro*/
2525 0, /*tp_setattro*/
2526 0, /*tp_as_buffer*/
2527 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002528 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002529 _io_BufferedWriter___init____doc__, /* tp_doc */
2530 (traverseproc)buffered_traverse, /* tp_traverse */
2531 (inquiry)buffered_clear, /* tp_clear */
2532 0, /* tp_richcompare */
2533 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2534 0, /* tp_iter */
2535 0, /* tp_iternext */
2536 bufferedwriter_methods, /* tp_methods */
2537 bufferedwriter_members, /* tp_members */
2538 bufferedwriter_getset, /* tp_getset */
2539 0, /* tp_base */
2540 0, /* tp_dict */
2541 0, /* tp_descr_get */
2542 0, /* tp_descr_set */
2543 offsetof(buffered, dict), /* tp_dictoffset */
2544 _io_BufferedWriter___init__, /* tp_init */
2545 0, /* tp_alloc */
2546 PyType_GenericNew, /* tp_new */
2547 0, /* tp_free */
2548 0, /* tp_is_gc */
2549 0, /* tp_bases */
2550 0, /* tp_mro */
2551 0, /* tp_cache */
2552 0, /* tp_subclasses */
2553 0, /* tp_weaklist */
2554 0, /* tp_del */
2555 0, /* tp_version_tag */
2556 0, /* tp_finalize */
2557};
2558
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002560static PyMethodDef bufferedrwpair_methods[] = {
2561 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2562 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2563 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2564 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002565 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2568 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2571 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2574 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575
2576 {NULL, NULL}
2577};
2578
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002579static PyGetSetDef bufferedrwpair_getset[] = {
2580 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002581 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002582};
2583
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002584PyTypeObject PyBufferedRWPair_Type = {
2585 PyVarObject_HEAD_INIT(NULL, 0)
2586 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002587 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002588 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002589 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002590 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002591 0, /*tp_getattr*/
2592 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002593 0, /*tp_as_async*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002594 0, /*tp_repr*/
2595 0, /*tp_as_number*/
2596 0, /*tp_as_sequence*/
2597 0, /*tp_as_mapping*/
2598 0, /*tp_hash */
2599 0, /*tp_call*/
2600 0, /*tp_str*/
2601 0, /*tp_getattro*/
2602 0, /*tp_setattro*/
2603 0, /*tp_as_buffer*/
2604 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002605 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002606 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002607 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2608 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002609 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002610 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002611 0, /* tp_iter */
2612 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002613 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002614 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002615 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616 0, /* tp_base */
2617 0, /* tp_dict */
2618 0, /* tp_descr_get */
2619 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002620 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002621 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002622 0, /* tp_alloc */
2623 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002624 0, /* tp_free */
2625 0, /* tp_is_gc */
2626 0, /* tp_bases */
2627 0, /* tp_mro */
2628 0, /* tp_cache */
2629 0, /* tp_subclasses */
2630 0, /* tp_weaklist */
2631 0, /* tp_del */
2632 0, /* tp_version_tag */
2633 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002634};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635
2636
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002637static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002638 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002639 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2640 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2641 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2642 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2643 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2644 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2645 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002646 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002648 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002649
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002650 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002651 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002652 _IO__BUFFERED_TRUNCATE_METHODDEF
2653 _IO__BUFFERED_READ_METHODDEF
2654 _IO__BUFFERED_READ1_METHODDEF
2655 _IO__BUFFERED_READINTO_METHODDEF
2656 _IO__BUFFERED_READINTO1_METHODDEF
2657 _IO__BUFFERED_READLINE_METHODDEF
2658 _IO__BUFFERED_PEEK_METHODDEF
2659 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002660 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002661 {NULL, NULL}
2662};
2663
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002664static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002665 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002666 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002667 {NULL}
2668};
2669
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002670static PyGetSetDef bufferedrandom_getset[] = {
2671 {"closed", (getter)buffered_closed_get, NULL, NULL},
2672 {"name", (getter)buffered_name_get, NULL, NULL},
2673 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002674 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002675};
2676
2677
2678PyTypeObject PyBufferedRandom_Type = {
2679 PyVarObject_HEAD_INIT(NULL, 0)
2680 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002681 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002682 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002683 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002684 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002685 0, /*tp_getattr*/
2686 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002687 0, /*tp_as_async*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002688 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002689 0, /*tp_as_number*/
2690 0, /*tp_as_sequence*/
2691 0, /*tp_as_mapping*/
2692 0, /*tp_hash */
2693 0, /*tp_call*/
2694 0, /*tp_str*/
2695 0, /*tp_getattro*/
2696 0, /*tp_setattro*/
2697 0, /*tp_as_buffer*/
2698 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002699 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002700 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002701 (traverseproc)buffered_traverse, /* tp_traverse */
2702 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002703 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002704 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002705 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002706 (iternextfunc)buffered_iternext, /* tp_iternext */
2707 bufferedrandom_methods, /* tp_methods */
2708 bufferedrandom_members, /* tp_members */
2709 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002710 0, /* tp_base */
2711 0, /*tp_dict*/
2712 0, /* tp_descr_get */
2713 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002714 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002715 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002716 0, /* tp_alloc */
2717 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002718 0, /* tp_free */
2719 0, /* tp_is_gc */
2720 0, /* tp_bases */
2721 0, /* tp_mro */
2722 0, /* tp_cache */
2723 0, /* tp_subclasses */
2724 0, /* tp_weaklist */
2725 0, /* tp_del */
2726 0, /* tp_version_tag */
2727 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002728};