blob: e1e45dc8fae08e5a0939cea733341467149bce84 [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 Stinner621cebe2018-11-12 16:53:38 +010012#include "pycore_pystate.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000013#include "structmember.h"
14#include "pythread.h"
15#include "_iomodule.h"
16
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030017/*[clinic input]
18module _io
19class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
20class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
21class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
22class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
23class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
24class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
25[clinic start generated code]*/
26/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
27
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020028_Py_IDENTIFIER(close);
29_Py_IDENTIFIER(_dealloc_warn);
30_Py_IDENTIFIER(flush);
31_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020032_Py_IDENTIFIER(mode);
33_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020034_Py_IDENTIFIER(peek);
35_Py_IDENTIFIER(read);
36_Py_IDENTIFIER(read1);
37_Py_IDENTIFIER(readable);
38_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070039_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020040_Py_IDENTIFIER(writable);
41_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020042
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000043/*
44 * BufferedIOBase class, inherits from IOBase.
45 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000046PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000047 "Base class for buffered IO objects.\n"
48 "\n"
49 "The main difference with RawIOBase is that the read() method\n"
50 "supports omitting the size argument, and does not have a default\n"
51 "implementation that defers to readinto().\n"
52 "\n"
53 "In addition, read(), readinto() and write() may raise\n"
54 "BlockingIOError if the underlying raw stream is in non-blocking\n"
55 "mode and not ready; unlike their raw counterparts, they will never\n"
56 "return None.\n"
57 "\n"
58 "A typical implementation should not inherit from a RawIOBase\n"
59 "implementation, but wrap one.\n"
60 );
61
62static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030063_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000065 Py_ssize_t len;
66 PyObject *data;
67
Benjamin Petersona96fea02014-06-22 14:17:44 -070068 data = _PyObject_CallMethodId(self,
69 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030070 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030072 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000073
74 if (!PyBytes_Check(data)) {
75 Py_DECREF(data);
76 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030077 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000078 }
79
Serhiy Storchakafff9a312017-03-21 08:53:25 +020080 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030081 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030082 PyErr_Format(PyExc_ValueError,
83 "read() returned too much data: "
84 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030085 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030086 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030087 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030088 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030089 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000091 Py_DECREF(data);
92
93 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094}
95
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030096/*[clinic input]
97_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070098 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030099 /
100[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700101
102static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300103_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700104/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700105{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300106 return _bufferediobase_readinto_generic(self, buffer, 0);
107}
108
109/*[clinic input]
110_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700111 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300112 /
113[clinic start generated code]*/
114
115static PyObject *
116_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700117/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300118{
119 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700120}
121
122static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000123bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000124{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100125 _PyIO_State *state = IO_STATE();
126 if (state != NULL)
127 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000128 return NULL;
129}
130
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300131/*[clinic input]
132_io._BufferedIOBase.detach
133
134Disconnect this buffer from its underlying raw stream and return it.
135
136After the raw stream has been detached, the buffer is in an unusable
137state.
138[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000139
140static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300141_io__BufferedIOBase_detach_impl(PyObject *self)
142/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000143{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000145}
146
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000147PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000148 "Read and return up to n bytes.\n"
149 "\n"
150 "If the argument is omitted, None, or negative, reads and\n"
151 "returns all data until EOF.\n"
152 "\n"
153 "If the argument is positive, and the underlying raw stream is\n"
154 "not 'interactive', multiple raw reads may be issued to satisfy\n"
155 "the byte count (unless EOF is reached first). But for\n"
156 "interactive raw streams (as well as sockets and pipes), at most\n"
157 "one raw read will be issued, and a short result does not imply\n"
158 "that EOF is imminent.\n"
159 "\n"
160 "Returns an empty bytes object on EOF.\n"
161 "\n"
162 "Returns None if the underlying raw stream was open in non-blocking\n"
163 "mode and no data is available at the moment.\n");
164
165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000166bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000167{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000168 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000169}
170
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000171PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000172 "Read and return up to n bytes, with at most one read() call\n"
173 "to the underlying raw stream. A short result does not imply\n"
174 "that EOF is imminent.\n"
175 "\n"
176 "Returns an empty bytes object on EOF.\n");
177
178static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000179bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000181 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000182}
183
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000184PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000185 "Write the given buffer to the IO stream.\n"
186 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000187 "Returns the number of bytes written, which is always the length of b\n"
188 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000189 "\n"
190 "Raises BlockingIOError if the buffer is full and the\n"
191 "underlying raw stream cannot accept more data at the moment.\n");
192
193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197}
198
199
Antoine Pitrou317def92017-12-13 01:39:26 +0100200typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000201 PyObject_HEAD
202
203 PyObject *raw;
204 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000205 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206 int readable;
207 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200208 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200209
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000210 /* True if this is a vanilla Buffered object (rather than a user derived
211 class) *and* the raw stream is a vanilla FileIO object. */
212 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213
214 /* Absolute position inside the raw stream (-1 if unknown). */
215 Py_off_t abs_pos;
216
217 /* A static buffer of size `buffer_size` */
218 char *buffer;
219 /* Current logical position in the buffer. */
220 Py_off_t pos;
221 /* Position of the raw stream in the buffer. */
222 Py_off_t raw_pos;
223
224 /* Just after the last buffered byte in the buffer, or -1 if the buffer
225 isn't ready for reading. */
226 Py_off_t read_end;
227
228 /* Just after the last byte actually written */
229 Py_off_t write_pos;
230 /* Just after the last byte waiting to be written, or -1 if the buffer
231 isn't ready for writing. */
232 Py_off_t write_end;
233
234 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200235 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000236
237 Py_ssize_t buffer_size;
238 Py_ssize_t buffer_mask;
239
240 PyObject *dict;
241 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000242} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000243
244/*
245 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200246
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000247 * BufferedReader, BufferedWriter and BufferedRandom try to share most
248 methods (this is helped by the members `readable` and `writable`, which
249 are initialized in the respective constructors)
250 * They also share a single buffer for reading and writing. This enables
251 interleaved reads and writes without flushing. It also makes the logic
252 a bit trickier to get right.
253 * The absolute position of the raw stream is cached, if possible, in the
254 `abs_pos` member. It must be updated every time an operation is done
255 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000256 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000257 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000258 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
259 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260
261 NOTE: we should try to maintain block alignment of reads and writes to the
262 raw stream (according to the buffer size), but for now it is only done
263 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200264
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000265*/
266
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000267/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000269static int
270_enter_buffered_busy(buffered *self)
271{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200272 int relax_locking;
273 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000274 if (self->owner == PyThread_get_thread_ident()) {
275 PyErr_Format(PyExc_RuntimeError,
276 "reentrant call inside %R", self);
277 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000278 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600279 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000280 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200281 if (!relax_locking)
282 st = PyThread_acquire_lock(self->lock, 1);
283 else {
284 /* When finalizing, we don't want a deadlock to happen with daemon
285 * threads abruptly shut down while they owned the lock.
286 * Therefore, only wait for a grace period (1 s.).
287 * Note that non-daemon threads have already exited here, so this
288 * shouldn't affect carefully written threaded I/O code.
289 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700290 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200291 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000292 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200293 if (relax_locking && st != PY_LOCK_ACQUIRED) {
294 PyObject *msgobj = PyUnicode_FromFormat(
295 "could not acquire lock for %A at interpreter "
296 "shutdown, possibly due to daemon threads",
297 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200298 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200299 Py_FatalError(msg);
300 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000301 return 1;
302}
303
304#define ENTER_BUFFERED(self) \
305 ( (PyThread_acquire_lock(self->lock, 0) ? \
306 1 : _enter_buffered_busy(self)) \
307 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000308
309#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000310 do { \
311 self->owner = 0; \
312 PyThread_release_lock(self->lock); \
313 } while(0);
314
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000315#define CHECK_INITIALIZED(self) \
316 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000317 if (self->detached) { \
318 PyErr_SetString(PyExc_ValueError, \
319 "raw stream has been detached"); \
320 } else { \
321 PyErr_SetString(PyExc_ValueError, \
322 "I/O operation on uninitialized object"); \
323 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000324 return NULL; \
325 }
326
327#define CHECK_INITIALIZED_INT(self) \
328 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000329 if (self->detached) { \
330 PyErr_SetString(PyExc_ValueError, \
331 "raw stream has been detached"); \
332 } else { \
333 PyErr_SetString(PyExc_ValueError, \
334 "I/O operation on uninitialized object"); \
335 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336 return -1; \
337 }
338
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000339#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500340 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000341 (self->fast_closed_checks \
342 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500343 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000344
345#define CHECK_CLOSED(self, error_msg) \
346 if (IS_CLOSED(self)) { \
347 PyErr_SetString(PyExc_ValueError, error_msg); \
348 return NULL; \
349 }
350
351
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000352#define VALID_READ_BUFFER(self) \
353 (self->readable && self->read_end != -1)
354
355#define VALID_WRITE_BUFFER(self) \
356 (self->writable && self->write_end != -1)
357
358#define ADJUST_POSITION(self, _new_pos) \
359 do { \
360 self->pos = _new_pos; \
361 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
362 self->read_end = self->pos; \
363 } while(0)
364
365#define READAHEAD(self) \
366 ((self->readable && VALID_READ_BUFFER(self)) \
367 ? (self->read_end - self->pos) : 0)
368
369#define RAW_OFFSET(self) \
370 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
371 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
372
373#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000374 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000375
376#define MINUS_LAST_BLOCK(self, size) \
377 (self->buffer_mask ? \
378 (size & ~self->buffer_mask) : \
379 (self->buffer_size * (size / self->buffer_size)))
380
381
382static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000383buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000384{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200385 self->finalizing = 1;
386 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387 return;
388 _PyObject_GC_UNTRACK(self);
389 self->ok = 0;
390 if (self->weakreflist != NULL)
391 PyObject_ClearWeakRefs((PyObject *)self);
392 Py_CLEAR(self->raw);
393 if (self->buffer) {
394 PyMem_Free(self->buffer);
395 self->buffer = NULL;
396 }
397 if (self->lock) {
398 PyThread_free_lock(self->lock);
399 self->lock = NULL;
400 }
401 Py_CLEAR(self->dict);
402 Py_TYPE(self)->tp_free((PyObject *)self);
403}
404
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200405static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200406buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200407{
408 Py_ssize_t res;
409
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200410 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200411 if (self->buffer)
412 res += self->buffer_size;
413 return PyLong_FromSsize_t(res);
414}
415
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000417buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000418{
419 Py_VISIT(self->raw);
420 Py_VISIT(self->dict);
421 return 0;
422}
423
424static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000425buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000426{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000427 self->ok = 0;
428 Py_CLEAR(self->raw);
429 Py_CLEAR(self->dict);
430 return 0;
431}
432
Antoine Pitroue033e062010-10-29 10:38:18 +0000433/* Because this can call arbitrary code, it shouldn't be called when
434 the refcount is 0 (that is, not directly from tp_dealloc unless
435 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000436static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000437buffered_dealloc_warn(buffered *self, PyObject *source)
438{
439 if (self->ok && self->raw) {
440 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100441 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
442 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000443 if (r)
444 Py_DECREF(r);
445 else
446 PyErr_Clear();
447 }
448 Py_RETURN_NONE;
449}
450
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000451/*
452 * _BufferedIOMixin methods
453 * This is not a class, just a collection of methods that will be reused
454 * by BufferedReader and BufferedWriter
455 */
456
457/* Flush and close */
458
459static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000460buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461{
462 CHECK_INITIALIZED(self)
463 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
464}
465
466static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000467buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000468{
469 int closed;
470 PyObject *res;
471 CHECK_INITIALIZED_INT(self)
472 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
473 if (res == NULL)
474 return -1;
475 closed = PyObject_IsTrue(res);
476 Py_DECREF(res);
477 return closed;
478}
479
480static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000481buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482{
483 CHECK_INITIALIZED(self)
484 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
485}
486
487static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000488buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489{
Benjamin Peterson68623612012-12-20 11:53:11 -0600490 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491 int r;
492
493 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000494 if (!ENTER_BUFFERED(self))
495 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498 if (r < 0)
499 goto end;
500 if (r > 0) {
501 res = Py_None;
502 Py_INCREF(res);
503 goto end;
504 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000505
Antoine Pitrou796564c2013-07-30 19:59:21 +0200506 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000507 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
508 if (r)
509 Py_DECREF(r);
510 else
511 PyErr_Clear();
512 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513 /* flush() will most probably re-take the lock, so drop it first */
514 LEAVE_BUFFERED(self)
515 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000516 if (!ENTER_BUFFERED(self))
517 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600518 if (res == NULL)
519 PyErr_Fetch(&exc, &val, &tb);
520 else
521 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522
523 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
524
Jesus Ceadc469452012-10-04 12:37:56 +0200525 if (self->buffer) {
526 PyMem_Free(self->buffer);
527 self->buffer = NULL;
528 }
529
Benjamin Peterson68623612012-12-20 11:53:11 -0600530 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300531 _PyErr_ChainExceptions(exc, val, tb);
532 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600533 }
534
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000535end:
536 LEAVE_BUFFERED(self)
537 return res;
538}
539
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000540/* detach */
541
542static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200543buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000544{
545 PyObject *raw, *res;
546 CHECK_INITIALIZED(self)
547 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
548 if (res == NULL)
549 return NULL;
550 Py_DECREF(res);
551 raw = self->raw;
552 self->raw = NULL;
553 self->detached = 1;
554 self->ok = 0;
555 return raw;
556}
557
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000558/* Inquiries */
559
560static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200561buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562{
563 CHECK_INITIALIZED(self)
564 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
565}
566
567static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200568buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 CHECK_INITIALIZED(self)
571 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
572}
573
574static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200575buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576{
577 CHECK_INITIALIZED(self)
578 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
579}
580
581static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000582buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583{
584 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200585 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586}
587
588static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000589buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590{
591 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200592 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593}
594
595/* Lower-level APIs */
596
597static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200598buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
601 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
602}
603
604static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +0200605buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
608 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
609}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611/* Forward decls */
612static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100613_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000617_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000619_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200621_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000623_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200628static Py_ssize_t
629_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630
631/*
632 * Helpers
633 */
634
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100635/* Sets the current error to BlockingIOError */
636static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200637_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100638{
639 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200640 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100641 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
642 errno, msg, written);
643 if (err)
644 PyErr_SetObject(PyExc_BlockingIOError, err);
645 Py_XDECREF(err);
646}
647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648/* Returns the address of the `written` member if a BlockingIOError was
649 raised, NULL otherwise. The error is always re-raised. */
650static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652{
653 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200654 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655
656 PyErr_Fetch(&t, &v, &tb);
657 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
658 PyErr_Restore(t, v, tb);
659 return NULL;
660 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200661 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662 /* TODO: sanity check (err->written >= 0) */
663 PyErr_Restore(t, v, tb);
664 return &err->written;
665}
666
667static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000668_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000671 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
673 if (res == NULL)
674 return -1;
675 n = PyNumber_AsOff_t(res, PyExc_ValueError);
676 Py_DECREF(res);
677 if (n < 0) {
678 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300679 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000680 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200681 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 return -1;
683 }
684 self->abs_pos = n;
685 return n;
686}
687
688static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000689_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690{
691 PyObject *res, *posobj, *whenceobj;
692 Py_off_t n;
693
694 posobj = PyLong_FromOff_t(target);
695 if (posobj == NULL)
696 return -1;
697 whenceobj = PyLong_FromLong(whence);
698 if (whenceobj == NULL) {
699 Py_DECREF(posobj);
700 return -1;
701 }
702 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
703 posobj, whenceobj, NULL);
704 Py_DECREF(posobj);
705 Py_DECREF(whenceobj);
706 if (res == NULL)
707 return -1;
708 n = PyNumber_AsOff_t(res, PyExc_ValueError);
709 Py_DECREF(res);
710 if (n < 0) {
711 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300712 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000713 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200714 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715 return -1;
716 }
717 self->abs_pos = n;
718 return n;
719}
720
721static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000722_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723{
724 Py_ssize_t n;
725 if (self->buffer_size <= 0) {
726 PyErr_SetString(PyExc_ValueError,
727 "buffer size must be strictly positive");
728 return -1;
729 }
730 if (self->buffer)
731 PyMem_Free(self->buffer);
732 self->buffer = PyMem_Malloc(self->buffer_size);
733 if (self->buffer == NULL) {
734 PyErr_NoMemory();
735 return -1;
736 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000737 if (self->lock)
738 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000739 self->lock = PyThread_allocate_lock();
740 if (self->lock == NULL) {
741 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
742 return -1;
743 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000744 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000745 /* Find out whether buffer_size is a power of 2 */
746 /* XXX is this optimization useful? */
747 for (n = self->buffer_size - 1; n & 1; n >>= 1)
748 ;
749 if (n == 0)
750 self->buffer_mask = self->buffer_size - 1;
751 else
752 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000753 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 PyErr_Clear();
755 return 0;
756}
757
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300758/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000759 clears the error indicator), 0 otherwise.
760 Should only be called when PyErr_Occurred() is true.
761*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700762int
763_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000764{
765 static PyObject *eintr_int = NULL;
766 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300767 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000768
769 if (eintr_int == NULL) {
770 eintr_int = PyLong_FromLong(EINTR);
771 assert(eintr_int != NULL);
772 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300773 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000774 return 0;
775 PyErr_Fetch(&typ, &val, &tb);
776 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300777 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000778 assert(env_err != NULL);
779 if (env_err->myerrno != NULL &&
780 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
781 Py_DECREF(typ);
782 Py_DECREF(val);
783 Py_XDECREF(tb);
784 return 1;
785 }
786 /* This silences any error set by PyObject_RichCompareBool() */
787 PyErr_Restore(typ, val, tb);
788 return 0;
789}
790
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000791/*
792 * Shared methods and wrappers
793 */
794
795static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200796buffered_flush_and_rewind_unlocked(buffered *self)
797{
798 PyObject *res;
799
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100800 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200801 if (res == NULL)
802 return NULL;
803 Py_DECREF(res);
804
805 if (self->readable) {
806 /* Rewind the raw stream so that its position corresponds to
807 the current logical position. */
808 Py_off_t n;
809 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
810 _bufferedreader_reset_buf(self);
811 if (n == -1)
812 return NULL;
813 }
814 Py_RETURN_NONE;
815}
816
817static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000818buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819{
820 PyObject *res;
821
822 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000823 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000824
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000825 if (!ENTER_BUFFERED(self))
826 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200827 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000828 LEAVE_BUFFERED(self)
829
830 return res;
831}
832
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300833/*[clinic input]
834_io._Buffered.peek
835 size: Py_ssize_t = 0
836 /
837
838[clinic start generated code]*/
839
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000840static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300841_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
842/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000844 PyObject *res = NULL;
845
846 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300847 CHECK_CLOSED(self, "peek of closed file")
848
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000849 if (!ENTER_BUFFERED(self))
850 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851
852 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200853 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000854 if (res == NULL)
855 goto end;
856 Py_CLEAR(res);
857 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200858 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859
860end:
861 LEAVE_BUFFERED(self)
862 return res;
863}
864
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300865/*[clinic input]
866_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300867 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300868 /
869[clinic start generated code]*/
870
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300872_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300873/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000874{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875 PyObject *res;
876
877 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000878 if (n < -1) {
879 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000880 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881 return NULL;
882 }
883
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000884 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000886 if (n == -1) {
887 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000888 if (!ENTER_BUFFERED(self))
889 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000890 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000891 }
892 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000893 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200894 if (res != Py_None)
895 return res;
896 Py_DECREF(res);
897 if (!ENTER_BUFFERED(self))
898 return NULL;
899 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000900 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901
Antoine Pitroue05565e2011-08-20 14:39:23 +0200902 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903 return res;
904}
905
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300906/*[clinic input]
907_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000908 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300909 /
910[clinic start generated code]*/
911
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300913_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000914/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300916 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 PyObject *res = NULL;
918
919 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000921 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300923
924 CHECK_CLOSED(self, "read of closed file")
925
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000926 if (n == 0)
927 return PyBytes_FromStringAndSize(NULL, 0);
928
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929 /* Return up to n bytes. If at least one byte is buffered, we
930 only return buffered bytes. Otherwise, we do one raw read. */
931
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
933 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100934 n = Py_MIN(have, n);
935 res = _bufferedreader_read_fast(self, n);
936 assert(res != Py_None);
937 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100939 res = PyBytes_FromStringAndSize(NULL, n);
940 if (res == NULL)
941 return NULL;
942 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200943 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100944 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200945 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000946 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100947 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
948 LEAVE_BUFFERED(self)
949 if (r == -1) {
950 Py_DECREF(res);
951 return NULL;
952 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 if (r == -2)
954 r = 0;
955 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100956 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 return res;
958}
959
960static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300961_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200963 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964 PyObject *res = NULL;
965
966 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200967
Antoine Pitrou3486a982011-05-12 01:57:53 +0200968 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
969 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300970 if (n >= buffer->len) {
971 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
972 self->pos += buffer->len;
973 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200974 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300975 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200976 self->pos += n;
977 written = n;
978 }
979
980 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300981 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200982
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200984 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985 if (res == NULL)
986 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200987 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000988 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200989
990 _bufferedreader_reset_buf(self);
991 self->pos = 0;
992
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300993 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200994 remaining > 0;
995 written += n, remaining -= n) {
996 /* If remaining bytes is larger than internal buffer size, copy
997 * directly into caller's buffer. */
998 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300999 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001000 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001001 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001002
1003 /* In readinto1 mode, we do not want to fill the internal
1004 buffer if we already have some data to return */
1005 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001006 n = _bufferedreader_fill_buffer(self);
1007 if (n > 0) {
1008 if (n > remaining)
1009 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001010 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001011 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001012 self->pos += n;
1013 continue; /* short circuit */
1014 }
1015 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001016 else
1017 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001018
Antoine Pitrou3486a982011-05-12 01:57:53 +02001019 if (n == 0 || (n == -2 && written > 0))
1020 break;
1021 if (n < 0) {
1022 if (n == -2) {
1023 Py_INCREF(Py_None);
1024 res = Py_None;
1025 }
1026 goto end;
1027 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001028
Benjamin Petersona96fea02014-06-22 14:17:44 -07001029 /* At most one read in readinto1 mode */
1030 if (readinto1) {
1031 written += n;
1032 break;
1033 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001034 }
1035 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001036
1037end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001038 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001039 return res;
1040}
1041
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001042/*[clinic input]
1043_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001044 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001045 /
1046[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001047
1048static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001049_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001050/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001051{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001052 return _buffered_readinto_generic(self, buffer, 0);
1053}
1054
1055/*[clinic input]
1056_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001057 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001058 /
1059[clinic start generated code]*/
1060
1061static PyObject *
1062_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001063/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001064{
1065 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001066}
1067
1068
1069static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001070_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001071{
1072 PyObject *res = NULL;
1073 PyObject *chunks = NULL;
1074 Py_ssize_t n, written = 0;
1075 const char *start, *s, *end;
1076
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001077 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001078
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001079 /* First, try to find a line in the buffer. This can run unlocked because
1080 the calls to the C API are simple enough that they can't trigger
1081 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001082 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1083 if (limit >= 0 && n > limit)
1084 n = limit;
1085 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001086 s = memchr(start, '\n', n);
1087 if (s != NULL) {
1088 res = PyBytes_FromStringAndSize(start, s - start + 1);
1089 if (res != NULL)
1090 self->pos += s - start + 1;
1091 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001092 }
1093 if (n == limit) {
1094 res = PyBytes_FromStringAndSize(start, n);
1095 if (res != NULL)
1096 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001097 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001098 }
1099
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001100 if (!ENTER_BUFFERED(self))
1101 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001102
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001103 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001104 chunks = PyList_New(0);
1105 if (chunks == NULL)
1106 goto end;
1107 if (n > 0) {
1108 res = PyBytes_FromStringAndSize(start, n);
1109 if (res == NULL)
1110 goto end;
1111 if (PyList_Append(chunks, res) < 0) {
1112 Py_CLEAR(res);
1113 goto end;
1114 }
1115 Py_CLEAR(res);
1116 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001117 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001118 if (limit >= 0)
1119 limit -= n;
1120 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001121 if (self->writable) {
1122 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1123 if (r == NULL)
1124 goto end;
1125 Py_DECREF(r);
1126 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127
1128 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001129 _bufferedreader_reset_buf(self);
1130 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001131 if (n == -1)
1132 goto end;
1133 if (n <= 0)
1134 break;
1135 if (limit >= 0 && n > limit)
1136 n = limit;
1137 start = self->buffer;
1138 end = start + n;
1139 s = start;
1140 while (s < end) {
1141 if (*s++ == '\n') {
1142 res = PyBytes_FromStringAndSize(start, s - start);
1143 if (res == NULL)
1144 goto end;
1145 self->pos = s - start;
1146 goto found;
1147 }
1148 }
1149 res = PyBytes_FromStringAndSize(start, n);
1150 if (res == NULL)
1151 goto end;
1152 if (n == limit) {
1153 self->pos = n;
1154 break;
1155 }
1156 if (PyList_Append(chunks, res) < 0) {
1157 Py_CLEAR(res);
1158 goto end;
1159 }
1160 Py_CLEAR(res);
1161 written += n;
1162 if (limit >= 0)
1163 limit -= n;
1164 }
1165found:
1166 if (res != NULL && PyList_Append(chunks, res) < 0) {
1167 Py_CLEAR(res);
1168 goto end;
1169 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001170 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001171
1172end:
1173 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001174end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001175 Py_XDECREF(chunks);
1176 return res;
1177}
1178
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001179/*[clinic input]
1180_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001181 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001182 /
1183[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001184
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001185static PyObject *
1186_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001187/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001188{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001189 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001190 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001191}
1192
1193
1194static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02001195buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001196{
1197 Py_off_t pos;
1198
1199 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001200 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201 if (pos == -1)
1202 return NULL;
1203 pos -= RAW_OFFSET(self);
1204 /* TODO: sanity check (pos >= 0) */
1205 return PyLong_FromOff_t(pos);
1206}
1207
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001208/*[clinic input]
1209_io._Buffered.seek
1210 target as targetobj: object
1211 whence: int = 0
1212 /
1213[clinic start generated code]*/
1214
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001215static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001216_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1217/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001218{
1219 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001220 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001221
1222 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001223
1224 /* Do some error checking instead of trusting OS 'seek()'
1225 ** error detection, just in case.
1226 */
1227 if ((whence < 0 || whence >2)
1228#ifdef SEEK_HOLE
1229 && (whence != SEEK_HOLE)
1230#endif
1231#ifdef SEEK_DATA
1232 && (whence != SEEK_DATA)
1233#endif
1234 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001235 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001236 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001237 return NULL;
1238 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001239
1240 CHECK_CLOSED(self, "seek of closed file")
1241
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001242 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1243 return NULL;
1244
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1246 if (target == -1 && PyErr_Occurred())
1247 return NULL;
1248
Jesus Cea94363612012-06-22 18:32:07 +02001249 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1250 buffer. Other whence values must be managed without this optimization.
1251 Some Operating Systems can provide additional values, like
1252 SEEK_HOLE/SEEK_DATA. */
1253 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 Py_off_t current, avail;
1255 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001256 so as to return quickly if possible. Also, we needn't take the
1257 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001258 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001259 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1260 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001261 current = RAW_TELL(self);
1262 avail = READAHEAD(self);
1263 if (avail > 0) {
1264 Py_off_t offset;
1265 if (whence == 0)
1266 offset = target - (current - RAW_OFFSET(self));
1267 else
1268 offset = target;
1269 if (offset >= -self->pos && offset <= avail) {
1270 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001271 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001272 }
1273 }
1274 }
1275
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001276 if (!ENTER_BUFFERED(self))
1277 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001278
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001279 /* Fallback: invoke raw seek() method and clear buffer */
1280 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001281 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 if (res == NULL)
1283 goto end;
1284 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285 }
1286
1287 /* TODO: align on block boundary and read buffer if needed? */
1288 if (whence == 1)
1289 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001290 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001291 if (n == -1)
1292 goto end;
1293 self->raw_pos = -1;
1294 res = PyLong_FromOff_t(n);
1295 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001296 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001297
1298end:
1299 LEAVE_BUFFERED(self)
1300 return res;
1301}
1302
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001303/*[clinic input]
1304_io._Buffered.truncate
1305 pos: object = None
1306 /
1307[clinic start generated code]*/
1308
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001309static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001310_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1311/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001312{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 PyObject *res = NULL;
1314
1315 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001316 if (!ENTER_BUFFERED(self))
1317 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001318
1319 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001320 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321 if (res == NULL)
1322 goto end;
1323 Py_CLEAR(res);
1324 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001325 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1326 if (res == NULL)
1327 goto end;
1328 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001329 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330 PyErr_Clear();
1331
1332end:
1333 LEAVE_BUFFERED(self)
1334 return res;
1335}
1336
1337static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001338buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339{
1340 PyObject *line;
1341 PyTypeObject *tp;
1342
1343 CHECK_INITIALIZED(self);
1344
1345 tp = Py_TYPE(self);
1346 if (tp == &PyBufferedReader_Type ||
1347 tp == &PyBufferedRandom_Type) {
1348 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001349 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350 }
1351 else {
1352 line = PyObject_CallMethodObjArgs((PyObject *)self,
1353 _PyIO_str_readline, NULL);
1354 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001355 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001356 "readline() should have returned a bytes object, "
1357 "not '%.200s'", Py_TYPE(line)->tp_name);
1358 Py_DECREF(line);
1359 return NULL;
1360 }
1361 }
1362
1363 if (line == NULL)
1364 return NULL;
1365
1366 if (PyBytes_GET_SIZE(line) == 0) {
1367 /* Reached EOF or would have blocked */
1368 Py_DECREF(line);
1369 return NULL;
1370 }
1371
1372 return line;
1373}
1374
Antoine Pitrou716c4442009-05-23 19:04:03 +00001375static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001376buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001377{
1378 PyObject *nameobj, *res;
1379
Martin v. Löwis767046a2011-10-14 15:35:36 +02001380 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001381 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001382 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001383 PyErr_Clear();
1384 else
1385 return NULL;
1386 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1387 }
1388 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001389 int status = Py_ReprEnter((PyObject *)self);
1390 res = NULL;
1391 if (status == 0) {
1392 res = PyUnicode_FromFormat("<%s name=%R>",
1393 Py_TYPE(self)->tp_name, nameobj);
1394 Py_ReprLeave((PyObject *)self);
1395 }
1396 else if (status > 0) {
1397 PyErr_Format(PyExc_RuntimeError,
1398 "reentrant call inside %s.__repr__",
1399 Py_TYPE(self)->tp_name);
1400 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001401 Py_DECREF(nameobj);
1402 }
1403 return res;
1404}
1405
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001406/*
1407 * class BufferedReader
1408 */
1409
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001410static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411{
1412 self->read_end = -1;
1413}
1414
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001415/*[clinic input]
1416_io.BufferedReader.__init__
1417 raw: object
1418 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001419
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001420Create a new buffered reader using the given readable raw IO object.
1421[clinic start generated code]*/
1422
1423static int
1424_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1425 Py_ssize_t buffer_size)
1426/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1427{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001428 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001429 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001430
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001431 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001432 return -1;
1433
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001434 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001435 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001436 self->buffer_size = buffer_size;
1437 self->readable = 1;
1438 self->writable = 0;
1439
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001440 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001442 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001444 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1445 Py_TYPE(raw) == &PyFileIO_Type);
1446
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001447 self->ok = 1;
1448 return 0;
1449}
1450
1451static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001452_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001453{
1454 Py_buffer buf;
1455 PyObject *memobj, *res;
1456 Py_ssize_t n;
1457 /* NOTE: the buffer needn't be released as its object is NULL. */
1458 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1459 return -1;
1460 memobj = PyMemoryView_FromBuffer(&buf);
1461 if (memobj == NULL)
1462 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001463 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1464 occurs so we needn't do it ourselves.
1465 We then retry reading, ignoring the signal if no handler has
1466 raised (see issue #10956).
1467 */
1468 do {
1469 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001470 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471 Py_DECREF(memobj);
1472 if (res == NULL)
1473 return -1;
1474 if (res == Py_None) {
1475 /* Non-blocking stream would have blocked. Special return code! */
1476 Py_DECREF(res);
1477 return -2;
1478 }
1479 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1480 Py_DECREF(res);
1481 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001482 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001483 "raw readinto() returned invalid length %zd "
1484 "(should have been between 0 and %zd)", n, len);
1485 return -1;
1486 }
1487 if (n > 0 && self->abs_pos != -1)
1488 self->abs_pos += n;
1489 return n;
1490}
1491
1492static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001493_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001494{
1495 Py_ssize_t start, len, n;
1496 if (VALID_READ_BUFFER(self))
1497 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1498 else
1499 start = 0;
1500 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001501 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001502 if (n <= 0)
1503 return n;
1504 self->read_end = start + n;
1505 self->raw_pos = start + n;
1506 return n;
1507}
1508
1509static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001510_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001511{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001512 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001513 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001514
1515 /* First copy what we have in the current buffer. */
1516 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1517 if (current_size) {
1518 data = PyBytes_FromStringAndSize(
1519 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001520 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001521 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001522 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001523 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001524 /* We're going past the buffer's bounds, flush it */
1525 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001526 tmp = buffered_flush_and_rewind_unlocked(self);
1527 if (tmp == NULL)
1528 goto cleanup;
1529 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001530 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001531 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001532
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001533 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1534 goto cleanup;
1535 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001536 if (readall) {
1537 tmp = _PyObject_CallNoArg(readall);
1538 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001539 if (tmp == NULL)
1540 goto cleanup;
1541 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001542 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001543 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001544 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001545 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001546 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001547 } else {
1548 if (tmp != Py_None) {
1549 PyBytes_Concat(&data, tmp);
1550 }
1551 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001552 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001553 goto cleanup;
1554 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001555
1556 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 if (chunks == NULL)
1558 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001559
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001560 while (1) {
1561 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001562 if (PyList_Append(chunks, data) < 0)
1563 goto cleanup;
1564 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001565 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001566
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567 /* Read until EOF or until read() would block. */
1568 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 if (data == NULL)
1570 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001571 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001572 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001573 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001574 }
1575 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1576 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001577 res = data;
1578 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001579 }
1580 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001581 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1582 res = tmp;
1583 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001584 }
1585 }
1586 current_size += PyBytes_GET_SIZE(data);
1587 if (self->abs_pos != -1)
1588 self->abs_pos += PyBytes_GET_SIZE(data);
1589 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001590cleanup:
1591 /* res is either NULL or a borrowed ref */
1592 Py_XINCREF(res);
1593 Py_XDECREF(data);
1594 Py_XDECREF(tmp);
1595 Py_XDECREF(chunks);
1596 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001597}
1598
1599/* Read n bytes from the buffer if it can, otherwise return None.
1600 This function is simple enough that it can run unlocked. */
1601static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001602_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001603{
1604 Py_ssize_t current_size;
1605
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1607 if (n <= current_size) {
1608 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1610 if (res != NULL)
1611 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001612 return res;
1613 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001614 Py_RETURN_NONE;
1615}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001616
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001617/* Generic read function: read from the stream until enough bytes are read,
1618 * or until an EOF occurs or until read() would block.
1619 */
1620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001621_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001622{
1623 PyObject *res = NULL;
1624 Py_ssize_t current_size, remaining, written;
1625 char *out;
1626
1627 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1628 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001630
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001631 res = PyBytes_FromStringAndSize(NULL, n);
1632 if (res == NULL)
1633 goto error;
1634 out = PyBytes_AS_STRING(res);
1635 remaining = n;
1636 written = 0;
1637 if (current_size > 0) {
1638 memcpy(out, self->buffer + self->pos, current_size);
1639 remaining -= current_size;
1640 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001641 self->pos += current_size;
1642 }
1643 /* Flush the write buffer if necessary */
1644 if (self->writable) {
1645 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1646 if (r == NULL)
1647 goto error;
1648 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001649 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001650 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001651 while (remaining > 0) {
1652 /* We want to read a whole block at the end into buffer.
1653 If we had readv() we could do this in one pass. */
1654 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1655 if (r == 0)
1656 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001657 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001658 if (r == -1)
1659 goto error;
1660 if (r == 0 || r == -2) {
1661 /* EOF occurred or read() would block. */
1662 if (r == 0 || written > 0) {
1663 if (_PyBytes_Resize(&res, written))
1664 goto error;
1665 return res;
1666 }
1667 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001668 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001669 }
1670 remaining -= r;
1671 written += r;
1672 }
1673 assert(remaining <= self->buffer_size);
1674 self->pos = 0;
1675 self->raw_pos = 0;
1676 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001677 /* NOTE: when the read is satisfied, we avoid issuing any additional
1678 reads, which could block indefinitely (e.g. on a socket).
1679 See issue #9550. */
1680 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001681 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001682 if (r == -1)
1683 goto error;
1684 if (r == 0 || r == -2) {
1685 /* EOF occurred or read() would block. */
1686 if (r == 0 || written > 0) {
1687 if (_PyBytes_Resize(&res, written))
1688 goto error;
1689 return res;
1690 }
1691 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001692 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693 }
1694 if (remaining > r) {
1695 memcpy(out + written, self->buffer + self->pos, r);
1696 written += r;
1697 self->pos += r;
1698 remaining -= r;
1699 }
1700 else if (remaining > 0) {
1701 memcpy(out + written, self->buffer + self->pos, remaining);
1702 written += remaining;
1703 self->pos += remaining;
1704 remaining = 0;
1705 }
1706 if (remaining == 0)
1707 break;
1708 }
1709
1710 return res;
1711
1712error:
1713 Py_XDECREF(res);
1714 return NULL;
1715}
1716
1717static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001718_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719{
1720 Py_ssize_t have, r;
1721
1722 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1723 /* Constraints:
1724 1. we don't want to advance the file position.
1725 2. we don't want to lose block alignment, so we can't shift the buffer
1726 to make some place.
1727 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1728 */
1729 if (have > 0) {
1730 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1731 }
1732
1733 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001734 _bufferedreader_reset_buf(self);
1735 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001736 if (r == -1)
1737 return NULL;
1738 if (r == -2)
1739 r = 0;
1740 self->pos = 0;
1741 return PyBytes_FromStringAndSize(self->buffer, r);
1742}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743
1744
Benjamin Peterson59406a92009-03-26 17:10:29 +00001745
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746/*
1747 * class BufferedWriter
1748 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001749static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001750_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001751{
1752 self->write_pos = 0;
1753 self->write_end = -1;
1754}
1755
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001756/*[clinic input]
1757_io.BufferedWriter.__init__
1758 raw: object
1759 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001761A buffer for a writeable sequential RawIO object.
1762
1763The constructor creates a BufferedWriter for the given writeable raw
1764stream. If the buffer_size is not given, it defaults to
1765DEFAULT_BUFFER_SIZE.
1766[clinic start generated code]*/
1767
1768static int
1769_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1770 Py_ssize_t buffer_size)
1771/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1772{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001774 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001776 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001777 return -1;
1778
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001780 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001781 self->readable = 0;
1782 self->writable = 1;
1783
1784 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001785 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 self->pos = 0;
1789
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001790 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1791 Py_TYPE(raw) == &PyFileIO_Type);
1792
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 self->ok = 1;
1794 return 0;
1795}
1796
1797static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001798_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799{
1800 Py_buffer buf;
1801 PyObject *memobj, *res;
1802 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001803 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 /* NOTE: the buffer needn't be released as its object is NULL. */
1805 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1806 return -1;
1807 memobj = PyMemoryView_FromBuffer(&buf);
1808 if (memobj == NULL)
1809 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001810 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1811 occurs so we needn't do it ourselves.
1812 We then retry writing, ignoring the signal if no handler has
1813 raised (see issue #10956).
1814 */
1815 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001816 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001817 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001818 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001819 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 Py_DECREF(memobj);
1821 if (res == NULL)
1822 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001823 if (res == Py_None) {
1824 /* Non-blocking stream would have blocked. Special return code!
1825 Being paranoid we reset errno in case it is changed by code
1826 triggered by a decref. errno is used by _set_BlockingIOError(). */
1827 Py_DECREF(res);
1828 errno = errnum;
1829 return -2;
1830 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1832 Py_DECREF(res);
1833 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001834 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 "raw write() returned invalid length %zd "
1836 "(should have been between 0 and %zd)", n, len);
1837 return -1;
1838 }
1839 if (n > 0 && self->abs_pos != -1)
1840 self->abs_pos += n;
1841 return n;
1842}
1843
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001844static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001845_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846{
1847 Py_ssize_t written = 0;
1848 Py_off_t n, rewind;
1849
1850 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1851 goto end;
1852 /* First, rewind */
1853 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1854 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001855 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856 if (n < 0) {
1857 goto error;
1858 }
1859 self->raw_pos -= rewind;
1860 }
1861 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001862 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863 self->buffer + self->write_pos,
1864 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1865 Py_off_t, Py_ssize_t));
1866 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001867 goto error;
1868 }
1869 else if (n == -2) {
1870 _set_BlockingIOError("write could not complete without blocking",
1871 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872 goto error;
1873 }
1874 self->write_pos += n;
1875 self->raw_pos = self->write_pos;
1876 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001877 /* Partial writes can return successfully when interrupted by a
1878 signal (see write(2)). We must run signal handlers before
1879 blocking another time, possibly indefinitely. */
1880 if (PyErr_CheckSignals() < 0)
1881 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001882 }
1883
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884
1885end:
Nitish Chandra059f58c2018-01-28 21:30:09 +05301886 /* This ensures that after return from this function,
1887 VALID_WRITE_BUFFER(self) returns false.
1888
1889 This is a required condition because when a tell() is called
1890 after flushing and if VALID_READ_BUFFER(self) is false, we need
1891 VALID_WRITE_BUFFER(self) to be false to have
1892 RAW_OFFSET(self) == 0.
1893
1894 Issue: https://bugs.python.org/issue32228 */
1895 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001896 Py_RETURN_NONE;
1897
1898error:
1899 return NULL;
1900}
1901
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001902/*[clinic input]
1903_io.BufferedWriter.write
1904 buffer: Py_buffer
1905 /
1906[clinic start generated code]*/
1907
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001909_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1910/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001911{
1912 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001913 Py_ssize_t written, avail, remaining;
1914 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915
1916 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001917
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001918 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001919 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001920
benfogle9703f092017-11-10 16:03:40 -05001921 /* Issue #31976: Check for closed file after acquiring the lock. Another
1922 thread could be holding the lock while closing the file. */
1923 if (IS_CLOSED(self)) {
1924 PyErr_SetString(PyExc_ValueError, "write to closed file");
1925 goto error;
1926 }
1927
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928 /* Fast path: the data to write can be fully buffered. */
1929 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1930 self->pos = 0;
1931 self->raw_pos = 0;
1932 }
1933 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001934 if (buffer->len <= avail) {
1935 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001936 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937 self->write_pos = self->pos;
1938 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001939 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001940 if (self->pos > self->write_end)
1941 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001942 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001943 goto end;
1944 }
1945
1946 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001947 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001949 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001950 if (w == NULL)
1951 goto error;
1952 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001953 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 /* Make some place by shifting the buffer. */
1955 assert(VALID_WRITE_BUFFER(self));
1956 memmove(self->buffer, self->buffer + self->write_pos,
1957 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1958 Py_off_t, Py_ssize_t));
1959 self->write_end -= self->write_pos;
1960 self->raw_pos -= self->write_pos;
1961 self->pos -= self->write_pos;
1962 self->write_pos = 0;
1963 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1964 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001965 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966 /* Everything can be buffered */
1967 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001968 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1969 self->write_end += buffer->len;
1970 self->pos += buffer->len;
1971 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972 goto end;
1973 }
1974 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001975 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001977 self->pos += avail;
1978 /* XXX Modifying the existing exception e using the pointer w
1979 will change e.characters_written but not e.args[2].
1980 Therefore we just replace with a new error. */
1981 _set_BlockingIOError("write could not complete without blocking",
1982 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983 goto error;
1984 }
1985 Py_CLEAR(res);
1986
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001987 /* Adjust the raw stream position if it is away from the logical stream
1988 position. This happens if the read buffer has been filled but not
1989 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1990 the raw stream by itself).
1991 Fixes issue #6629.
1992 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001993 offset = RAW_OFFSET(self);
1994 if (offset != 0) {
1995 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001996 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001997 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001998 }
1999
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002001 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002002 written = 0;
2003 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002004 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002005 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002006 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002007 goto error;
2008 } else if (n == -2) {
2009 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 if (remaining > self->buffer_size) {
2011 /* Can't buffer everything, still buffer as much as possible */
2012 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002013 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 self->raw_pos = 0;
2015 ADJUST_POSITION(self, self->buffer_size);
2016 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002017 written += self->buffer_size;
2018 _set_BlockingIOError("write could not complete without "
2019 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 goto error;
2021 }
2022 PyErr_Clear();
2023 break;
2024 }
2025 written += n;
2026 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002027 /* Partial writes can return successfully when interrupted by a
2028 signal (see write(2)). We must run signal handlers before
2029 blocking another time, possibly indefinitely. */
2030 if (PyErr_CheckSignals() < 0)
2031 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002032 }
2033 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002034 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002036 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 written += remaining;
2038 }
2039 self->write_pos = 0;
2040 /* TODO: sanity check (remaining >= 0) */
2041 self->write_end = remaining;
2042 ADJUST_POSITION(self, remaining);
2043 self->raw_pos = 0;
2044
2045end:
2046 res = PyLong_FromSsize_t(written);
2047
2048error:
2049 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002050 return res;
2051}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002052
2053
2054
2055/*
2056 * BufferedRWPair
2057 */
2058
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059/* XXX The usefulness of this (compared to having two separate IO objects) is
2060 * questionable.
2061 */
2062
2063typedef struct {
2064 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002065 buffered *reader;
2066 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002067 PyObject *dict;
2068 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002069} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002070
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002071/*[clinic input]
2072_io.BufferedRWPair.__init__
2073 reader: object
2074 writer: object
2075 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2076 /
2077
2078A buffered reader and writer object together.
2079
2080A buffered reader object and buffered writer object put together to
2081form a sequential IO object that can read and write. This is typically
2082used with a socket or two-way pipe.
2083
2084reader and writer are RawIOBase objects that are readable and
2085writeable respectively. If the buffer_size is omitted it defaults to
2086DEFAULT_BUFFER_SIZE.
2087[clinic start generated code]*/
2088
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002089static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002090_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2091 PyObject *writer, Py_ssize_t buffer_size)
2092/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002093{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002094 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002096 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097 return -1;
2098
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002099 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002100 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 if (self->reader == NULL)
2102 return -1;
2103
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002104 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002105 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106 if (self->writer == NULL) {
2107 Py_CLEAR(self->reader);
2108 return -1;
2109 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002110
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 return 0;
2112}
2113
2114static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002115bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002116{
2117 Py_VISIT(self->dict);
2118 return 0;
2119}
2120
2121static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002122bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123{
2124 Py_CLEAR(self->reader);
2125 Py_CLEAR(self->writer);
2126 Py_CLEAR(self->dict);
2127 return 0;
2128}
2129
2130static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002132{
2133 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002134 if (self->weakreflist != NULL)
2135 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002136 Py_CLEAR(self->reader);
2137 Py_CLEAR(self->writer);
2138 Py_CLEAR(self->dict);
2139 Py_TYPE(self)->tp_free((PyObject *) self);
2140}
2141
2142static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002143_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002144{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002145 PyObject *func, *ret;
2146 if (self == NULL) {
2147 PyErr_SetString(PyExc_ValueError,
2148 "I/O operation on uninitialized object");
2149 return NULL;
2150 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002152 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002154 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155 return NULL;
2156 }
2157
2158 ret = PyObject_CallObject(func, args);
2159 Py_DECREF(func);
2160 return ret;
2161}
2162
2163static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002164bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002166 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167}
2168
2169static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002172 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173}
2174
2175static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002176bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002178 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179}
2180
2181static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002182bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002183{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002184 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002185}
2186
2187static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002188bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2189{
2190 return _forward_call(self->reader, &PyId_readinto1, args);
2191}
2192
2193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002194bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002196 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197}
2198
2199static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002200bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201{
jdemeyerfc512e32018-08-02 13:14:54 +02002202 return _forward_call(self->writer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203}
2204
2205static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002206bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207{
jdemeyerfc512e32018-08-02 13:14:54 +02002208 return _forward_call(self->reader, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209}
2210
2211static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002212bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213{
jdemeyerfc512e32018-08-02 13:14:54 +02002214 return _forward_call(self->writer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002215}
2216
2217static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002218bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002220 PyObject *exc = NULL, *val, *tb;
jdemeyerfc512e32018-08-02 13:14:54 +02002221 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002223 PyErr_Fetch(&exc, &val, &tb);
2224 else
2225 Py_DECREF(ret);
jdemeyerfc512e32018-08-02 13:14:54 +02002226 ret = _forward_call(self->reader, &PyId_close, NULL);
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002227 if (exc != NULL) {
2228 _PyErr_ChainExceptions(exc, val, tb);
2229 Py_CLEAR(ret);
2230 }
2231 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232}
2233
2234static PyObject *
jdemeyerfc512e32018-08-02 13:14:54 +02002235bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236{
jdemeyerfc512e32018-08-02 13:14:54 +02002237 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238
2239 if (ret != Py_False) {
2240 /* either True or exception */
2241 return ret;
2242 }
2243 Py_DECREF(ret);
2244
jdemeyerfc512e32018-08-02 13:14:54 +02002245 return _forward_call(self->reader, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246}
2247
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002248static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002249bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002250{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002251 if (self->writer == NULL) {
2252 PyErr_SetString(PyExc_RuntimeError,
2253 "the BufferedRWPair object is being garbage-collected");
2254 return NULL;
2255 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002256 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2257}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002258
2259
2260
2261/*
2262 * BufferedRandom
2263 */
2264
2265/*[clinic input]
2266_io.BufferedRandom.__init__
2267 raw: object
2268 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2269
2270A buffered interface to random access streams.
2271
2272The constructor creates a reader and writer for a seekable stream,
2273raw, given in the first argument. If the buffer_size is omitted it
2274defaults to DEFAULT_BUFFER_SIZE.
2275[clinic start generated code]*/
2276
2277static int
2278_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2279 Py_ssize_t buffer_size)
2280/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2281{
2282 self->ok = 0;
2283 self->detached = 0;
2284
2285 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2286 return -1;
2287 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2288 return -1;
2289 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2290 return -1;
2291
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002292 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002293 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002294 self->buffer_size = buffer_size;
2295 self->readable = 1;
2296 self->writable = 1;
2297
2298 if (_buffered_init(self) < 0)
2299 return -1;
2300 _bufferedreader_reset_buf(self);
2301 _bufferedwriter_reset_buf(self);
2302 self->pos = 0;
2303
2304 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2305 Py_TYPE(raw) == &PyFileIO_Type);
2306
2307 self->ok = 1;
2308 return 0;
2309}
2310
2311#include "clinic/bufferedio.c.h"
2312
2313
2314static PyMethodDef bufferediobase_methods[] = {
2315 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2316 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2317 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2318 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2319 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2320 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2321 {NULL, NULL}
2322};
2323
2324PyTypeObject PyBufferedIOBase_Type = {
2325 PyVarObject_HEAD_INIT(NULL, 0)
2326 "_io._BufferedIOBase", /*tp_name*/
2327 0, /*tp_basicsize*/
2328 0, /*tp_itemsize*/
2329 0, /*tp_dealloc*/
2330 0, /*tp_print*/
2331 0, /*tp_getattr*/
2332 0, /*tp_setattr*/
2333 0, /*tp_compare */
2334 0, /*tp_repr*/
2335 0, /*tp_as_number*/
2336 0, /*tp_as_sequence*/
2337 0, /*tp_as_mapping*/
2338 0, /*tp_hash */
2339 0, /*tp_call*/
2340 0, /*tp_str*/
2341 0, /*tp_getattro*/
2342 0, /*tp_setattro*/
2343 0, /*tp_as_buffer*/
2344 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2345 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2346 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
2436 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2437 _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
2522 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2523 _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 Pitrou796564c2013-07-30 19:59:21 +02002599 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* 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 Pitrou796564c2013-07-30 19:59:21 +02002693 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*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};