blob: 9c0eeb56860eea23b814a3d2ca9ac8accc7a4108 [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;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100442 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
443 source, NULL);
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)
464 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
465}
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)
516 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
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
524 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
525
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)
548 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
549 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)
565 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
566}
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)
572 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
573}
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)
579 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
580}
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)
602 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
603}
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)
609 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
610}
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;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
674 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)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200968
Antoine Pitrou3486a982011-05-12 01:57:53 +0200969 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
970 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300971 if (n >= buffer->len) {
972 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
973 self->pos += buffer->len;
974 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200975 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300976 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200977 self->pos += n;
978 written = n;
979 }
980
981 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300982 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200985 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986 if (res == NULL)
987 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000989 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200990
991 _bufferedreader_reset_buf(self);
992 self->pos = 0;
993
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300994 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995 remaining > 0;
996 written += n, remaining -= n) {
997 /* If remaining bytes is larger than internal buffer size, copy
998 * directly into caller's buffer. */
999 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001000 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001001 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001003
1004 /* In readinto1 mode, we do not want to fill the internal
1005 buffer if we already have some data to return */
1006 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001007 n = _bufferedreader_fill_buffer(self);
1008 if (n > 0) {
1009 if (n > remaining)
1010 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001011 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001012 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001013 self->pos += n;
1014 continue; /* short circuit */
1015 }
1016 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001017 else
1018 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001019
Antoine Pitrou3486a982011-05-12 01:57:53 +02001020 if (n == 0 || (n == -2 && written > 0))
1021 break;
1022 if (n < 0) {
1023 if (n == -2) {
1024 Py_INCREF(Py_None);
1025 res = Py_None;
1026 }
1027 goto end;
1028 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001029
Benjamin Petersona96fea02014-06-22 14:17:44 -07001030 /* At most one read in readinto1 mode */
1031 if (readinto1) {
1032 written += n;
1033 break;
1034 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001035 }
1036 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001037
1038end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001039 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001040 return res;
1041}
1042
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001043/*[clinic input]
1044_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001045 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001046 /
1047[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001048
1049static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001050_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001051/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001052{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001053 return _buffered_readinto_generic(self, buffer, 0);
1054}
1055
1056/*[clinic input]
1057_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001058 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001059 /
1060[clinic start generated code]*/
1061
1062static PyObject *
1063_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001064/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001065{
1066 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001067}
1068
1069
1070static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001071_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001072{
1073 PyObject *res = NULL;
1074 PyObject *chunks = NULL;
1075 Py_ssize_t n, written = 0;
1076 const char *start, *s, *end;
1077
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001078 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001080 /* First, try to find a line in the buffer. This can run unlocked because
1081 the calls to the C API are simple enough that they can't trigger
1082 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001083 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1084 if (limit >= 0 && n > limit)
1085 n = limit;
1086 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087 s = memchr(start, '\n', n);
1088 if (s != NULL) {
1089 res = PyBytes_FromStringAndSize(start, s - start + 1);
1090 if (res != NULL)
1091 self->pos += s - start + 1;
1092 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001093 }
1094 if (n == limit) {
1095 res = PyBytes_FromStringAndSize(start, n);
1096 if (res != NULL)
1097 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001098 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099 }
1100
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001101 if (!ENTER_BUFFERED(self))
1102 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001103
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001104 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105 chunks = PyList_New(0);
1106 if (chunks == NULL)
1107 goto end;
1108 if (n > 0) {
1109 res = PyBytes_FromStringAndSize(start, n);
1110 if (res == NULL)
1111 goto end;
1112 if (PyList_Append(chunks, res) < 0) {
1113 Py_CLEAR(res);
1114 goto end;
1115 }
1116 Py_CLEAR(res);
1117 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001118 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 if (limit >= 0)
1120 limit -= n;
1121 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001122 if (self->writable) {
1123 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1124 if (r == NULL)
1125 goto end;
1126 Py_DECREF(r);
1127 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128
1129 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001130 _bufferedreader_reset_buf(self);
1131 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132 if (n == -1)
1133 goto end;
1134 if (n <= 0)
1135 break;
1136 if (limit >= 0 && n > limit)
1137 n = limit;
1138 start = self->buffer;
1139 end = start + n;
1140 s = start;
1141 while (s < end) {
1142 if (*s++ == '\n') {
1143 res = PyBytes_FromStringAndSize(start, s - start);
1144 if (res == NULL)
1145 goto end;
1146 self->pos = s - start;
1147 goto found;
1148 }
1149 }
1150 res = PyBytes_FromStringAndSize(start, n);
1151 if (res == NULL)
1152 goto end;
1153 if (n == limit) {
1154 self->pos = n;
1155 break;
1156 }
1157 if (PyList_Append(chunks, res) < 0) {
1158 Py_CLEAR(res);
1159 goto end;
1160 }
1161 Py_CLEAR(res);
1162 written += n;
1163 if (limit >= 0)
1164 limit -= n;
1165 }
1166found:
1167 if (res != NULL && PyList_Append(chunks, res) < 0) {
1168 Py_CLEAR(res);
1169 goto end;
1170 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001171 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172
1173end:
1174 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001175end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176 Py_XDECREF(chunks);
1177 return res;
1178}
1179
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001180/*[clinic input]
1181_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001182 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001183 /
1184[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001186static PyObject *
1187_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001188/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001189{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001190 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001191 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192}
1193
1194
1195static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001196buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197{
1198 Py_off_t pos;
1199
1200 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001201 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202 if (pos == -1)
1203 return NULL;
1204 pos -= RAW_OFFSET(self);
1205 /* TODO: sanity check (pos >= 0) */
1206 return PyLong_FromOff_t(pos);
1207}
1208
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001209/*[clinic input]
1210_io._Buffered.seek
1211 target as targetobj: object
1212 whence: int = 0
1213 /
1214[clinic start generated code]*/
1215
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001216static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001217_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1218/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219{
1220 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001221 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222
1223 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001224
1225 /* Do some error checking instead of trusting OS 'seek()'
1226 ** error detection, just in case.
1227 */
1228 if ((whence < 0 || whence >2)
1229#ifdef SEEK_HOLE
1230 && (whence != SEEK_HOLE)
1231#endif
1232#ifdef SEEK_DATA
1233 && (whence != SEEK_DATA)
1234#endif
1235 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001237 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238 return NULL;
1239 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001240
1241 CHECK_CLOSED(self, "seek of closed file")
1242
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001243 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1244 return NULL;
1245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1247 if (target == -1 && PyErr_Occurred())
1248 return NULL;
1249
Jesus Cea94363612012-06-22 18:32:07 +02001250 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1251 buffer. Other whence values must be managed without this optimization.
1252 Some Operating Systems can provide additional values, like
1253 SEEK_HOLE/SEEK_DATA. */
1254 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001255 Py_off_t current, avail;
1256 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001257 so as to return quickly if possible. Also, we needn't take the
1258 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001259 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001260 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1261 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262 current = RAW_TELL(self);
1263 avail = READAHEAD(self);
1264 if (avail > 0) {
1265 Py_off_t offset;
1266 if (whence == 0)
1267 offset = target - (current - RAW_OFFSET(self));
1268 else
1269 offset = target;
1270 if (offset >= -self->pos && offset <= avail) {
1271 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001272 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 }
1274 }
1275 }
1276
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001277 if (!ENTER_BUFFERED(self))
1278 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001279
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001280 /* Fallback: invoke raw seek() method and clear buffer */
1281 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001282 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 if (res == NULL)
1284 goto end;
1285 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286 }
1287
1288 /* TODO: align on block boundary and read buffer if needed? */
1289 if (whence == 1)
1290 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001291 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 if (n == -1)
1293 goto end;
1294 self->raw_pos = -1;
1295 res = PyLong_FromOff_t(n);
1296 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001297 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001298
1299end:
1300 LEAVE_BUFFERED(self)
1301 return res;
1302}
1303
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001304/*[clinic input]
1305_io._Buffered.truncate
1306 pos: object = None
1307 /
1308[clinic start generated code]*/
1309
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001311_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1312/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 PyObject *res = NULL;
1315
1316 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001317 if (!ENTER_BUFFERED(self))
1318 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319
1320 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001321 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 if (res == NULL)
1323 goto end;
1324 Py_CLEAR(res);
1325 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001326 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1327 if (res == NULL)
1328 goto end;
1329 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001330 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331 PyErr_Clear();
1332
1333end:
1334 LEAVE_BUFFERED(self)
1335 return res;
1336}
1337
1338static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001339buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340{
1341 PyObject *line;
1342 PyTypeObject *tp;
1343
1344 CHECK_INITIALIZED(self);
1345
1346 tp = Py_TYPE(self);
1347 if (tp == &PyBufferedReader_Type ||
1348 tp == &PyBufferedRandom_Type) {
1349 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001350 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001351 }
1352 else {
1353 line = PyObject_CallMethodObjArgs((PyObject *)self,
1354 _PyIO_str_readline, NULL);
1355 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001356 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001357 "readline() should have returned a bytes object, "
1358 "not '%.200s'", Py_TYPE(line)->tp_name);
1359 Py_DECREF(line);
1360 return NULL;
1361 }
1362 }
1363
1364 if (line == NULL)
1365 return NULL;
1366
1367 if (PyBytes_GET_SIZE(line) == 0) {
1368 /* Reached EOF or would have blocked */
1369 Py_DECREF(line);
1370 return NULL;
1371 }
1372
1373 return line;
1374}
1375
Antoine Pitrou716c4442009-05-23 19:04:03 +00001376static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001377buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001378{
1379 PyObject *nameobj, *res;
1380
Martin v. Löwis767046a2011-10-14 15:35:36 +02001381 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001382 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001383 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001384 PyErr_Clear();
1385 else
1386 return NULL;
1387 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1388 }
1389 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001390 int status = Py_ReprEnter((PyObject *)self);
1391 res = NULL;
1392 if (status == 0) {
1393 res = PyUnicode_FromFormat("<%s name=%R>",
1394 Py_TYPE(self)->tp_name, nameobj);
1395 Py_ReprLeave((PyObject *)self);
1396 }
1397 else if (status > 0) {
1398 PyErr_Format(PyExc_RuntimeError,
1399 "reentrant call inside %s.__repr__",
1400 Py_TYPE(self)->tp_name);
1401 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001402 Py_DECREF(nameobj);
1403 }
1404 return res;
1405}
1406
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001407/*
1408 * class BufferedReader
1409 */
1410
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001411static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001412{
1413 self->read_end = -1;
1414}
1415
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001416/*[clinic input]
1417_io.BufferedReader.__init__
1418 raw: object
1419 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001420
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001421Create a new buffered reader using the given readable raw IO object.
1422[clinic start generated code]*/
1423
1424static int
1425_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1426 Py_ssize_t buffer_size)
1427/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1428{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001429 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001430 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001431
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001432 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001433 return -1;
1434
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001436 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437 self->buffer_size = buffer_size;
1438 self->readable = 1;
1439 self->writable = 0;
1440
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001441 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001442 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001443 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001444
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001445 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1446 Py_TYPE(raw) == &PyFileIO_Type);
1447
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448 self->ok = 1;
1449 return 0;
1450}
1451
1452static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001453_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454{
1455 Py_buffer buf;
1456 PyObject *memobj, *res;
1457 Py_ssize_t n;
1458 /* NOTE: the buffer needn't be released as its object is NULL. */
1459 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1460 return -1;
1461 memobj = PyMemoryView_FromBuffer(&buf);
1462 if (memobj == NULL)
1463 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001464 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1465 occurs so we needn't do it ourselves.
1466 We then retry reading, ignoring the signal if no handler has
1467 raised (see issue #10956).
1468 */
1469 do {
1470 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001471 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001472 Py_DECREF(memobj);
1473 if (res == NULL)
1474 return -1;
1475 if (res == Py_None) {
1476 /* Non-blocking stream would have blocked. Special return code! */
1477 Py_DECREF(res);
1478 return -2;
1479 }
1480 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1481 Py_DECREF(res);
1482 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001483 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484 "raw readinto() returned invalid length %zd "
1485 "(should have been between 0 and %zd)", n, len);
1486 return -1;
1487 }
1488 if (n > 0 && self->abs_pos != -1)
1489 self->abs_pos += n;
1490 return n;
1491}
1492
1493static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001494_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001495{
1496 Py_ssize_t start, len, n;
1497 if (VALID_READ_BUFFER(self))
1498 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1499 else
1500 start = 0;
1501 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001502 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001503 if (n <= 0)
1504 return n;
1505 self->read_end = start + n;
1506 self->raw_pos = start + n;
1507 return n;
1508}
1509
1510static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001511_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001512{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001513 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001514 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001515
1516 /* First copy what we have in the current buffer. */
1517 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1518 if (current_size) {
1519 data = PyBytes_FromStringAndSize(
1520 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001521 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001522 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001523 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001524 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001525 /* We're going past the buffer's bounds, flush it */
1526 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001527 tmp = buffered_flush_and_rewind_unlocked(self);
1528 if (tmp == NULL)
1529 goto cleanup;
1530 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001531 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001532 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001533
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001534 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1535 goto cleanup;
1536 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001537 if (readall) {
1538 tmp = _PyObject_CallNoArg(readall);
1539 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001540 if (tmp == NULL)
1541 goto cleanup;
1542 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001543 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001544 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001545 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001546 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001547 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001548 } else {
1549 if (tmp != Py_None) {
1550 PyBytes_Concat(&data, tmp);
1551 }
1552 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001553 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001554 goto cleanup;
1555 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001556
1557 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001558 if (chunks == NULL)
1559 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001560
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001561 while (1) {
1562 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001563 if (PyList_Append(chunks, data) < 0)
1564 goto cleanup;
1565 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001566 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001567
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001568 /* Read until EOF or until read() would block. */
1569 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001570 if (data == NULL)
1571 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001573 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001574 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001575 }
1576 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1577 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001578 res = data;
1579 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001580 }
1581 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001582 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1583 res = tmp;
1584 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001585 }
1586 }
1587 current_size += PyBytes_GET_SIZE(data);
1588 if (self->abs_pos != -1)
1589 self->abs_pos += PyBytes_GET_SIZE(data);
1590 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001591cleanup:
1592 /* res is either NULL or a borrowed ref */
1593 Py_XINCREF(res);
1594 Py_XDECREF(data);
1595 Py_XDECREF(tmp);
1596 Py_XDECREF(chunks);
1597 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001598}
1599
1600/* Read n bytes from the buffer if it can, otherwise return None.
1601 This function is simple enough that it can run unlocked. */
1602static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001603_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001604{
1605 Py_ssize_t current_size;
1606
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001607 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1608 if (n <= current_size) {
1609 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001610 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1611 if (res != NULL)
1612 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001613 return res;
1614 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001615 Py_RETURN_NONE;
1616}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001617
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001618/* Generic read function: read from the stream until enough bytes are read,
1619 * or until an EOF occurs or until read() would block.
1620 */
1621static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001622_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001623{
1624 PyObject *res = NULL;
1625 Py_ssize_t current_size, remaining, written;
1626 char *out;
1627
1628 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1629 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001630 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001631
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001632 res = PyBytes_FromStringAndSize(NULL, n);
1633 if (res == NULL)
1634 goto error;
1635 out = PyBytes_AS_STRING(res);
1636 remaining = n;
1637 written = 0;
1638 if (current_size > 0) {
1639 memcpy(out, self->buffer + self->pos, current_size);
1640 remaining -= current_size;
1641 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001642 self->pos += current_size;
1643 }
1644 /* Flush the write buffer if necessary */
1645 if (self->writable) {
1646 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1647 if (r == NULL)
1648 goto error;
1649 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001650 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001651 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001652 while (remaining > 0) {
1653 /* We want to read a whole block at the end into buffer.
1654 If we had readv() we could do this in one pass. */
1655 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1656 if (r == 0)
1657 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001658 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001659 if (r == -1)
1660 goto error;
1661 if (r == 0 || r == -2) {
1662 /* EOF occurred or read() would block. */
1663 if (r == 0 || written > 0) {
1664 if (_PyBytes_Resize(&res, written))
1665 goto error;
1666 return res;
1667 }
1668 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001669 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001670 }
1671 remaining -= r;
1672 written += r;
1673 }
1674 assert(remaining <= self->buffer_size);
1675 self->pos = 0;
1676 self->raw_pos = 0;
1677 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001678 /* NOTE: when the read is satisfied, we avoid issuing any additional
1679 reads, which could block indefinitely (e.g. on a socket).
1680 See issue #9550. */
1681 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001682 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683 if (r == -1)
1684 goto error;
1685 if (r == 0 || r == -2) {
1686 /* EOF occurred or read() would block. */
1687 if (r == 0 || written > 0) {
1688 if (_PyBytes_Resize(&res, written))
1689 goto error;
1690 return res;
1691 }
1692 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001693 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001694 }
1695 if (remaining > r) {
1696 memcpy(out + written, self->buffer + self->pos, r);
1697 written += r;
1698 self->pos += r;
1699 remaining -= r;
1700 }
1701 else if (remaining > 0) {
1702 memcpy(out + written, self->buffer + self->pos, remaining);
1703 written += remaining;
1704 self->pos += remaining;
1705 remaining = 0;
1706 }
1707 if (remaining == 0)
1708 break;
1709 }
1710
1711 return res;
1712
1713error:
1714 Py_XDECREF(res);
1715 return NULL;
1716}
1717
1718static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001719_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001720{
1721 Py_ssize_t have, r;
1722
1723 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1724 /* Constraints:
1725 1. we don't want to advance the file position.
1726 2. we don't want to lose block alignment, so we can't shift the buffer
1727 to make some place.
1728 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1729 */
1730 if (have > 0) {
1731 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1732 }
1733
1734 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001735 _bufferedreader_reset_buf(self);
1736 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 if (r == -1)
1738 return NULL;
1739 if (r == -2)
1740 r = 0;
1741 self->pos = 0;
1742 return PyBytes_FromStringAndSize(self->buffer, r);
1743}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001744
1745
Benjamin Peterson59406a92009-03-26 17:10:29 +00001746
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001747/*
1748 * class BufferedWriter
1749 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001751_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001752{
1753 self->write_pos = 0;
1754 self->write_end = -1;
1755}
1756
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001757/*[clinic input]
1758_io.BufferedWriter.__init__
1759 raw: object
1760 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001762A buffer for a writeable sequential RawIO object.
1763
1764The constructor creates a BufferedWriter for the given writeable raw
1765stream. If the buffer_size is not given, it defaults to
1766DEFAULT_BUFFER_SIZE.
1767[clinic start generated code]*/
1768
1769static int
1770_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1771 Py_ssize_t buffer_size)
1772/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1773{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001775 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001777 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 return -1;
1779
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001781 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001782 self->readable = 0;
1783 self->writable = 1;
1784
1785 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001786 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001788 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789 self->pos = 0;
1790
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001791 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1792 Py_TYPE(raw) == &PyFileIO_Type);
1793
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794 self->ok = 1;
1795 return 0;
1796}
1797
1798static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800{
1801 Py_buffer buf;
1802 PyObject *memobj, *res;
1803 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001804 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 /* NOTE: the buffer needn't be released as its object is NULL. */
1806 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1807 return -1;
1808 memobj = PyMemoryView_FromBuffer(&buf);
1809 if (memobj == NULL)
1810 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001811 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1812 occurs so we needn't do it ourselves.
1813 We then retry writing, ignoring the signal if no handler has
1814 raised (see issue #10956).
1815 */
1816 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001817 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001818 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001819 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001820 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001821 Py_DECREF(memobj);
1822 if (res == NULL)
1823 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001824 if (res == Py_None) {
1825 /* Non-blocking stream would have blocked. Special return code!
1826 Being paranoid we reset errno in case it is changed by code
1827 triggered by a decref. errno is used by _set_BlockingIOError(). */
1828 Py_DECREF(res);
1829 errno = errnum;
1830 return -2;
1831 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001832 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1833 Py_DECREF(res);
1834 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001835 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 "raw write() returned invalid length %zd "
1837 "(should have been between 0 and %zd)", n, len);
1838 return -1;
1839 }
1840 if (n > 0 && self->abs_pos != -1)
1841 self->abs_pos += n;
1842 return n;
1843}
1844
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001845static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001846_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847{
1848 Py_ssize_t written = 0;
1849 Py_off_t n, rewind;
1850
1851 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1852 goto end;
1853 /* First, rewind */
1854 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1855 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001856 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001857 if (n < 0) {
1858 goto error;
1859 }
1860 self->raw_pos -= rewind;
1861 }
1862 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001863 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864 self->buffer + self->write_pos,
1865 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1866 Py_off_t, Py_ssize_t));
1867 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001868 goto error;
1869 }
1870 else if (n == -2) {
1871 _set_BlockingIOError("write could not complete without blocking",
1872 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001873 goto error;
1874 }
1875 self->write_pos += n;
1876 self->raw_pos = self->write_pos;
1877 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001878 /* Partial writes can return successfully when interrupted by a
1879 signal (see write(2)). We must run signal handlers before
1880 blocking another time, possibly indefinitely. */
1881 if (PyErr_CheckSignals() < 0)
1882 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001883 }
1884
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885
1886end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301887 /* This ensures that after return from this function,
1888 VALID_WRITE_BUFFER(self) returns false.
1889
1890 This is a required condition because when a tell() is called
1891 after flushing and if VALID_READ_BUFFER(self) is false, we need
1892 VALID_WRITE_BUFFER(self) to be false to have
1893 RAW_OFFSET(self) == 0.
1894
1895 Issue: https://bugs.python.org/issue32228 */
1896 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001897 Py_RETURN_NONE;
1898
1899error:
1900 return NULL;
1901}
1902
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001903/*[clinic input]
1904_io.BufferedWriter.write
1905 buffer: Py_buffer
1906 /
1907[clinic start generated code]*/
1908
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001909static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001910_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1911/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912{
1913 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001914 Py_ssize_t written, avail, remaining;
1915 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916
1917 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001919 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001920 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921
benfogle9703f092017-11-10 16:03:40 -05001922 /* Issue #31976: Check for closed file after acquiring the lock. Another
1923 thread could be holding the lock while closing the file. */
1924 if (IS_CLOSED(self)) {
1925 PyErr_SetString(PyExc_ValueError, "write to closed file");
1926 goto error;
1927 }
1928
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929 /* Fast path: the data to write can be fully buffered. */
1930 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1931 self->pos = 0;
1932 self->raw_pos = 0;
1933 }
1934 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001935 if (buffer->len <= avail) {
1936 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001937 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938 self->write_pos = self->pos;
1939 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001940 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941 if (self->pos > self->write_end)
1942 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001943 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 goto end;
1945 }
1946
1947 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001948 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001950 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951 if (w == NULL)
1952 goto error;
1953 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001954 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955 /* Make some place by shifting the buffer. */
1956 assert(VALID_WRITE_BUFFER(self));
1957 memmove(self->buffer, self->buffer + self->write_pos,
1958 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1959 Py_off_t, Py_ssize_t));
1960 self->write_end -= self->write_pos;
1961 self->raw_pos -= self->write_pos;
1962 self->pos -= self->write_pos;
1963 self->write_pos = 0;
1964 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1965 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001966 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 /* Everything can be buffered */
1968 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001969 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1970 self->write_end += buffer->len;
1971 self->pos += buffer->len;
1972 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973 goto end;
1974 }
1975 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001976 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001977 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001978 self->pos += avail;
1979 /* XXX Modifying the existing exception e using the pointer w
1980 will change e.characters_written but not e.args[2].
1981 Therefore we just replace with a new error. */
1982 _set_BlockingIOError("write could not complete without blocking",
1983 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001984 goto error;
1985 }
1986 Py_CLEAR(res);
1987
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001988 /* Adjust the raw stream position if it is away from the logical stream
1989 position. This happens if the read buffer has been filled but not
1990 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1991 the raw stream by itself).
1992 Fixes issue #6629.
1993 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001994 offset = RAW_OFFSET(self);
1995 if (offset != 0) {
1996 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001997 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001998 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001999 }
2000
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002002 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003 written = 0;
2004 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002005 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002006 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002008 goto error;
2009 } else if (n == -2) {
2010 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002011 if (remaining > self->buffer_size) {
2012 /* Can't buffer everything, still buffer as much as possible */
2013 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002014 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 self->raw_pos = 0;
2016 ADJUST_POSITION(self, self->buffer_size);
2017 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002018 written += self->buffer_size;
2019 _set_BlockingIOError("write could not complete without "
2020 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002021 goto error;
2022 }
2023 PyErr_Clear();
2024 break;
2025 }
2026 written += n;
2027 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002028 /* Partial writes can return successfully when interrupted by a
2029 signal (see write(2)). We must run signal handlers before
2030 blocking another time, possibly indefinitely. */
2031 if (PyErr_CheckSignals() < 0)
2032 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033 }
2034 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002035 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002036 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002037 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002038 written += remaining;
2039 }
2040 self->write_pos = 0;
2041 /* TODO: sanity check (remaining >= 0) */
2042 self->write_end = remaining;
2043 ADJUST_POSITION(self, remaining);
2044 self->raw_pos = 0;
2045
2046end:
2047 res = PyLong_FromSsize_t(written);
2048
2049error:
2050 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051 return res;
2052}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002053
2054
2055
2056/*
2057 * BufferedRWPair
2058 */
2059
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060/* XXX The usefulness of this (compared to having two separate IO objects) is
2061 * questionable.
2062 */
2063
2064typedef struct {
2065 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002066 buffered *reader;
2067 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068 PyObject *dict;
2069 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002070} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002072/*[clinic input]
2073_io.BufferedRWPair.__init__
2074 reader: object
2075 writer: object
2076 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2077 /
2078
2079A buffered reader and writer object together.
2080
2081A buffered reader object and buffered writer object put together to
2082form a sequential IO object that can read and write. This is typically
2083used with a socket or two-way pipe.
2084
2085reader and writer are RawIOBase objects that are readable and
2086writeable respectively. If the buffer_size is omitted it defaults to
2087DEFAULT_BUFFER_SIZE.
2088[clinic start generated code]*/
2089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002090static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002091_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2092 PyObject *writer, Py_ssize_t buffer_size)
2093/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002094{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002095 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002097 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098 return -1;
2099
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002101 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002102 if (self->reader == NULL)
2103 return -1;
2104
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002106 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002107 if (self->writer == NULL) {
2108 Py_CLEAR(self->reader);
2109 return -1;
2110 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002111
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002112 return 0;
2113}
2114
2115static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002116bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002117{
2118 Py_VISIT(self->dict);
2119 return 0;
2120}
2121
2122static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124{
2125 Py_CLEAR(self->reader);
2126 Py_CLEAR(self->writer);
2127 Py_CLEAR(self->dict);
2128 return 0;
2129}
2130
2131static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002132bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133{
2134 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002135 if (self->weakreflist != NULL)
2136 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002137 Py_CLEAR(self->reader);
2138 Py_CLEAR(self->writer);
2139 Py_CLEAR(self->dict);
2140 Py_TYPE(self)->tp_free((PyObject *) self);
2141}
2142
2143static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002144_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002145{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002146 PyObject *func, *ret;
2147 if (self == NULL) {
2148 PyErr_SetString(PyExc_ValueError,
2149 "I/O operation on uninitialized object");
2150 return NULL;
2151 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002153 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002155 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 return NULL;
2157 }
2158
2159 ret = PyObject_CallObject(func, args);
2160 Py_DECREF(func);
2161 return ret;
2162}
2163
2164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002167 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168}
2169
2170static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002171bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002173 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002174}
2175
2176static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002177bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002179 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180}
2181
2182static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002183bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002184{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002185 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002186}
2187
2188static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002189bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2190{
2191 return _forward_call(self->reader, &PyId_readinto1, args);
2192}
2193
2194static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002195bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002196{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002197 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002198}
2199
2200static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002201bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202{
jdemeyerfc512e32018-08-02 13:14:54 +02002203 return _forward_call(self->writer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002204}
2205
2206static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002207bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208{
jdemeyerfc512e32018-08-02 13:14:54 +02002209 return _forward_call(self->reader, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210}
2211
2212static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002213bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214{
jdemeyerfc512e32018-08-02 13:14:54 +02002215 return _forward_call(self->writer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216}
2217
2218static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002219bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002221 PyObject *exc = NULL, *val, *tb;
jdemeyerfc512e32018-08-02 13:14:54 +02002222 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002224 PyErr_Fetch(&exc, &val, &tb);
2225 else
2226 Py_DECREF(ret);
jdemeyerfc512e32018-08-02 13:14:54 +02002227 ret = _forward_call(self->reader, &PyId_close, NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002228 if (exc != NULL) {
2229 _PyErr_ChainExceptions(exc, val, tb);
2230 Py_CLEAR(ret);
2231 }
2232 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233}
2234
2235static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002236bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237{
jdemeyerfc512e32018-08-02 13:14:54 +02002238 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239
2240 if (ret != Py_False) {
2241 /* either True or exception */
2242 return ret;
2243 }
2244 Py_DECREF(ret);
2245
jdemeyerfc512e32018-08-02 13:14:54 +02002246 return _forward_call(self->reader, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002247}
2248
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002249static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002251{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002252 if (self->writer == NULL) {
2253 PyErr_SetString(PyExc_RuntimeError,
2254 "the BufferedRWPair object is being garbage-collected");
2255 return NULL;
2256 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002257 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2258}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002259
2260
2261
2262/*
2263 * BufferedRandom
2264 */
2265
2266/*[clinic input]
2267_io.BufferedRandom.__init__
2268 raw: object
2269 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2270
2271A buffered interface to random access streams.
2272
2273The constructor creates a reader and writer for a seekable stream,
2274raw, given in the first argument. If the buffer_size is omitted it
2275defaults to DEFAULT_BUFFER_SIZE.
2276[clinic start generated code]*/
2277
2278static int
2279_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2280 Py_ssize_t buffer_size)
2281/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2282{
2283 self->ok = 0;
2284 self->detached = 0;
2285
2286 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2287 return -1;
2288 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2289 return -1;
2290 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2291 return -1;
2292
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002293 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002294 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002295 self->buffer_size = buffer_size;
2296 self->readable = 1;
2297 self->writable = 1;
2298
2299 if (_buffered_init(self) < 0)
2300 return -1;
2301 _bufferedreader_reset_buf(self);
2302 _bufferedwriter_reset_buf(self);
2303 self->pos = 0;
2304
2305 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2306 Py_TYPE(raw) == &PyFileIO_Type);
2307
2308 self->ok = 1;
2309 return 0;
2310}
2311
2312#include "clinic/bufferedio.c.h"
2313
2314
2315static PyMethodDef bufferediobase_methods[] = {
2316 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2317 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2318 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2319 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2320 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2321 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2322 {NULL, NULL}
2323};
2324
2325PyTypeObject PyBufferedIOBase_Type = {
2326 PyVarObject_HEAD_INIT(NULL, 0)
2327 "_io._BufferedIOBase", /*tp_name*/
2328 0, /*tp_basicsize*/
2329 0, /*tp_itemsize*/
2330 0, /*tp_dealloc*/
2331 0, /*tp_print*/
2332 0, /*tp_getattr*/
2333 0, /*tp_setattr*/
2334 0, /*tp_compare */
2335 0, /*tp_repr*/
2336 0, /*tp_as_number*/
2337 0, /*tp_as_sequence*/
2338 0, /*tp_as_mapping*/
2339 0, /*tp_hash */
2340 0, /*tp_call*/
2341 0, /*tp_str*/
2342 0, /*tp_getattro*/
2343 0, /*tp_setattro*/
2344 0, /*tp_as_buffer*/
Antoine Pitrouada319b2019-05-29 22:12:38 +02002345 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002346 bufferediobase_doc, /* tp_doc */
2347 0, /* tp_traverse */
2348 0, /* tp_clear */
2349 0, /* tp_richcompare */
2350 0, /* tp_weaklistoffset */
2351 0, /* tp_iter */
2352 0, /* tp_iternext */
2353 bufferediobase_methods, /* tp_methods */
2354 0, /* tp_members */
2355 0, /* tp_getset */
2356 &PyIOBase_Type, /* tp_base */
2357 0, /* tp_dict */
2358 0, /* tp_descr_get */
2359 0, /* tp_descr_set */
2360 0, /* tp_dictoffset */
2361 0, /* tp_init */
2362 0, /* tp_alloc */
2363 0, /* tp_new */
2364 0, /* tp_free */
2365 0, /* tp_is_gc */
2366 0, /* tp_bases */
2367 0, /* tp_mro */
2368 0, /* tp_cache */
2369 0, /* tp_subclasses */
2370 0, /* tp_weaklist */
2371 0, /* tp_del */
2372 0, /* tp_version_tag */
2373 0, /* tp_finalize */
2374};
2375
2376
2377static PyMethodDef bufferedreader_methods[] = {
2378 /* BufferedIOMixin methods */
2379 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2380 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2381 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2382 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2383 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002384 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2385 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2386 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002387
2388 _IO__BUFFERED_READ_METHODDEF
2389 _IO__BUFFERED_PEEK_METHODDEF
2390 _IO__BUFFERED_READ1_METHODDEF
2391 _IO__BUFFERED_READINTO_METHODDEF
2392 _IO__BUFFERED_READINTO1_METHODDEF
2393 _IO__BUFFERED_READLINE_METHODDEF
2394 _IO__BUFFERED_SEEK_METHODDEF
2395 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2396 _IO__BUFFERED_TRUNCATE_METHODDEF
2397 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2398 {NULL, NULL}
2399};
2400
2401static PyMemberDef bufferedreader_members[] = {
2402 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2403 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2404 {NULL}
2405};
2406
2407static PyGetSetDef bufferedreader_getset[] = {
2408 {"closed", (getter)buffered_closed_get, NULL, NULL},
2409 {"name", (getter)buffered_name_get, NULL, NULL},
2410 {"mode", (getter)buffered_mode_get, NULL, NULL},
2411 {NULL}
2412};
2413
2414
2415PyTypeObject PyBufferedReader_Type = {
2416 PyVarObject_HEAD_INIT(NULL, 0)
2417 "_io.BufferedReader", /*tp_name*/
2418 sizeof(buffered), /*tp_basicsize*/
2419 0, /*tp_itemsize*/
2420 (destructor)buffered_dealloc, /*tp_dealloc*/
2421 0, /*tp_print*/
2422 0, /*tp_getattr*/
2423 0, /*tp_setattr*/
2424 0, /*tp_compare */
2425 (reprfunc)buffered_repr, /*tp_repr*/
2426 0, /*tp_as_number*/
2427 0, /*tp_as_sequence*/
2428 0, /*tp_as_mapping*/
2429 0, /*tp_hash */
2430 0, /*tp_call*/
2431 0, /*tp_str*/
2432 0, /*tp_getattro*/
2433 0, /*tp_setattro*/
2434 0, /*tp_as_buffer*/
2435 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002436 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002437 _io_BufferedReader___init____doc__, /* tp_doc */
2438 (traverseproc)buffered_traverse, /* tp_traverse */
2439 (inquiry)buffered_clear, /* tp_clear */
2440 0, /* tp_richcompare */
2441 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2442 0, /* tp_iter */
2443 (iternextfunc)buffered_iternext, /* tp_iternext */
2444 bufferedreader_methods, /* tp_methods */
2445 bufferedreader_members, /* tp_members */
2446 bufferedreader_getset, /* tp_getset */
2447 0, /* tp_base */
2448 0, /* tp_dict */
2449 0, /* tp_descr_get */
2450 0, /* tp_descr_set */
2451 offsetof(buffered, dict), /* tp_dictoffset */
2452 _io_BufferedReader___init__, /* tp_init */
2453 0, /* tp_alloc */
2454 PyType_GenericNew, /* tp_new */
2455 0, /* tp_free */
2456 0, /* tp_is_gc */
2457 0, /* tp_bases */
2458 0, /* tp_mro */
2459 0, /* tp_cache */
2460 0, /* tp_subclasses */
2461 0, /* tp_weaklist */
2462 0, /* tp_del */
2463 0, /* tp_version_tag */
2464 0, /* tp_finalize */
2465};
2466
2467
2468static PyMethodDef bufferedwriter_methods[] = {
2469 /* BufferedIOMixin methods */
2470 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2471 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2472 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002473 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2474 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2475 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2476 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002477
2478 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2479 _IO__BUFFERED_TRUNCATE_METHODDEF
2480 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2481 _IO__BUFFERED_SEEK_METHODDEF
2482 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2483 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2484 {NULL, NULL}
2485};
2486
2487static PyMemberDef bufferedwriter_members[] = {
2488 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2489 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2490 {NULL}
2491};
2492
2493static PyGetSetDef bufferedwriter_getset[] = {
2494 {"closed", (getter)buffered_closed_get, NULL, NULL},
2495 {"name", (getter)buffered_name_get, NULL, NULL},
2496 {"mode", (getter)buffered_mode_get, NULL, NULL},
2497 {NULL}
2498};
2499
2500
2501PyTypeObject PyBufferedWriter_Type = {
2502 PyVarObject_HEAD_INIT(NULL, 0)
2503 "_io.BufferedWriter", /*tp_name*/
2504 sizeof(buffered), /*tp_basicsize*/
2505 0, /*tp_itemsize*/
2506 (destructor)buffered_dealloc, /*tp_dealloc*/
2507 0, /*tp_print*/
2508 0, /*tp_getattr*/
2509 0, /*tp_setattr*/
2510 0, /*tp_compare */
2511 (reprfunc)buffered_repr, /*tp_repr*/
2512 0, /*tp_as_number*/
2513 0, /*tp_as_sequence*/
2514 0, /*tp_as_mapping*/
2515 0, /*tp_hash */
2516 0, /*tp_call*/
2517 0, /*tp_str*/
2518 0, /*tp_getattro*/
2519 0, /*tp_setattro*/
2520 0, /*tp_as_buffer*/
2521 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002522 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002523 _io_BufferedWriter___init____doc__, /* tp_doc */
2524 (traverseproc)buffered_traverse, /* tp_traverse */
2525 (inquiry)buffered_clear, /* tp_clear */
2526 0, /* tp_richcompare */
2527 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2528 0, /* tp_iter */
2529 0, /* tp_iternext */
2530 bufferedwriter_methods, /* tp_methods */
2531 bufferedwriter_members, /* tp_members */
2532 bufferedwriter_getset, /* tp_getset */
2533 0, /* tp_base */
2534 0, /* tp_dict */
2535 0, /* tp_descr_get */
2536 0, /* tp_descr_set */
2537 offsetof(buffered, dict), /* tp_dictoffset */
2538 _io_BufferedWriter___init__, /* tp_init */
2539 0, /* tp_alloc */
2540 PyType_GenericNew, /* tp_new */
2541 0, /* tp_free */
2542 0, /* tp_is_gc */
2543 0, /* tp_bases */
2544 0, /* tp_mro */
2545 0, /* tp_cache */
2546 0, /* tp_subclasses */
2547 0, /* tp_weaklist */
2548 0, /* tp_del */
2549 0, /* tp_version_tag */
2550 0, /* tp_finalize */
2551};
2552
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002553
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002554static PyMethodDef bufferedrwpair_methods[] = {
2555 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2556 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2557 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2558 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002559 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002561 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2562 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002563
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002564 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2565 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2568 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569
2570 {NULL, NULL}
2571};
2572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573static PyGetSetDef bufferedrwpair_getset[] = {
2574 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002575 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002576};
2577
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002578PyTypeObject PyBufferedRWPair_Type = {
2579 PyVarObject_HEAD_INIT(NULL, 0)
2580 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002581 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002583 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002584 0, /*tp_print*/
2585 0, /*tp_getattr*/
2586 0, /*tp_setattr*/
2587 0, /*tp_compare */
2588 0, /*tp_repr*/
2589 0, /*tp_as_number*/
2590 0, /*tp_as_sequence*/
2591 0, /*tp_as_mapping*/
2592 0, /*tp_hash */
2593 0, /*tp_call*/
2594 0, /*tp_str*/
2595 0, /*tp_getattro*/
2596 0, /*tp_setattro*/
2597 0, /*tp_as_buffer*/
2598 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002599 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002600 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2602 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002603 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002604 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002605 0, /* tp_iter */
2606 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002607 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002608 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002609 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002610 0, /* tp_base */
2611 0, /* tp_dict */
2612 0, /* tp_descr_get */
2613 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002614 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002615 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616 0, /* tp_alloc */
2617 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002618 0, /* tp_free */
2619 0, /* tp_is_gc */
2620 0, /* tp_bases */
2621 0, /* tp_mro */
2622 0, /* tp_cache */
2623 0, /* tp_subclasses */
2624 0, /* tp_weaklist */
2625 0, /* tp_del */
2626 0, /* tp_version_tag */
2627 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002628};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629
2630
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002631static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002632 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002633 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2634 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2635 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2636 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2637 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2638 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2639 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002640 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002641
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002642 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002643
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002644 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002645 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002646 _IO__BUFFERED_TRUNCATE_METHODDEF
2647 _IO__BUFFERED_READ_METHODDEF
2648 _IO__BUFFERED_READ1_METHODDEF
2649 _IO__BUFFERED_READINTO_METHODDEF
2650 _IO__BUFFERED_READINTO1_METHODDEF
2651 _IO__BUFFERED_READLINE_METHODDEF
2652 _IO__BUFFERED_PEEK_METHODDEF
2653 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002654 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002655 {NULL, NULL}
2656};
2657
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002658static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002659 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002660 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002661 {NULL}
2662};
2663
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002664static PyGetSetDef bufferedrandom_getset[] = {
2665 {"closed", (getter)buffered_closed_get, NULL, NULL},
2666 {"name", (getter)buffered_name_get, NULL, NULL},
2667 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002668 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002669};
2670
2671
2672PyTypeObject PyBufferedRandom_Type = {
2673 PyVarObject_HEAD_INIT(NULL, 0)
2674 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002675 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002676 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002677 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002678 0, /*tp_print*/
2679 0, /*tp_getattr*/
2680 0, /*tp_setattr*/
2681 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002682 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002683 0, /*tp_as_number*/
2684 0, /*tp_as_sequence*/
2685 0, /*tp_as_mapping*/
2686 0, /*tp_hash */
2687 0, /*tp_call*/
2688 0, /*tp_str*/
2689 0, /*tp_getattro*/
2690 0, /*tp_setattro*/
2691 0, /*tp_as_buffer*/
2692 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrouada319b2019-05-29 22:12:38 +02002693 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002694 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002695 (traverseproc)buffered_traverse, /* tp_traverse */
2696 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002697 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002698 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002699 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002700 (iternextfunc)buffered_iternext, /* tp_iternext */
2701 bufferedrandom_methods, /* tp_methods */
2702 bufferedrandom_members, /* tp_members */
2703 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002704 0, /* tp_base */
2705 0, /*tp_dict*/
2706 0, /* tp_descr_get */
2707 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002708 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002709 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002710 0, /* tp_alloc */
2711 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002712 0, /* tp_free */
2713 0, /* tp_is_gc */
2714 0, /* tp_bases */
2715 0, /* tp_mro */
2716 0, /* tp_cache */
2717 0, /* tp_subclasses */
2718 0, /* tp_weaklist */
2719 0, /* tp_del */
2720 0, /* tp_version_tag */
2721 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002722};