blob: a09082c84f8a210c903f12f988f69983dc87d8da [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) {
295 PyObject *msgobj = PyUnicode_FromFormat(
296 "could not acquire lock for %A at interpreter "
297 "shutdown, possibly due to daemon threads",
298 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200299 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200300 Py_FatalError(msg);
301 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000302 return 1;
303}
304
305#define ENTER_BUFFERED(self) \
306 ( (PyThread_acquire_lock(self->lock, 0) ? \
307 1 : _enter_buffered_busy(self)) \
308 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000309
310#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000311 do { \
312 self->owner = 0; \
313 PyThread_release_lock(self->lock); \
314 } while(0);
315
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000316#define CHECK_INITIALIZED(self) \
317 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000318 if (self->detached) { \
319 PyErr_SetString(PyExc_ValueError, \
320 "raw stream has been detached"); \
321 } else { \
322 PyErr_SetString(PyExc_ValueError, \
323 "I/O operation on uninitialized object"); \
324 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000325 return NULL; \
326 }
327
328#define CHECK_INITIALIZED_INT(self) \
329 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000330 if (self->detached) { \
331 PyErr_SetString(PyExc_ValueError, \
332 "raw stream has been detached"); \
333 } else { \
334 PyErr_SetString(PyExc_ValueError, \
335 "I/O operation on uninitialized object"); \
336 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000337 return -1; \
338 }
339
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000340#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500341 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000342 (self->fast_closed_checks \
343 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500344 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000345
346#define CHECK_CLOSED(self, error_msg) \
347 if (IS_CLOSED(self)) { \
348 PyErr_SetString(PyExc_ValueError, error_msg); \
349 return NULL; \
350 }
351
352
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000353#define VALID_READ_BUFFER(self) \
354 (self->readable && self->read_end != -1)
355
356#define VALID_WRITE_BUFFER(self) \
357 (self->writable && self->write_end != -1)
358
359#define ADJUST_POSITION(self, _new_pos) \
360 do { \
361 self->pos = _new_pos; \
362 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
363 self->read_end = self->pos; \
364 } while(0)
365
366#define READAHEAD(self) \
367 ((self->readable && VALID_READ_BUFFER(self)) \
368 ? (self->read_end - self->pos) : 0)
369
370#define RAW_OFFSET(self) \
371 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
372 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
373
374#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000375 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000376
377#define MINUS_LAST_BLOCK(self, size) \
378 (self->buffer_mask ? \
379 (size & ~self->buffer_mask) : \
380 (self->buffer_size * (size / self->buffer_size)))
381
382
383static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000384buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200386 self->finalizing = 1;
387 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 return;
389 _PyObject_GC_UNTRACK(self);
390 self->ok = 0;
391 if (self->weakreflist != NULL)
392 PyObject_ClearWeakRefs((PyObject *)self);
393 Py_CLEAR(self->raw);
394 if (self->buffer) {
395 PyMem_Free(self->buffer);
396 self->buffer = NULL;
397 }
398 if (self->lock) {
399 PyThread_free_lock(self->lock);
400 self->lock = NULL;
401 }
402 Py_CLEAR(self->dict);
403 Py_TYPE(self)->tp_free((PyObject *)self);
404}
405
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200406static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200407buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200408{
409 Py_ssize_t res;
410
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200411 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200412 if (self->buffer)
413 res += self->buffer_size;
414 return PyLong_FromSsize_t(res);
415}
416
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000417static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000418buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000419{
420 Py_VISIT(self->raw);
421 Py_VISIT(self->dict);
422 return 0;
423}
424
425static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000426buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000427{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000428 self->ok = 0;
429 Py_CLEAR(self->raw);
430 Py_CLEAR(self->dict);
431 return 0;
432}
433
Antoine Pitroue033e062010-10-29 10:38:18 +0000434/* Because this can call arbitrary code, it shouldn't be called when
435 the refcount is 0 (that is, not directly from tp_dealloc unless
436 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000437static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000438buffered_dealloc_warn(buffered *self, PyObject *source)
439{
440 if (self->ok && self->raw) {
441 PyObject *r;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200442 r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn,
443 source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000444 if (r)
445 Py_DECREF(r);
446 else
447 PyErr_Clear();
448 }
449 Py_RETURN_NONE;
450}
451
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000452/*
453 * _BufferedIOMixin methods
454 * This is not a class, just a collection of methods that will be reused
455 * by BufferedReader and BufferedWriter
456 */
457
458/* Flush and close */
459
460static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000461buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462{
463 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100464 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000465}
466
467static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000468buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000469{
470 int closed;
471 PyObject *res;
472 CHECK_INITIALIZED_INT(self)
473 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
474 if (res == NULL)
475 return -1;
476 closed = PyObject_IsTrue(res);
477 Py_DECREF(res);
478 return closed;
479}
480
481static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000482buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000483{
484 CHECK_INITIALIZED(self)
485 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
486}
487
488static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000489buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000490{
Benjamin Peterson68623612012-12-20 11:53:11 -0600491 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000492 int r;
493
494 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000495 if (!ENTER_BUFFERED(self))
496 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000497
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000498 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000499 if (r < 0)
500 goto end;
501 if (r > 0) {
502 res = Py_None;
503 Py_INCREF(res);
504 goto end;
505 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000506
Antoine Pitrou796564c2013-07-30 19:59:21 +0200507 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000508 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
509 if (r)
510 Py_DECREF(r);
511 else
512 PyErr_Clear();
513 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000514 /* flush() will most probably re-take the lock, so drop it first */
515 LEAVE_BUFFERED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100516 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000517 if (!ENTER_BUFFERED(self))
518 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600519 if (res == NULL)
520 PyErr_Fetch(&exc, &val, &tb);
521 else
522 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000523
Petr Viktorinffd97532020-02-11 17:46:57 +0100524 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000525
Jesus Ceadc469452012-10-04 12:37:56 +0200526 if (self->buffer) {
527 PyMem_Free(self->buffer);
528 self->buffer = NULL;
529 }
530
Benjamin Peterson68623612012-12-20 11:53:11 -0600531 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300532 _PyErr_ChainExceptions(exc, val, tb);
533 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600534 }
535
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000536end:
537 LEAVE_BUFFERED(self)
538 return res;
539}
540
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000541/* detach */
542
543static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200544buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000545{
546 PyObject *raw, *res;
547 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100548 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000549 if (res == NULL)
550 return NULL;
551 Py_DECREF(res);
552 raw = self->raw;
553 self->raw = NULL;
554 self->detached = 1;
555 self->ok = 0;
556 return raw;
557}
558
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000559/* Inquiries */
560
561static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200562buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000563{
564 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100565 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000566}
567
568static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200569buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570{
571 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100572 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573}
574
575static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200576buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000577{
578 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100579 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580}
581
582static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000583buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584{
585 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200586 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000587}
588
589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000590buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591{
592 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200593 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594}
595
596/* Lower-level APIs */
597
598static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200599buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600{
601 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100602 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000603}
604
605static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200606buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607{
608 CHECK_INITIALIZED(self)
Petr Viktorinffd97532020-02-11 17:46:57 +0100609 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000610}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000611
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000612/* Forward decls */
613static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100614_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000616_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000618_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000621static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200622_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000624_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000625static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000626_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000627static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000628_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200629static Py_ssize_t
630_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000631
632/*
633 * Helpers
634 */
635
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100636/* Sets the current error to BlockingIOError */
637static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200638_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100639{
640 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200641 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100642 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
643 errno, msg, written);
644 if (err)
645 PyErr_SetObject(PyExc_BlockingIOError, err);
646 Py_XDECREF(err);
647}
648
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649/* Returns the address of the `written` member if a BlockingIOError was
650 raised, NULL otherwise. The error is always re-raised. */
651static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653{
654 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200655 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
657 PyErr_Fetch(&t, &v, &tb);
658 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
659 PyErr_Restore(t, v, tb);
660 return NULL;
661 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200662 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000663 /* TODO: sanity check (err->written >= 0) */
664 PyErr_Restore(t, v, tb);
665 return &err->written;
666}
667
668static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000669_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000672 PyObject *res;
Petr Viktorinffd97532020-02-11 17:46:57 +0100673 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674 if (res == NULL)
675 return -1;
676 n = PyNumber_AsOff_t(res, PyExc_ValueError);
677 Py_DECREF(res);
678 if (n < 0) {
679 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300680 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000681 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200682 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000683 return -1;
684 }
685 self->abs_pos = n;
686 return n;
687}
688
689static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000690_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691{
692 PyObject *res, *posobj, *whenceobj;
693 Py_off_t n;
694
695 posobj = PyLong_FromOff_t(target);
696 if (posobj == NULL)
697 return -1;
698 whenceobj = PyLong_FromLong(whence);
699 if (whenceobj == NULL) {
700 Py_DECREF(posobj);
701 return -1;
702 }
703 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
704 posobj, whenceobj, NULL);
705 Py_DECREF(posobj);
706 Py_DECREF(whenceobj);
707 if (res == NULL)
708 return -1;
709 n = PyNumber_AsOff_t(res, PyExc_ValueError);
710 Py_DECREF(res);
711 if (n < 0) {
712 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300713 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000714 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200715 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716 return -1;
717 }
718 self->abs_pos = n;
719 return n;
720}
721
722static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000723_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000724{
725 Py_ssize_t n;
726 if (self->buffer_size <= 0) {
727 PyErr_SetString(PyExc_ValueError,
728 "buffer size must be strictly positive");
729 return -1;
730 }
731 if (self->buffer)
732 PyMem_Free(self->buffer);
733 self->buffer = PyMem_Malloc(self->buffer_size);
734 if (self->buffer == NULL) {
735 PyErr_NoMemory();
736 return -1;
737 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000738 if (self->lock)
739 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740 self->lock = PyThread_allocate_lock();
741 if (self->lock == NULL) {
742 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
743 return -1;
744 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000745 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000746 /* Find out whether buffer_size is a power of 2 */
747 /* XXX is this optimization useful? */
748 for (n = self->buffer_size - 1; n & 1; n >>= 1)
749 ;
750 if (n == 0)
751 self->buffer_mask = self->buffer_size - 1;
752 else
753 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000754 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000755 PyErr_Clear();
756 return 0;
757}
758
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300759/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000760 clears the error indicator), 0 otherwise.
761 Should only be called when PyErr_Occurred() is true.
762*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700763int
764_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000765{
766 static PyObject *eintr_int = NULL;
767 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300768 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000769
770 if (eintr_int == NULL) {
771 eintr_int = PyLong_FromLong(EINTR);
772 assert(eintr_int != NULL);
773 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300774 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000775 return 0;
776 PyErr_Fetch(&typ, &val, &tb);
777 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300778 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000779 assert(env_err != NULL);
780 if (env_err->myerrno != NULL &&
781 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
782 Py_DECREF(typ);
783 Py_DECREF(val);
784 Py_XDECREF(tb);
785 return 1;
786 }
787 /* This silences any error set by PyObject_RichCompareBool() */
788 PyErr_Restore(typ, val, tb);
789 return 0;
790}
791
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000792/*
793 * Shared methods and wrappers
794 */
795
796static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200797buffered_flush_and_rewind_unlocked(buffered *self)
798{
799 PyObject *res;
800
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100801 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200802 if (res == NULL)
803 return NULL;
804 Py_DECREF(res);
805
806 if (self->readable) {
807 /* Rewind the raw stream so that its position corresponds to
808 the current logical position. */
809 Py_off_t n;
810 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
811 _bufferedreader_reset_buf(self);
812 if (n == -1)
813 return NULL;
814 }
815 Py_RETURN_NONE;
816}
817
818static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000819buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000820{
821 PyObject *res;
822
823 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000824 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000825
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000826 if (!ENTER_BUFFERED(self))
827 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200828 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000829 LEAVE_BUFFERED(self)
830
831 return res;
832}
833
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300834/*[clinic input]
835_io._Buffered.peek
836 size: Py_ssize_t = 0
837 /
838
839[clinic start generated code]*/
840
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000841static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300842_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
843/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000844{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000845 PyObject *res = NULL;
846
847 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300848 CHECK_CLOSED(self, "peek of closed file")
849
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000850 if (!ENTER_BUFFERED(self))
851 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852
853 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200854 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855 if (res == NULL)
856 goto end;
857 Py_CLEAR(res);
858 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200859 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860
861end:
862 LEAVE_BUFFERED(self)
863 return res;
864}
865
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300866/*[clinic input]
867_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300868 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300869 /
870[clinic start generated code]*/
871
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000872static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300873_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300874/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000876 PyObject *res;
877
878 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000879 if (n < -1) {
880 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000881 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882 return NULL;
883 }
884
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000885 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000887 if (n == -1) {
888 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000889 if (!ENTER_BUFFERED(self))
890 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000891 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000892 }
893 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000894 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200895 if (res != Py_None)
896 return res;
897 Py_DECREF(res);
898 if (!ENTER_BUFFERED(self))
899 return NULL;
900 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000901 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902
Antoine Pitroue05565e2011-08-20 14:39:23 +0200903 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000904 return res;
905}
906
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300907/*[clinic input]
908_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000909 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300910 /
911[clinic start generated code]*/
912
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300914_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000915/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000916{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300917 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000918 PyObject *res = NULL;
919
920 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000921 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000922 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300924
925 CHECK_CLOSED(self, "read of closed file")
926
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927 if (n == 0)
928 return PyBytes_FromStringAndSize(NULL, 0);
929
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930 /* Return up to n bytes. If at least one byte is buffered, we
931 only return buffered bytes. Otherwise, we do one raw read. */
932
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000933 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
934 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100935 n = Py_MIN(have, n);
936 res = _bufferedreader_read_fast(self, n);
937 assert(res != Py_None);
938 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100940 res = PyBytes_FromStringAndSize(NULL, n);
941 if (res == NULL)
942 return NULL;
943 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200944 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100945 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200946 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000947 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100948 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
949 LEAVE_BUFFERED(self)
950 if (r == -1) {
951 Py_DECREF(res);
952 return NULL;
953 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954 if (r == -2)
955 r = 0;
956 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100957 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 return res;
959}
960
961static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300962_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200964 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000965 PyObject *res = NULL;
966
967 CHECK_INITIALIZED(self)
Philipp Gesangcb1c0742020-02-04 22:25:16 +0100968 CHECK_CLOSED(self, "readinto of closed file")
Antoine Pitrou3486a982011-05-12 01:57:53 +0200969
Antoine Pitrou3486a982011-05-12 01:57:53 +0200970 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
971 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300972 if (n >= buffer->len) {
973 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
974 self->pos += buffer->len;
975 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200976 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300977 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200978 self->pos += n;
979 written = n;
980 }
981
982 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300983 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200984
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200986 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987 if (res == NULL)
988 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200989 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200991
992 _bufferedreader_reset_buf(self);
993 self->pos = 0;
994
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300995 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996 remaining > 0;
997 written += n, remaining -= n) {
998 /* If remaining bytes is larger than internal buffer size, copy
999 * directly into caller's buffer. */
1000 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001001 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001002 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001003 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001004
1005 /* In readinto1 mode, we do not want to fill the internal
1006 buffer if we already have some data to return */
1007 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001008 n = _bufferedreader_fill_buffer(self);
1009 if (n > 0) {
1010 if (n > remaining)
1011 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001012 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001013 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001014 self->pos += n;
1015 continue; /* short circuit */
1016 }
1017 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001018 else
1019 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001020
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 if (n == 0 || (n == -2 && written > 0))
1022 break;
1023 if (n < 0) {
1024 if (n == -2) {
1025 Py_INCREF(Py_None);
1026 res = Py_None;
1027 }
1028 goto end;
1029 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001030
Benjamin Petersona96fea02014-06-22 14:17:44 -07001031 /* At most one read in readinto1 mode */
1032 if (readinto1) {
1033 written += n;
1034 break;
1035 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001036 }
1037 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001038
1039end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001040 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 return res;
1042}
1043
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001044/*[clinic input]
1045_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001046 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001047 /
1048[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001049
1050static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001051_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001052/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001053{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001054 return _buffered_readinto_generic(self, buffer, 0);
1055}
1056
1057/*[clinic input]
1058_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001059 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001060 /
1061[clinic start generated code]*/
1062
1063static PyObject *
1064_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001065/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001066{
1067 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001068}
1069
1070
1071static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001072_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001073{
1074 PyObject *res = NULL;
1075 PyObject *chunks = NULL;
1076 Py_ssize_t n, written = 0;
1077 const char *start, *s, *end;
1078
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001079 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001080
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001081 /* First, try to find a line in the buffer. This can run unlocked because
1082 the calls to the C API are simple enough that they can't trigger
1083 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001084 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1085 if (limit >= 0 && n > limit)
1086 n = limit;
1087 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001088 s = memchr(start, '\n', n);
1089 if (s != NULL) {
1090 res = PyBytes_FromStringAndSize(start, s - start + 1);
1091 if (res != NULL)
1092 self->pos += s - start + 1;
1093 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001094 }
1095 if (n == limit) {
1096 res = PyBytes_FromStringAndSize(start, n);
1097 if (res != NULL)
1098 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001099 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100 }
1101
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001102 if (!ENTER_BUFFERED(self))
1103 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001104
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106 chunks = PyList_New(0);
1107 if (chunks == NULL)
1108 goto end;
1109 if (n > 0) {
1110 res = PyBytes_FromStringAndSize(start, n);
1111 if (res == NULL)
1112 goto end;
1113 if (PyList_Append(chunks, res) < 0) {
1114 Py_CLEAR(res);
1115 goto end;
1116 }
1117 Py_CLEAR(res);
1118 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001119 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001120 if (limit >= 0)
1121 limit -= n;
1122 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001123 if (self->writable) {
1124 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1125 if (r == NULL)
1126 goto end;
1127 Py_DECREF(r);
1128 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001129
1130 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001131 _bufferedreader_reset_buf(self);
1132 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001133 if (n == -1)
1134 goto end;
1135 if (n <= 0)
1136 break;
1137 if (limit >= 0 && n > limit)
1138 n = limit;
1139 start = self->buffer;
1140 end = start + n;
1141 s = start;
1142 while (s < end) {
1143 if (*s++ == '\n') {
1144 res = PyBytes_FromStringAndSize(start, s - start);
1145 if (res == NULL)
1146 goto end;
1147 self->pos = s - start;
1148 goto found;
1149 }
1150 }
1151 res = PyBytes_FromStringAndSize(start, n);
1152 if (res == NULL)
1153 goto end;
1154 if (n == limit) {
1155 self->pos = n;
1156 break;
1157 }
1158 if (PyList_Append(chunks, res) < 0) {
1159 Py_CLEAR(res);
1160 goto end;
1161 }
1162 Py_CLEAR(res);
1163 written += n;
1164 if (limit >= 0)
1165 limit -= n;
1166 }
1167found:
1168 if (res != NULL && PyList_Append(chunks, res) < 0) {
1169 Py_CLEAR(res);
1170 goto end;
1171 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001172 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001173
1174end:
1175 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001176end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177 Py_XDECREF(chunks);
1178 return res;
1179}
1180
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001181/*[clinic input]
1182_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001183 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001184 /
1185[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001187static PyObject *
1188_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001189/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001190{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001191 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001192 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001193}
1194
1195
1196static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001197buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001198{
1199 Py_off_t pos;
1200
1201 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001202 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001203 if (pos == -1)
1204 return NULL;
1205 pos -= RAW_OFFSET(self);
1206 /* TODO: sanity check (pos >= 0) */
1207 return PyLong_FromOff_t(pos);
1208}
1209
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001210/*[clinic input]
1211_io._Buffered.seek
1212 target as targetobj: object
1213 whence: int = 0
1214 /
1215[clinic start generated code]*/
1216
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001218_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1219/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220{
1221 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001222 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001223
1224 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001225
1226 /* Do some error checking instead of trusting OS 'seek()'
1227 ** error detection, just in case.
1228 */
1229 if ((whence < 0 || whence >2)
1230#ifdef SEEK_HOLE
1231 && (whence != SEEK_HOLE)
1232#endif
1233#ifdef SEEK_DATA
1234 && (whence != SEEK_DATA)
1235#endif
1236 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001237 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001238 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239 return NULL;
1240 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001241
1242 CHECK_CLOSED(self, "seek of closed file")
1243
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001244 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1245 return NULL;
1246
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001247 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1248 if (target == -1 && PyErr_Occurred())
1249 return NULL;
1250
Jesus Cea94363612012-06-22 18:32:07 +02001251 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1252 buffer. Other whence values must be managed without this optimization.
1253 Some Operating Systems can provide additional values, like
1254 SEEK_HOLE/SEEK_DATA. */
1255 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 Py_off_t current, avail;
1257 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001258 so as to return quickly if possible. Also, we needn't take the
1259 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001261 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1262 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 current = RAW_TELL(self);
1264 avail = READAHEAD(self);
1265 if (avail > 0) {
1266 Py_off_t offset;
1267 if (whence == 0)
1268 offset = target - (current - RAW_OFFSET(self));
1269 else
1270 offset = target;
1271 if (offset >= -self->pos && offset <= avail) {
1272 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001273 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 }
1275 }
1276 }
1277
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001278 if (!ENTER_BUFFERED(self))
1279 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001280
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001281 /* Fallback: invoke raw seek() method and clear buffer */
1282 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001283 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001284 if (res == NULL)
1285 goto end;
1286 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001287 }
1288
1289 /* TODO: align on block boundary and read buffer if needed? */
1290 if (whence == 1)
1291 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001292 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001293 if (n == -1)
1294 goto end;
1295 self->raw_pos = -1;
1296 res = PyLong_FromOff_t(n);
1297 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001298 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001299
1300end:
1301 LEAVE_BUFFERED(self)
1302 return res;
1303}
1304
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001305/*[clinic input]
1306_io._Buffered.truncate
1307 pos: object = None
1308 /
1309[clinic start generated code]*/
1310
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001312_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1313/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001315 PyObject *res = NULL;
1316
1317 CHECK_INITIALIZED(self)
Berker Peksagfd5116c2020-02-21 20:57:26 +03001318 CHECK_CLOSED(self, "truncate of closed file")
1319 if (!self->writable) {
1320 return bufferediobase_unsupported("truncate");
1321 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001322 if (!ENTER_BUFFERED(self))
1323 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001324
Berker Peksagfd5116c2020-02-21 20:57:26 +03001325 res = buffered_flush_and_rewind_unlocked(self);
1326 if (res == NULL) {
1327 goto end;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328 }
Berker Peksagfd5116c2020-02-21 20:57:26 +03001329 Py_CLEAR(res);
1330
Petr Viktorinffd97532020-02-11 17:46:57 +01001331 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001332 if (res == NULL)
1333 goto end;
1334 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001335 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336 PyErr_Clear();
1337
1338end:
1339 LEAVE_BUFFERED(self)
1340 return res;
1341}
1342
1343static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001344buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001345{
1346 PyObject *line;
1347 PyTypeObject *tp;
1348
1349 CHECK_INITIALIZED(self);
1350
1351 tp = Py_TYPE(self);
1352 if (tp == &PyBufferedReader_Type ||
1353 tp == &PyBufferedRandom_Type) {
1354 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001355 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001356 }
1357 else {
Petr Viktorinffd97532020-02-11 17:46:57 +01001358 line = PyObject_CallMethodNoArgs((PyObject *)self,
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02001359 _PyIO_str_readline);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001361 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362 "readline() should have returned a bytes object, "
1363 "not '%.200s'", Py_TYPE(line)->tp_name);
1364 Py_DECREF(line);
1365 return NULL;
1366 }
1367 }
1368
1369 if (line == NULL)
1370 return NULL;
1371
1372 if (PyBytes_GET_SIZE(line) == 0) {
1373 /* Reached EOF or would have blocked */
1374 Py_DECREF(line);
1375 return NULL;
1376 }
1377
1378 return line;
1379}
1380
Antoine Pitrou716c4442009-05-23 19:04:03 +00001381static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001382buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001383{
1384 PyObject *nameobj, *res;
1385
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001386 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1387 if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001388 return NULL;
Serhiy Storchakab235a1b2019-08-29 09:25:22 +03001389 }
1390 /* Ignore ValueError raised if the underlying stream was detached */
1391 PyErr_Clear();
1392 }
1393 if (nameobj == NULL) {
Antoine Pitrou716c4442009-05-23 19:04:03 +00001394 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1395 }
1396 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001397 int status = Py_ReprEnter((PyObject *)self);
1398 res = NULL;
1399 if (status == 0) {
1400 res = PyUnicode_FromFormat("<%s name=%R>",
1401 Py_TYPE(self)->tp_name, nameobj);
1402 Py_ReprLeave((PyObject *)self);
1403 }
1404 else if (status > 0) {
1405 PyErr_Format(PyExc_RuntimeError,
1406 "reentrant call inside %s.__repr__",
1407 Py_TYPE(self)->tp_name);
1408 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001409 Py_DECREF(nameobj);
1410 }
1411 return res;
1412}
1413
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001414/*
1415 * class BufferedReader
1416 */
1417
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001418static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001419{
1420 self->read_end = -1;
1421}
1422
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001423/*[clinic input]
1424_io.BufferedReader.__init__
1425 raw: object
1426 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001427
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001428Create a new buffered reader using the given readable raw IO object.
1429[clinic start generated code]*/
1430
1431static int
1432_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1433 Py_ssize_t buffer_size)
1434/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1435{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001436 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001437 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001439 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440 return -1;
1441
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001442 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001443 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001444 self->buffer_size = buffer_size;
1445 self->readable = 1;
1446 self->writable = 0;
1447
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001448 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001449 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001450 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001451
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001452 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1453 Py_TYPE(raw) == &PyFileIO_Type);
1454
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001455 self->ok = 1;
1456 return 0;
1457}
1458
1459static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001460_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001461{
1462 Py_buffer buf;
1463 PyObject *memobj, *res;
1464 Py_ssize_t n;
1465 /* NOTE: the buffer needn't be released as its object is NULL. */
1466 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1467 return -1;
1468 memobj = PyMemoryView_FromBuffer(&buf);
1469 if (memobj == NULL)
1470 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001471 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1472 occurs so we needn't do it ourselves.
1473 We then retry reading, ignoring the signal if no handler has
1474 raised (see issue #10956).
1475 */
1476 do {
Petr Viktorinffd97532020-02-11 17:46:57 +01001477 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj);
Gregory P. Smith51359922012-06-23 23:55:39 -07001478 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 Py_DECREF(memobj);
1480 if (res == NULL)
1481 return -1;
1482 if (res == Py_None) {
1483 /* Non-blocking stream would have blocked. Special return code! */
1484 Py_DECREF(res);
1485 return -2;
1486 }
1487 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1488 Py_DECREF(res);
1489 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001490 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001491 "raw readinto() returned invalid length %zd "
1492 "(should have been between 0 and %zd)", n, len);
1493 return -1;
1494 }
1495 if (n > 0 && self->abs_pos != -1)
1496 self->abs_pos += n;
1497 return n;
1498}
1499
1500static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001501_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001502{
1503 Py_ssize_t start, len, n;
1504 if (VALID_READ_BUFFER(self))
1505 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1506 else
1507 start = 0;
1508 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001509 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001510 if (n <= 0)
1511 return n;
1512 self->read_end = start + n;
1513 self->raw_pos = start + n;
1514 return n;
1515}
1516
1517static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001518_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001519{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001520 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001521 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001522
1523 /* First copy what we have in the current buffer. */
1524 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1525 if (current_size) {
1526 data = PyBytes_FromStringAndSize(
1527 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001528 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001529 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001530 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001531 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001532 /* We're going past the buffer's bounds, flush it */
1533 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001534 tmp = buffered_flush_and_rewind_unlocked(self);
1535 if (tmp == NULL)
1536 goto cleanup;
1537 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001538 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001539 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001540
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001541 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1542 goto cleanup;
1543 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001544 if (readall) {
1545 tmp = _PyObject_CallNoArg(readall);
1546 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001547 if (tmp == NULL)
1548 goto cleanup;
1549 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001550 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001551 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001552 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001553 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001554 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001555 } else {
1556 if (tmp != Py_None) {
1557 PyBytes_Concat(&data, tmp);
1558 }
1559 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001560 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001561 goto cleanup;
1562 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001563
1564 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001565 if (chunks == NULL)
1566 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001567
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001568 while (1) {
1569 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001570 if (PyList_Append(chunks, data) < 0)
1571 goto cleanup;
1572 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001573 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001574
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001575 /* Read until EOF or until read() would block. */
Petr Viktorinffd97532020-02-11 17:46:57 +01001576 data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001577 if (data == NULL)
1578 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001579 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001580 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001581 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001582 }
1583 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1584 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001585 res = data;
1586 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001587 }
1588 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001589 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1590 res = tmp;
1591 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001592 }
1593 }
1594 current_size += PyBytes_GET_SIZE(data);
1595 if (self->abs_pos != -1)
1596 self->abs_pos += PyBytes_GET_SIZE(data);
1597 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001598cleanup:
1599 /* res is either NULL or a borrowed ref */
1600 Py_XINCREF(res);
1601 Py_XDECREF(data);
1602 Py_XDECREF(tmp);
1603 Py_XDECREF(chunks);
1604 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001605}
1606
1607/* Read n bytes from the buffer if it can, otherwise return None.
1608 This function is simple enough that it can run unlocked. */
1609static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001610_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611{
1612 Py_ssize_t current_size;
1613
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001614 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1615 if (n <= current_size) {
1616 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001617 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1618 if (res != NULL)
1619 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620 return res;
1621 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001622 Py_RETURN_NONE;
1623}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001624
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001625/* Generic read function: read from the stream until enough bytes are read,
1626 * or until an EOF occurs or until read() would block.
1627 */
1628static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001630{
1631 PyObject *res = NULL;
1632 Py_ssize_t current_size, remaining, written;
1633 char *out;
1634
1635 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1636 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001637 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001638
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001639 res = PyBytes_FromStringAndSize(NULL, n);
1640 if (res == NULL)
1641 goto error;
1642 out = PyBytes_AS_STRING(res);
1643 remaining = n;
1644 written = 0;
1645 if (current_size > 0) {
1646 memcpy(out, self->buffer + self->pos, current_size);
1647 remaining -= current_size;
1648 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001649 self->pos += current_size;
1650 }
1651 /* Flush the write buffer if necessary */
1652 if (self->writable) {
1653 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1654 if (r == NULL)
1655 goto error;
1656 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001657 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001658 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001659 while (remaining > 0) {
1660 /* We want to read a whole block at the end into buffer.
1661 If we had readv() we could do this in one pass. */
1662 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1663 if (r == 0)
1664 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001665 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001666 if (r == -1)
1667 goto error;
1668 if (r == 0 || r == -2) {
1669 /* EOF occurred or read() would block. */
1670 if (r == 0 || written > 0) {
1671 if (_PyBytes_Resize(&res, written))
1672 goto error;
1673 return res;
1674 }
1675 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001676 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001677 }
1678 remaining -= r;
1679 written += r;
1680 }
1681 assert(remaining <= self->buffer_size);
1682 self->pos = 0;
1683 self->raw_pos = 0;
1684 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001685 /* NOTE: when the read is satisfied, we avoid issuing any additional
1686 reads, which could block indefinitely (e.g. on a socket).
1687 See issue #9550. */
1688 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001689 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001690 if (r == -1)
1691 goto error;
1692 if (r == 0 || r == -2) {
1693 /* EOF occurred or read() would block. */
1694 if (r == 0 || written > 0) {
1695 if (_PyBytes_Resize(&res, written))
1696 goto error;
1697 return res;
1698 }
1699 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001700 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001701 }
1702 if (remaining > r) {
1703 memcpy(out + written, self->buffer + self->pos, r);
1704 written += r;
1705 self->pos += r;
1706 remaining -= r;
1707 }
1708 else if (remaining > 0) {
1709 memcpy(out + written, self->buffer + self->pos, remaining);
1710 written += remaining;
1711 self->pos += remaining;
1712 remaining = 0;
1713 }
1714 if (remaining == 0)
1715 break;
1716 }
1717
1718 return res;
1719
1720error:
1721 Py_XDECREF(res);
1722 return NULL;
1723}
1724
1725static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001726_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001727{
1728 Py_ssize_t have, r;
1729
1730 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1731 /* Constraints:
1732 1. we don't want to advance the file position.
1733 2. we don't want to lose block alignment, so we can't shift the buffer
1734 to make some place.
1735 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1736 */
1737 if (have > 0) {
1738 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1739 }
1740
1741 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001742 _bufferedreader_reset_buf(self);
1743 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001744 if (r == -1)
1745 return NULL;
1746 if (r == -2)
1747 r = 0;
1748 self->pos = 0;
1749 return PyBytes_FromStringAndSize(self->buffer, r);
1750}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001751
1752
Benjamin Peterson59406a92009-03-26 17:10:29 +00001753
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001754/*
1755 * class BufferedWriter
1756 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001758_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759{
1760 self->write_pos = 0;
1761 self->write_end = -1;
1762}
1763
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001764/*[clinic input]
1765_io.BufferedWriter.__init__
1766 raw: object
1767 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001768
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001769A buffer for a writeable sequential RawIO object.
1770
1771The constructor creates a BufferedWriter for the given writeable raw
1772stream. If the buffer_size is not given, it defaults to
1773DEFAULT_BUFFER_SIZE.
1774[clinic start generated code]*/
1775
1776static int
1777_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1778 Py_ssize_t buffer_size)
1779/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1780{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001782 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785 return -1;
1786
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001788 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789 self->readable = 0;
1790 self->writable = 1;
1791
1792 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001793 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001795 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001796 self->pos = 0;
1797
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001798 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1799 Py_TYPE(raw) == &PyFileIO_Type);
1800
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 self->ok = 1;
1802 return 0;
1803}
1804
1805static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001806_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807{
1808 Py_buffer buf;
1809 PyObject *memobj, *res;
1810 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001811 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812 /* NOTE: the buffer needn't be released as its object is NULL. */
1813 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1814 return -1;
1815 memobj = PyMemoryView_FromBuffer(&buf);
1816 if (memobj == NULL)
1817 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001818 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1819 occurs so we needn't do it ourselves.
1820 We then retry writing, ignoring the signal if no handler has
1821 raised (see issue #10956).
1822 */
1823 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001824 errno = 0;
Petr Viktorinffd97532020-02-11 17:46:57 +01001825 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001826 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001827 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828 Py_DECREF(memobj);
1829 if (res == NULL)
1830 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001831 if (res == Py_None) {
1832 /* Non-blocking stream would have blocked. Special return code!
1833 Being paranoid we reset errno in case it is changed by code
1834 triggered by a decref. errno is used by _set_BlockingIOError(). */
1835 Py_DECREF(res);
1836 errno = errnum;
1837 return -2;
1838 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001839 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1840 Py_DECREF(res);
1841 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001842 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001843 "raw write() returned invalid length %zd "
1844 "(should have been between 0 and %zd)", n, len);
1845 return -1;
1846 }
1847 if (n > 0 && self->abs_pos != -1)
1848 self->abs_pos += n;
1849 return n;
1850}
1851
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001852static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001853_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854{
1855 Py_ssize_t written = 0;
1856 Py_off_t n, rewind;
1857
1858 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1859 goto end;
1860 /* First, rewind */
1861 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1862 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001863 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864 if (n < 0) {
1865 goto error;
1866 }
1867 self->raw_pos -= rewind;
1868 }
1869 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001870 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001871 self->buffer + self->write_pos,
1872 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1873 Py_off_t, Py_ssize_t));
1874 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001875 goto error;
1876 }
1877 else if (n == -2) {
1878 _set_BlockingIOError("write could not complete without blocking",
1879 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880 goto error;
1881 }
1882 self->write_pos += n;
1883 self->raw_pos = self->write_pos;
1884 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001885 /* Partial writes can return successfully when interrupted by a
1886 signal (see write(2)). We must run signal handlers before
1887 blocking another time, possibly indefinitely. */
1888 if (PyErr_CheckSignals() < 0)
1889 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001890 }
1891
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001892
1893end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301894 /* This ensures that after return from this function,
1895 VALID_WRITE_BUFFER(self) returns false.
1896
1897 This is a required condition because when a tell() is called
1898 after flushing and if VALID_READ_BUFFER(self) is false, we need
1899 VALID_WRITE_BUFFER(self) to be false to have
1900 RAW_OFFSET(self) == 0.
1901
1902 Issue: https://bugs.python.org/issue32228 */
1903 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001904 Py_RETURN_NONE;
1905
1906error:
1907 return NULL;
1908}
1909
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001910/*[clinic input]
1911_io.BufferedWriter.write
1912 buffer: Py_buffer
1913 /
1914[clinic start generated code]*/
1915
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001917_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1918/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001919{
1920 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001921 Py_ssize_t written, avail, remaining;
1922 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923
1924 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001925
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001926 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001927 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928
benfogle9703f092017-11-10 16:03:40 -05001929 /* Issue #31976: Check for closed file after acquiring the lock. Another
1930 thread could be holding the lock while closing the file. */
1931 if (IS_CLOSED(self)) {
1932 PyErr_SetString(PyExc_ValueError, "write to closed file");
1933 goto error;
1934 }
1935
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936 /* Fast path: the data to write can be fully buffered. */
1937 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1938 self->pos = 0;
1939 self->raw_pos = 0;
1940 }
1941 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001942 if (buffer->len <= avail) {
1943 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001944 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945 self->write_pos = self->pos;
1946 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001947 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 if (self->pos > self->write_end)
1949 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001950 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951 goto end;
1952 }
1953
1954 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001955 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001956 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001957 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 if (w == NULL)
1959 goto error;
1960 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001961 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001962 /* Make some place by shifting the buffer. */
1963 assert(VALID_WRITE_BUFFER(self));
1964 memmove(self->buffer, self->buffer + self->write_pos,
1965 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1966 Py_off_t, Py_ssize_t));
1967 self->write_end -= self->write_pos;
1968 self->raw_pos -= self->write_pos;
1969 self->pos -= self->write_pos;
1970 self->write_pos = 0;
1971 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1972 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001973 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001974 /* Everything can be buffered */
1975 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001976 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1977 self->write_end += buffer->len;
1978 self->pos += buffer->len;
1979 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001980 goto end;
1981 }
1982 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001983 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001984 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001985 self->pos += avail;
1986 /* XXX Modifying the existing exception e using the pointer w
1987 will change e.characters_written but not e.args[2].
1988 Therefore we just replace with a new error. */
1989 _set_BlockingIOError("write could not complete without blocking",
1990 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 goto error;
1992 }
1993 Py_CLEAR(res);
1994
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001995 /* Adjust the raw stream position if it is away from the logical stream
1996 position. This happens if the read buffer has been filled but not
1997 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1998 the raw stream by itself).
1999 Fixes issue #6629.
2000 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002001 offset = RAW_OFFSET(self);
2002 if (offset != 0) {
2003 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002004 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002005 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002006 }
2007
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002009 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 written = 0;
2011 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002012 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002013 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002015 goto error;
2016 } else if (n == -2) {
2017 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 if (remaining > self->buffer_size) {
2019 /* Can't buffer everything, still buffer as much as possible */
2020 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002021 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022 self->raw_pos = 0;
2023 ADJUST_POSITION(self, self->buffer_size);
2024 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002025 written += self->buffer_size;
2026 _set_BlockingIOError("write could not complete without "
2027 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002028 goto error;
2029 }
2030 PyErr_Clear();
2031 break;
2032 }
2033 written += n;
2034 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002035 /* Partial writes can return successfully when interrupted by a
2036 signal (see write(2)). We must run signal handlers before
2037 blocking another time, possibly indefinitely. */
2038 if (PyErr_CheckSignals() < 0)
2039 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002040 }
2041 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002042 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002043 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002044 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002045 written += remaining;
2046 }
2047 self->write_pos = 0;
2048 /* TODO: sanity check (remaining >= 0) */
2049 self->write_end = remaining;
2050 ADJUST_POSITION(self, remaining);
2051 self->raw_pos = 0;
2052
2053end:
2054 res = PyLong_FromSsize_t(written);
2055
2056error:
2057 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002058 return res;
2059}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060
2061
2062
2063/*
2064 * BufferedRWPair
2065 */
2066
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002067/* XXX The usefulness of this (compared to having two separate IO objects) is
2068 * questionable.
2069 */
2070
2071typedef struct {
2072 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002073 buffered *reader;
2074 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075 PyObject *dict;
2076 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002077} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002079/*[clinic input]
2080_io.BufferedRWPair.__init__
2081 reader: object
2082 writer: object
2083 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2084 /
2085
2086A buffered reader and writer object together.
2087
2088A buffered reader object and buffered writer object put together to
2089form a sequential IO object that can read and write. This is typically
2090used with a socket or two-way pipe.
2091
2092reader and writer are RawIOBase objects that are readable and
2093writeable respectively. If the buffer_size is omitted it defaults to
2094DEFAULT_BUFFER_SIZE.
2095[clinic start generated code]*/
2096
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002098_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2099 PyObject *writer, Py_ssize_t buffer_size)
2100/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002102 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002103 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002104 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002105 return -1;
2106
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002107 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002108 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 if (self->reader == NULL)
2110 return -1;
2111
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002112 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002113 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002114 if (self->writer == NULL) {
2115 Py_CLEAR(self->reader);
2116 return -1;
2117 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002118
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002119 return 0;
2120}
2121
2122static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124{
2125 Py_VISIT(self->dict);
2126 return 0;
2127}
2128
2129static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002130bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131{
2132 Py_CLEAR(self->reader);
2133 Py_CLEAR(self->writer);
2134 Py_CLEAR(self->dict);
2135 return 0;
2136}
2137
2138static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140{
2141 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002142 if (self->weakreflist != NULL)
2143 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002144 Py_CLEAR(self->reader);
2145 Py_CLEAR(self->writer);
2146 Py_CLEAR(self->dict);
2147 Py_TYPE(self)->tp_free((PyObject *) self);
2148}
2149
2150static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002151_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002153 PyObject *func, *ret;
2154 if (self == NULL) {
2155 PyErr_SetString(PyExc_ValueError,
2156 "I/O operation on uninitialized object");
2157 return NULL;
2158 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002160 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002162 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002163 return NULL;
2164 }
2165
2166 ret = PyObject_CallObject(func, args);
2167 Py_DECREF(func);
2168 return ret;
2169}
2170
2171static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002172bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002174 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175}
2176
2177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002178bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002180 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181}
2182
2183static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002184bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002185{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002186 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002187}
2188
2189static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002190bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002191{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002192 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002193}
2194
2195static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002196bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2197{
2198 return _forward_call(self->reader, &PyId_readinto1, args);
2199}
2200
2201static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002202bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002204 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205}
2206
2207static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002208bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209{
jdemeyerfc512e32018-08-02 13:14:54 +02002210 return _forward_call(self->writer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211}
2212
2213static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002214bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215{
jdemeyerfc512e32018-08-02 13:14:54 +02002216 return _forward_call(self->reader, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217}
2218
2219static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002220bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221{
jdemeyerfc512e32018-08-02 13:14:54 +02002222 return _forward_call(self->writer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223}
2224
2225static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002226bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002228 PyObject *exc = NULL, *val, *tb;
jdemeyerfc512e32018-08-02 13:14:54 +02002229 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002231 PyErr_Fetch(&exc, &val, &tb);
2232 else
2233 Py_DECREF(ret);
jdemeyerfc512e32018-08-02 13:14:54 +02002234 ret = _forward_call(self->reader, &PyId_close, NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002235 if (exc != NULL) {
2236 _PyErr_ChainExceptions(exc, val, tb);
2237 Py_CLEAR(ret);
2238 }
2239 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240}
2241
2242static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002243bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002244{
jdemeyerfc512e32018-08-02 13:14:54 +02002245 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246
2247 if (ret != Py_False) {
2248 /* either True or exception */
2249 return ret;
2250 }
2251 Py_DECREF(ret);
2252
jdemeyerfc512e32018-08-02 13:14:54 +02002253 return _forward_call(self->reader, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254}
2255
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002256static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002257bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002258{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002259 if (self->writer == NULL) {
2260 PyErr_SetString(PyExc_RuntimeError,
2261 "the BufferedRWPair object is being garbage-collected");
2262 return NULL;
2263 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002264 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2265}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002266
2267
2268
2269/*
2270 * BufferedRandom
2271 */
2272
2273/*[clinic input]
2274_io.BufferedRandom.__init__
2275 raw: object
2276 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2277
2278A buffered interface to random access streams.
2279
2280The constructor creates a reader and writer for a seekable stream,
2281raw, given in the first argument. If the buffer_size is omitted it
2282defaults to DEFAULT_BUFFER_SIZE.
2283[clinic start generated code]*/
2284
2285static int
2286_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2287 Py_ssize_t buffer_size)
2288/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2289{
2290 self->ok = 0;
2291 self->detached = 0;
2292
2293 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2294 return -1;
2295 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2296 return -1;
2297 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2298 return -1;
2299
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002300 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002301 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002302 self->buffer_size = buffer_size;
2303 self->readable = 1;
2304 self->writable = 1;
2305
2306 if (_buffered_init(self) < 0)
2307 return -1;
2308 _bufferedreader_reset_buf(self);
2309 _bufferedwriter_reset_buf(self);
2310 self->pos = 0;
2311
2312 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2313 Py_TYPE(raw) == &PyFileIO_Type);
2314
2315 self->ok = 1;
2316 return 0;
2317}
2318
2319#include "clinic/bufferedio.c.h"
2320
2321
2322static PyMethodDef bufferediobase_methods[] = {
2323 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2324 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2325 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2326 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2327 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2328 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2329 {NULL, NULL}
2330};
2331
2332PyTypeObject PyBufferedIOBase_Type = {
2333 PyVarObject_HEAD_INIT(NULL, 0)
2334 "_io._BufferedIOBase", /*tp_name*/
2335 0, /*tp_basicsize*/
2336 0, /*tp_itemsize*/
2337 0, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002338 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002339 0, /*tp_getattr*/
2340 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002341 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002342 0, /*tp_repr*/
2343 0, /*tp_as_number*/
2344 0, /*tp_as_sequence*/
2345 0, /*tp_as_mapping*/
2346 0, /*tp_hash */
2347 0, /*tp_call*/
2348 0, /*tp_str*/
2349 0, /*tp_getattro*/
2350 0, /*tp_setattro*/
2351 0, /*tp_as_buffer*/
Antoine Pitrouada319b2019-05-29 22:12:38 +02002352 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002353 bufferediobase_doc, /* tp_doc */
2354 0, /* tp_traverse */
2355 0, /* tp_clear */
2356 0, /* tp_richcompare */
2357 0, /* tp_weaklistoffset */
2358 0, /* tp_iter */
2359 0, /* tp_iternext */
2360 bufferediobase_methods, /* tp_methods */
2361 0, /* tp_members */
2362 0, /* tp_getset */
2363 &PyIOBase_Type, /* tp_base */
2364 0, /* tp_dict */
2365 0, /* tp_descr_get */
2366 0, /* tp_descr_set */
2367 0, /* tp_dictoffset */
2368 0, /* tp_init */
2369 0, /* tp_alloc */
2370 0, /* tp_new */
2371 0, /* tp_free */
2372 0, /* tp_is_gc */
2373 0, /* tp_bases */
2374 0, /* tp_mro */
2375 0, /* tp_cache */
2376 0, /* tp_subclasses */
2377 0, /* tp_weaklist */
2378 0, /* tp_del */
2379 0, /* tp_version_tag */
2380 0, /* tp_finalize */
2381};
2382
2383
2384static PyMethodDef bufferedreader_methods[] = {
2385 /* BufferedIOMixin methods */
2386 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2387 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2388 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2389 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2390 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002391 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2392 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2393 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002394
2395 _IO__BUFFERED_READ_METHODDEF
2396 _IO__BUFFERED_PEEK_METHODDEF
2397 _IO__BUFFERED_READ1_METHODDEF
2398 _IO__BUFFERED_READINTO_METHODDEF
2399 _IO__BUFFERED_READINTO1_METHODDEF
2400 _IO__BUFFERED_READLINE_METHODDEF
2401 _IO__BUFFERED_SEEK_METHODDEF
2402 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2403 _IO__BUFFERED_TRUNCATE_METHODDEF
2404 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2405 {NULL, NULL}
2406};
2407
2408static PyMemberDef bufferedreader_members[] = {
2409 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2410 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2411 {NULL}
2412};
2413
2414static PyGetSetDef bufferedreader_getset[] = {
2415 {"closed", (getter)buffered_closed_get, NULL, NULL},
2416 {"name", (getter)buffered_name_get, NULL, NULL},
2417 {"mode", (getter)buffered_mode_get, NULL, NULL},
2418 {NULL}
2419};
2420
2421
2422PyTypeObject PyBufferedReader_Type = {
2423 PyVarObject_HEAD_INIT(NULL, 0)
2424 "_io.BufferedReader", /*tp_name*/
2425 sizeof(buffered), /*tp_basicsize*/
2426 0, /*tp_itemsize*/
2427 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002428 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002429 0, /*tp_getattr*/
2430 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002431 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002432 (reprfunc)buffered_repr, /*tp_repr*/
2433 0, /*tp_as_number*/
2434 0, /*tp_as_sequence*/
2435 0, /*tp_as_mapping*/
2436 0, /*tp_hash */
2437 0, /*tp_call*/
2438 0, /*tp_str*/
2439 0, /*tp_getattro*/
2440 0, /*tp_setattro*/
2441 0, /*tp_as_buffer*/
2442 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002443 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002444 _io_BufferedReader___init____doc__, /* tp_doc */
2445 (traverseproc)buffered_traverse, /* tp_traverse */
2446 (inquiry)buffered_clear, /* tp_clear */
2447 0, /* tp_richcompare */
2448 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2449 0, /* tp_iter */
2450 (iternextfunc)buffered_iternext, /* tp_iternext */
2451 bufferedreader_methods, /* tp_methods */
2452 bufferedreader_members, /* tp_members */
2453 bufferedreader_getset, /* tp_getset */
2454 0, /* tp_base */
2455 0, /* tp_dict */
2456 0, /* tp_descr_get */
2457 0, /* tp_descr_set */
2458 offsetof(buffered, dict), /* tp_dictoffset */
2459 _io_BufferedReader___init__, /* tp_init */
2460 0, /* tp_alloc */
2461 PyType_GenericNew, /* tp_new */
2462 0, /* tp_free */
2463 0, /* tp_is_gc */
2464 0, /* tp_bases */
2465 0, /* tp_mro */
2466 0, /* tp_cache */
2467 0, /* tp_subclasses */
2468 0, /* tp_weaklist */
2469 0, /* tp_del */
2470 0, /* tp_version_tag */
2471 0, /* tp_finalize */
2472};
2473
2474
2475static PyMethodDef bufferedwriter_methods[] = {
2476 /* BufferedIOMixin methods */
2477 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2478 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2479 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002480 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2481 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2482 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2483 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002484
2485 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2486 _IO__BUFFERED_TRUNCATE_METHODDEF
2487 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2488 _IO__BUFFERED_SEEK_METHODDEF
2489 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2490 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2491 {NULL, NULL}
2492};
2493
2494static PyMemberDef bufferedwriter_members[] = {
2495 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2496 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2497 {NULL}
2498};
2499
2500static PyGetSetDef bufferedwriter_getset[] = {
2501 {"closed", (getter)buffered_closed_get, NULL, NULL},
2502 {"name", (getter)buffered_name_get, NULL, NULL},
2503 {"mode", (getter)buffered_mode_get, NULL, NULL},
2504 {NULL}
2505};
2506
2507
2508PyTypeObject PyBufferedWriter_Type = {
2509 PyVarObject_HEAD_INIT(NULL, 0)
2510 "_io.BufferedWriter", /*tp_name*/
2511 sizeof(buffered), /*tp_basicsize*/
2512 0, /*tp_itemsize*/
2513 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002514 0, /*tp_vectorcall_offset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002515 0, /*tp_getattr*/
2516 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002517 0, /*tp_as_async*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002518 (reprfunc)buffered_repr, /*tp_repr*/
2519 0, /*tp_as_number*/
2520 0, /*tp_as_sequence*/
2521 0, /*tp_as_mapping*/
2522 0, /*tp_hash */
2523 0, /*tp_call*/
2524 0, /*tp_str*/
2525 0, /*tp_getattro*/
2526 0, /*tp_setattro*/
2527 0, /*tp_as_buffer*/
2528 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002529 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002530 _io_BufferedWriter___init____doc__, /* tp_doc */
2531 (traverseproc)buffered_traverse, /* tp_traverse */
2532 (inquiry)buffered_clear, /* tp_clear */
2533 0, /* tp_richcompare */
2534 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2535 0, /* tp_iter */
2536 0, /* tp_iternext */
2537 bufferedwriter_methods, /* tp_methods */
2538 bufferedwriter_members, /* tp_members */
2539 bufferedwriter_getset, /* tp_getset */
2540 0, /* tp_base */
2541 0, /* tp_dict */
2542 0, /* tp_descr_get */
2543 0, /* tp_descr_set */
2544 offsetof(buffered, dict), /* tp_dictoffset */
2545 _io_BufferedWriter___init__, /* tp_init */
2546 0, /* tp_alloc */
2547 PyType_GenericNew, /* tp_new */
2548 0, /* tp_free */
2549 0, /* tp_is_gc */
2550 0, /* tp_bases */
2551 0, /* tp_mro */
2552 0, /* tp_cache */
2553 0, /* tp_subclasses */
2554 0, /* tp_weaklist */
2555 0, /* tp_del */
2556 0, /* tp_version_tag */
2557 0, /* tp_finalize */
2558};
2559
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002561static PyMethodDef bufferedrwpair_methods[] = {
2562 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2563 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2564 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2565 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002566 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002567
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002568 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2569 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002570
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002571 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2572 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002573
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002574 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2575 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002576
2577 {NULL, NULL}
2578};
2579
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580static PyGetSetDef bufferedrwpair_getset[] = {
2581 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002582 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002583};
2584
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585PyTypeObject PyBufferedRWPair_Type = {
2586 PyVarObject_HEAD_INIT(NULL, 0)
2587 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002588 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002590 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002591 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002592 0, /*tp_getattr*/
2593 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002594 0, /*tp_as_async*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002595 0, /*tp_repr*/
2596 0, /*tp_as_number*/
2597 0, /*tp_as_sequence*/
2598 0, /*tp_as_mapping*/
2599 0, /*tp_hash */
2600 0, /*tp_call*/
2601 0, /*tp_str*/
2602 0, /*tp_getattro*/
2603 0, /*tp_setattro*/
2604 0, /*tp_as_buffer*/
2605 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002606 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002607 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002608 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2609 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002610 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002611 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002612 0, /* tp_iter */
2613 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002614 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002615 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002616 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002617 0, /* tp_base */
2618 0, /* tp_dict */
2619 0, /* tp_descr_get */
2620 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002621 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002622 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623 0, /* tp_alloc */
2624 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002625 0, /* tp_free */
2626 0, /* tp_is_gc */
2627 0, /* tp_bases */
2628 0, /* tp_mro */
2629 0, /* tp_cache */
2630 0, /* tp_subclasses */
2631 0, /* tp_weaklist */
2632 0, /* tp_del */
2633 0, /* tp_version_tag */
2634 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636
2637
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002638static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002639 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002640 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2641 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2642 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2643 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2644 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2645 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2646 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002647 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002648
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002649 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002651 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002652 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002653 _IO__BUFFERED_TRUNCATE_METHODDEF
2654 _IO__BUFFERED_READ_METHODDEF
2655 _IO__BUFFERED_READ1_METHODDEF
2656 _IO__BUFFERED_READINTO_METHODDEF
2657 _IO__BUFFERED_READINTO1_METHODDEF
2658 _IO__BUFFERED_READLINE_METHODDEF
2659 _IO__BUFFERED_PEEK_METHODDEF
2660 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002661 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002662 {NULL, NULL}
2663};
2664
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002665static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002666 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002667 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002668 {NULL}
2669};
2670
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002671static PyGetSetDef bufferedrandom_getset[] = {
2672 {"closed", (getter)buffered_closed_get, NULL, NULL},
2673 {"name", (getter)buffered_name_get, NULL, NULL},
2674 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002675 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002676};
2677
2678
2679PyTypeObject PyBufferedRandom_Type = {
2680 PyVarObject_HEAD_INIT(NULL, 0)
2681 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002682 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002683 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002684 (destructor)buffered_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002685 0, /*tp_vectorcall_offset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002686 0, /*tp_getattr*/
2687 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002688 0, /*tp_as_async*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002689 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690 0, /*tp_as_number*/
2691 0, /*tp_as_sequence*/
2692 0, /*tp_as_mapping*/
2693 0, /*tp_hash */
2694 0, /*tp_call*/
2695 0, /*tp_str*/
2696 0, /*tp_getattro*/
2697 0, /*tp_setattro*/
2698 0, /*tp_as_buffer*/
2699 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002700 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002701 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002702 (traverseproc)buffered_traverse, /* tp_traverse */
2703 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002704 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002705 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002706 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002707 (iternextfunc)buffered_iternext, /* tp_iternext */
2708 bufferedrandom_methods, /* tp_methods */
2709 bufferedrandom_members, /* tp_members */
2710 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002711 0, /* tp_base */
2712 0, /*tp_dict*/
2713 0, /* tp_descr_get */
2714 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002715 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002716 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002717 0, /* tp_alloc */
2718 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002719 0, /* tp_free */
2720 0, /* tp_is_gc */
2721 0, /* tp_bases */
2722 0, /* tp_mro */
2723 0, /* tp_cache */
2724 0, /* tp_subclasses */
2725 0, /* tp_weaklist */
2726 0, /* tp_del */
2727 0, /* tp_version_tag */
2728 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002729};