blob: 50c87c1746d6f21021e698948dc57e66fc0c742a [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"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030016/*[clinic input]
17module _io
18class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24[clinic start generated code]*/
25/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020027_Py_IDENTIFIER(close);
28_Py_IDENTIFIER(_dealloc_warn);
29_Py_IDENTIFIER(flush);
30_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020031_Py_IDENTIFIER(mode);
32_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020033_Py_IDENTIFIER(peek);
34_Py_IDENTIFIER(read);
35_Py_IDENTIFIER(read1);
36_Py_IDENTIFIER(readable);
37_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070038_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020039_Py_IDENTIFIER(writable);
40_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042/*
43 * BufferedIOBase class, inherits from IOBase.
44 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000045PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000046 "Base class for buffered IO objects.\n"
47 "\n"
48 "The main difference with RawIOBase is that the read() method\n"
49 "supports omitting the size argument, and does not have a default\n"
50 "implementation that defers to readinto().\n"
51 "\n"
52 "In addition, read(), readinto() and write() may raise\n"
53 "BlockingIOError if the underlying raw stream is in non-blocking\n"
54 "mode and not ready; unlike their raw counterparts, they will never\n"
55 "return None.\n"
56 "\n"
57 "A typical implementation should not inherit from a RawIOBase\n"
58 "implementation, but wrap one.\n"
59 );
60
61static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030062_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000063{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064 Py_ssize_t len;
65 PyObject *data;
66
Benjamin Petersona96fea02014-06-22 14:17:44 -070067 data = _PyObject_CallMethodId(self,
68 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030069 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030071 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000072
73 if (!PyBytes_Check(data)) {
74 Py_DECREF(data);
75 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030076 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 }
78
Serhiy Storchakafff9a312017-03-21 08:53:25 +020079 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030080 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030081 PyErr_Format(PyExc_ValueError,
82 "read() returned too much data: "
83 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030084 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030085 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030086 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030087 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030088 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090 Py_DECREF(data);
91
92 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000093}
94
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030095/*[clinic input]
96_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070097 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030098 /
99[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700100
101static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300102_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700103/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700104{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300105 return _bufferediobase_readinto_generic(self, buffer, 0);
106}
107
108/*[clinic input]
109_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700110 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300111 /
112[clinic start generated code]*/
113
114static PyObject *
115_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700116/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300117{
118 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700119}
120
121static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100124 _PyIO_State *state = IO_STATE();
125 if (state != NULL)
126 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000127 return NULL;
128}
129
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300130/*[clinic input]
131_io._BufferedIOBase.detach
132
133Disconnect this buffer from its underlying raw stream and return it.
134
135After the raw stream has been detached, the buffer is in an unusable
136state.
137[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000138
139static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300140_io__BufferedIOBase_detach_impl(PyObject *self)
141/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000142{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000144}
145
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000146PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000147 "Read and return up to n bytes.\n"
148 "\n"
149 "If the argument is omitted, None, or negative, reads and\n"
150 "returns all data until EOF.\n"
151 "\n"
152 "If the argument is positive, and the underlying raw stream is\n"
153 "not 'interactive', multiple raw reads may be issued to satisfy\n"
154 "the byte count (unless EOF is reached first). But for\n"
155 "interactive raw streams (as well as sockets and pipes), at most\n"
156 "one raw read will be issued, and a short result does not imply\n"
157 "that EOF is imminent.\n"
158 "\n"
159 "Returns an empty bytes object on EOF.\n"
160 "\n"
161 "Returns None if the underlying raw stream was open in non-blocking\n"
162 "mode and no data is available at the moment.\n");
163
164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000166{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000168}
169
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000170PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171 "Read and return up to n bytes, with at most one read() call\n"
172 "to the underlying raw stream. A short result does not imply\n"
173 "that EOF is imminent.\n"
174 "\n"
175 "Returns an empty bytes object on EOF.\n");
176
177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000178bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000179{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000180 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181}
182
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000183PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000184 "Write the given buffer to the IO stream.\n"
185 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000186 "Returns the number of bytes written, which is always the length of b\n"
187 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188 "\n"
189 "Raises BlockingIOError if the buffer is full and the\n"
190 "underlying raw stream cannot accept more data at the moment.\n");
191
192static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000193bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000194{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000195 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196}
197
198
Neil Schemenauere38d12e2017-09-04 20:18:38 -0700199typedef struct _buffered {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000200 PyObject_HEAD
201
202 PyObject *raw;
203 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000204 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000205 int readable;
206 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200207 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200208
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000209 /* True if this is a vanilla Buffered object (rather than a user derived
210 class) *and* the raw stream is a vanilla FileIO object. */
211 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212
213 /* Absolute position inside the raw stream (-1 if unknown). */
214 Py_off_t abs_pos;
215
216 /* A static buffer of size `buffer_size` */
217 char *buffer;
218 /* Current logical position in the buffer. */
219 Py_off_t pos;
220 /* Position of the raw stream in the buffer. */
221 Py_off_t raw_pos;
222
223 /* Just after the last buffered byte in the buffer, or -1 if the buffer
224 isn't ready for reading. */
225 Py_off_t read_end;
226
227 /* Just after the last byte actually written */
228 Py_off_t write_pos;
229 /* Just after the last byte waiting to be written, or -1 if the buffer
230 isn't ready for writing. */
231 Py_off_t write_end;
232
Georg Brandldfd73442009-04-05 11:47:34 +0000233#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000234 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200235 volatile unsigned long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000236#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000237
238 Py_ssize_t buffer_size;
239 Py_ssize_t buffer_mask;
240
241 PyObject *dict;
242 PyObject *weakreflist;
Neil Schemenauere38d12e2017-09-04 20:18:38 -0700243
244 /* a doubly-linked chained list of "buffered" objects that need to
245 be flushed when the process exits */
246 struct _buffered *next, *prev;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000247} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000248
Neil Schemenauere38d12e2017-09-04 20:18:38 -0700249/* the actual list of buffered objects */
250static buffered buffer_list_end = {
251 .next = &buffer_list_end,
252 .prev = &buffer_list_end
253};
254
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000255/*
256 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200257
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000258 * BufferedReader, BufferedWriter and BufferedRandom try to share most
259 methods (this is helped by the members `readable` and `writable`, which
260 are initialized in the respective constructors)
261 * They also share a single buffer for reading and writing. This enables
262 interleaved reads and writes without flushing. It also makes the logic
263 a bit trickier to get right.
264 * The absolute position of the raw stream is cached, if possible, in the
265 `abs_pos` member. It must be updated every time an operation is done
266 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000267 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000269 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
270 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000271
272 NOTE: we should try to maintain block alignment of reads and writes to the
273 raw stream (according to the buffer size), but for now it is only done
274 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200275
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000276*/
277
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000278/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000279
Georg Brandldfd73442009-04-05 11:47:34 +0000280#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000281
282static int
283_enter_buffered_busy(buffered *self)
284{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200285 int relax_locking;
286 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000287 if (self->owner == PyThread_get_thread_ident()) {
288 PyErr_Format(PyExc_RuntimeError,
289 "reentrant call inside %R", self);
290 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000291 }
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200292 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000293 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200294 if (!relax_locking)
295 st = PyThread_acquire_lock(self->lock, 1);
296 else {
297 /* When finalizing, we don't want a deadlock to happen with daemon
298 * threads abruptly shut down while they owned the lock.
299 * Therefore, only wait for a grace period (1 s.).
300 * Note that non-daemon threads have already exited here, so this
301 * shouldn't affect carefully written threaded I/O code.
302 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700303 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200304 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000305 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200306 if (relax_locking && st != PY_LOCK_ACQUIRED) {
307 PyObject *msgobj = PyUnicode_FromFormat(
308 "could not acquire lock for %A at interpreter "
309 "shutdown, possibly due to daemon threads",
310 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200311 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200312 Py_FatalError(msg);
313 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000314 return 1;
315}
316
317#define ENTER_BUFFERED(self) \
318 ( (PyThread_acquire_lock(self->lock, 0) ? \
319 1 : _enter_buffered_busy(self)) \
320 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000321
322#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000323 do { \
324 self->owner = 0; \
325 PyThread_release_lock(self->lock); \
326 } while(0);
327
Georg Brandldfd73442009-04-05 11:47:34 +0000328#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000329#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000330#define LEAVE_BUFFERED(self)
331#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000332
333#define CHECK_INITIALIZED(self) \
334 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000335 if (self->detached) { \
336 PyErr_SetString(PyExc_ValueError, \
337 "raw stream has been detached"); \
338 } else { \
339 PyErr_SetString(PyExc_ValueError, \
340 "I/O operation on uninitialized object"); \
341 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000342 return NULL; \
343 }
344
345#define CHECK_INITIALIZED_INT(self) \
346 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000347 if (self->detached) { \
348 PyErr_SetString(PyExc_ValueError, \
349 "raw stream has been detached"); \
350 } else { \
351 PyErr_SetString(PyExc_ValueError, \
352 "I/O operation on uninitialized object"); \
353 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354 return -1; \
355 }
356
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000357#define IS_CLOSED(self) \
358 (self->fast_closed_checks \
359 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000360 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000361
362#define CHECK_CLOSED(self, error_msg) \
363 if (IS_CLOSED(self)) { \
364 PyErr_SetString(PyExc_ValueError, error_msg); \
365 return NULL; \
366 }
367
368
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000369#define VALID_READ_BUFFER(self) \
370 (self->readable && self->read_end != -1)
371
372#define VALID_WRITE_BUFFER(self) \
373 (self->writable && self->write_end != -1)
374
375#define ADJUST_POSITION(self, _new_pos) \
376 do { \
377 self->pos = _new_pos; \
378 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
379 self->read_end = self->pos; \
380 } while(0)
381
382#define READAHEAD(self) \
383 ((self->readable && VALID_READ_BUFFER(self)) \
384 ? (self->read_end - self->pos) : 0)
385
386#define RAW_OFFSET(self) \
387 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
388 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
389
390#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000391 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000392
393#define MINUS_LAST_BLOCK(self, size) \
394 (self->buffer_mask ? \
395 (size & ~self->buffer_mask) : \
396 (self->buffer_size * (size / self->buffer_size)))
397
398
399static void
Neil Schemenauere38d12e2017-09-04 20:18:38 -0700400remove_from_linked_list(buffered *self)
401{
402 self->next->prev = self->prev;
403 self->prev->next = self->next;
404 self->prev = NULL;
405 self->next = NULL;
406}
407
408static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000409buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000410{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200411 self->finalizing = 1;
412 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000413 return;
414 _PyObject_GC_UNTRACK(self);
415 self->ok = 0;
Neil Schemenauere38d12e2017-09-04 20:18:38 -0700416 if (self->next != NULL)
417 remove_from_linked_list(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000418 if (self->weakreflist != NULL)
419 PyObject_ClearWeakRefs((PyObject *)self);
420 Py_CLEAR(self->raw);
421 if (self->buffer) {
422 PyMem_Free(self->buffer);
423 self->buffer = NULL;
424 }
Georg Brandldfd73442009-04-05 11:47:34 +0000425#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000426 if (self->lock) {
427 PyThread_free_lock(self->lock);
428 self->lock = NULL;
429 }
Georg Brandldfd73442009-04-05 11:47:34 +0000430#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000431 Py_CLEAR(self->dict);
432 Py_TYPE(self)->tp_free((PyObject *)self);
433}
434
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200435static PyObject *
436buffered_sizeof(buffered *self, void *unused)
437{
438 Py_ssize_t res;
439
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200440 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200441 if (self->buffer)
442 res += self->buffer_size;
443 return PyLong_FromSsize_t(res);
444}
445
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000446static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000447buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000448{
449 Py_VISIT(self->raw);
450 Py_VISIT(self->dict);
451 return 0;
452}
453
454static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000455buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000457 self->ok = 0;
458 Py_CLEAR(self->raw);
459 Py_CLEAR(self->dict);
460 return 0;
461}
462
Antoine Pitroue033e062010-10-29 10:38:18 +0000463/* Because this can call arbitrary code, it shouldn't be called when
464 the refcount is 0 (that is, not directly from tp_dealloc unless
465 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000466static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000467buffered_dealloc_warn(buffered *self, PyObject *source)
468{
469 if (self->ok && self->raw) {
470 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100471 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
472 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000473 if (r)
474 Py_DECREF(r);
475 else
476 PyErr_Clear();
477 }
478 Py_RETURN_NONE;
479}
480
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481/*
482 * _BufferedIOMixin methods
483 * This is not a class, just a collection of methods that will be reused
484 * by BufferedReader and BufferedWriter
485 */
486
487/* Flush and close */
488
489static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000490buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491{
492 CHECK_INITIALIZED(self)
493 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
494}
495
496static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498{
499 int closed;
500 PyObject *res;
501 CHECK_INITIALIZED_INT(self)
502 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
503 if (res == NULL)
504 return -1;
505 closed = PyObject_IsTrue(res);
506 Py_DECREF(res);
507 return closed;
508}
509
510static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000511buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512{
513 CHECK_INITIALIZED(self)
514 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
515}
516
517static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000518buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519{
Benjamin Peterson68623612012-12-20 11:53:11 -0600520 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000521 int r;
522
523 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000524 if (!ENTER_BUFFERED(self))
525 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000526
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000527 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000528 if (r < 0)
529 goto end;
530 if (r > 0) {
531 res = Py_None;
532 Py_INCREF(res);
533 goto end;
534 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000535
Antoine Pitrou796564c2013-07-30 19:59:21 +0200536 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000537 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
538 if (r)
539 Py_DECREF(r);
540 else
541 PyErr_Clear();
542 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543 /* flush() will most probably re-take the lock, so drop it first */
544 LEAVE_BUFFERED(self)
545 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000546 if (!ENTER_BUFFERED(self))
547 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600548 if (res == NULL)
549 PyErr_Fetch(&exc, &val, &tb);
550 else
551 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000552
553 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
554
Jesus Ceadc469452012-10-04 12:37:56 +0200555 if (self->buffer) {
556 PyMem_Free(self->buffer);
557 self->buffer = NULL;
558 }
559
Benjamin Peterson68623612012-12-20 11:53:11 -0600560 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300561 _PyErr_ChainExceptions(exc, val, tb);
562 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600563 }
564
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565end:
566 LEAVE_BUFFERED(self)
567 return res;
568}
569
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000570/* detach */
571
572static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000573buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000574{
575 PyObject *raw, *res;
576 CHECK_INITIALIZED(self)
577 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
578 if (res == NULL)
579 return NULL;
580 Py_DECREF(res);
581 raw = self->raw;
582 self->raw = NULL;
583 self->detached = 1;
584 self->ok = 0;
585 return raw;
586}
587
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000588/* Inquiries */
589
590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000591buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
594 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
595}
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
601 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
602}
603
604static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
608 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
609}
610
611static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000612buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000613{
614 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200615 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616}
617
618static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000619buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620{
621 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200622 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623}
624
625/* Lower-level APIs */
626
627static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000628buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629{
630 CHECK_INITIALIZED(self)
631 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
632}
633
634static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000635buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000636{
637 CHECK_INITIALIZED(self)
638 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
639}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000640
Antoine Pitrou243757e2010-11-05 21:15:39 +0000641/* Serialization */
642
643static PyObject *
644buffered_getstate(buffered *self, PyObject *args)
645{
646 PyErr_Format(PyExc_TypeError,
647 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
648 return NULL;
649}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000650
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651/* Forward decls */
652static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100653_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000655_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000657_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000659_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200661_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000663_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000664static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000665_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000666static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000667_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200668static Py_ssize_t
669_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670
671/*
672 * Helpers
673 */
674
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100675/* Sets the current error to BlockingIOError */
676static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200677_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100678{
679 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200680 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100681 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
682 errno, msg, written);
683 if (err)
684 PyErr_SetObject(PyExc_BlockingIOError, err);
685 Py_XDECREF(err);
686}
687
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688/* Returns the address of the `written` member if a BlockingIOError was
689 raised, NULL otherwise. The error is always re-raised. */
690static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000691_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692{
693 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200694 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695
696 PyErr_Fetch(&t, &v, &tb);
697 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
698 PyErr_Restore(t, v, tb);
699 return NULL;
700 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200701 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 /* TODO: sanity check (err->written >= 0) */
703 PyErr_Restore(t, v, tb);
704 return &err->written;
705}
706
707static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000708_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000711 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
713 if (res == NULL)
714 return -1;
715 n = PyNumber_AsOff_t(res, PyExc_ValueError);
716 Py_DECREF(res);
717 if (n < 0) {
718 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300719 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000720 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200721 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000722 return -1;
723 }
724 self->abs_pos = n;
725 return n;
726}
727
728static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000729_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000730{
731 PyObject *res, *posobj, *whenceobj;
732 Py_off_t n;
733
734 posobj = PyLong_FromOff_t(target);
735 if (posobj == NULL)
736 return -1;
737 whenceobj = PyLong_FromLong(whence);
738 if (whenceobj == NULL) {
739 Py_DECREF(posobj);
740 return -1;
741 }
742 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
743 posobj, whenceobj, NULL);
744 Py_DECREF(posobj);
745 Py_DECREF(whenceobj);
746 if (res == NULL)
747 return -1;
748 n = PyNumber_AsOff_t(res, PyExc_ValueError);
749 Py_DECREF(res);
750 if (n < 0) {
751 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300752 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000753 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200754 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000755 return -1;
756 }
757 self->abs_pos = n;
758 return n;
759}
760
761static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000762_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000763{
764 Py_ssize_t n;
765 if (self->buffer_size <= 0) {
766 PyErr_SetString(PyExc_ValueError,
767 "buffer size must be strictly positive");
768 return -1;
769 }
770 if (self->buffer)
771 PyMem_Free(self->buffer);
772 self->buffer = PyMem_Malloc(self->buffer_size);
773 if (self->buffer == NULL) {
774 PyErr_NoMemory();
775 return -1;
776 }
Georg Brandldfd73442009-04-05 11:47:34 +0000777#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000778 if (self->lock)
779 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000780 self->lock = PyThread_allocate_lock();
781 if (self->lock == NULL) {
782 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
783 return -1;
784 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000785 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000786#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000787 /* Find out whether buffer_size is a power of 2 */
788 /* XXX is this optimization useful? */
789 for (n = self->buffer_size - 1; n & 1; n >>= 1)
790 ;
791 if (n == 0)
792 self->buffer_mask = self->buffer_size - 1;
793 else
794 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000795 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000796 PyErr_Clear();
797 return 0;
798}
799
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300800/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000801 clears the error indicator), 0 otherwise.
802 Should only be called when PyErr_Occurred() is true.
803*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700804int
805_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000806{
807 static PyObject *eintr_int = NULL;
808 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300809 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000810
811 if (eintr_int == NULL) {
812 eintr_int = PyLong_FromLong(EINTR);
813 assert(eintr_int != NULL);
814 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300815 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000816 return 0;
817 PyErr_Fetch(&typ, &val, &tb);
818 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300819 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000820 assert(env_err != NULL);
821 if (env_err->myerrno != NULL &&
822 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
823 Py_DECREF(typ);
824 Py_DECREF(val);
825 Py_XDECREF(tb);
826 return 1;
827 }
828 /* This silences any error set by PyObject_RichCompareBool() */
829 PyErr_Restore(typ, val, tb);
830 return 0;
831}
832
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833/*
834 * Shared methods and wrappers
835 */
836
837static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200838buffered_flush_and_rewind_unlocked(buffered *self)
839{
840 PyObject *res;
841
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100842 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200843 if (res == NULL)
844 return NULL;
845 Py_DECREF(res);
846
847 if (self->readable) {
848 /* Rewind the raw stream so that its position corresponds to
849 the current logical position. */
850 Py_off_t n;
851 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
852 _bufferedreader_reset_buf(self);
853 if (n == -1)
854 return NULL;
855 }
856 Py_RETURN_NONE;
857}
858
859static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000860buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000861{
862 PyObject *res;
863
864 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000865 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000866
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000867 if (!ENTER_BUFFERED(self))
868 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200869 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000870 LEAVE_BUFFERED(self)
871
872 return res;
873}
874
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300875/*[clinic input]
876_io._Buffered.peek
877 size: Py_ssize_t = 0
878 /
879
880[clinic start generated code]*/
881
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300883_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
884/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886 PyObject *res = NULL;
887
888 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300889 CHECK_CLOSED(self, "peek of closed file")
890
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000891 if (!ENTER_BUFFERED(self))
892 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000893
894 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200895 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896 if (res == NULL)
897 goto end;
898 Py_CLEAR(res);
899 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200900 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901
902end:
903 LEAVE_BUFFERED(self)
904 return res;
905}
906
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300907/*[clinic input]
908_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300909 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300910 /
911[clinic start generated code]*/
912
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300914_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300915/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000916{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000917 PyObject *res;
918
919 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920 if (n < -1) {
921 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000922 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923 return NULL;
924 }
925
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000926 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000928 if (n == -1) {
929 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000930 if (!ENTER_BUFFERED(self))
931 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000932 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000933 }
934 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000935 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200936 if (res != Py_None)
937 return res;
938 Py_DECREF(res);
939 if (!ENTER_BUFFERED(self))
940 return NULL;
941 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000942 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943
Antoine Pitroue05565e2011-08-20 14:39:23 +0200944 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945 return res;
946}
947
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300948/*[clinic input]
949_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000950 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300951 /
952[clinic start generated code]*/
953
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300955_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000956/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300958 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 PyObject *res = NULL;
960
961 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000963 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000964 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300965
966 CHECK_CLOSED(self, "read of closed file")
967
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 if (n == 0)
969 return PyBytes_FromStringAndSize(NULL, 0);
970
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000971 /* Return up to n bytes. If at least one byte is buffered, we
972 only return buffered bytes. Otherwise, we do one raw read. */
973
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000974 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
975 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100976 n = Py_MIN(have, n);
977 res = _bufferedreader_read_fast(self, n);
978 assert(res != Py_None);
979 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100981 res = PyBytes_FromStringAndSize(NULL, n);
982 if (res == NULL)
983 return NULL;
984 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200985 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100986 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200987 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000988 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100989 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
990 LEAVE_BUFFERED(self)
991 if (r == -1) {
992 Py_DECREF(res);
993 return NULL;
994 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995 if (r == -2)
996 r = 0;
997 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100998 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000999 return res;
1000}
1001
1002static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001003_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001004{
Antoine Pitrou3486a982011-05-12 01:57:53 +02001005 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001006 PyObject *res = NULL;
1007
1008 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +02001009
Antoine Pitrou3486a982011-05-12 01:57:53 +02001010 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1011 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001012 if (n >= buffer->len) {
1013 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1014 self->pos += buffer->len;
1015 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001017 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001018 self->pos += n;
1019 written = n;
1020 }
1021
1022 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001023 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001024
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001025 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001026 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001027 if (res == NULL)
1028 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001029 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001030 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001031
1032 _bufferedreader_reset_buf(self);
1033 self->pos = 0;
1034
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001035 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001036 remaining > 0;
1037 written += n, remaining -= n) {
1038 /* If remaining bytes is larger than internal buffer size, copy
1039 * directly into caller's buffer. */
1040 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001041 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001042 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001043 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001044
1045 /* In readinto1 mode, we do not want to fill the internal
1046 buffer if we already have some data to return */
1047 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001048 n = _bufferedreader_fill_buffer(self);
1049 if (n > 0) {
1050 if (n > remaining)
1051 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001052 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001053 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001054 self->pos += n;
1055 continue; /* short circuit */
1056 }
1057 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001058 else
1059 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001060
Antoine Pitrou3486a982011-05-12 01:57:53 +02001061 if (n == 0 || (n == -2 && written > 0))
1062 break;
1063 if (n < 0) {
1064 if (n == -2) {
1065 Py_INCREF(Py_None);
1066 res = Py_None;
1067 }
1068 goto end;
1069 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001070
Benjamin Petersona96fea02014-06-22 14:17:44 -07001071 /* At most one read in readinto1 mode */
1072 if (readinto1) {
1073 written += n;
1074 break;
1075 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001076 }
1077 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001078
1079end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001080 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081 return res;
1082}
1083
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001084/*[clinic input]
1085_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001086 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001087 /
1088[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001089
1090static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001091_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001092/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001093{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001094 return _buffered_readinto_generic(self, buffer, 0);
1095}
1096
1097/*[clinic input]
1098_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001099 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001100 /
1101[clinic start generated code]*/
1102
1103static PyObject *
1104_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001105/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001106{
1107 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001108}
1109
1110
1111static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001112_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113{
1114 PyObject *res = NULL;
1115 PyObject *chunks = NULL;
1116 Py_ssize_t n, written = 0;
1117 const char *start, *s, *end;
1118
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001119 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001120
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001121 /* First, try to find a line in the buffer. This can run unlocked because
1122 the calls to the C API are simple enough that they can't trigger
1123 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001124 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1125 if (limit >= 0 && n > limit)
1126 n = limit;
1127 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001128 s = memchr(start, '\n', n);
1129 if (s != NULL) {
1130 res = PyBytes_FromStringAndSize(start, s - start + 1);
1131 if (res != NULL)
1132 self->pos += s - start + 1;
1133 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001134 }
1135 if (n == limit) {
1136 res = PyBytes_FromStringAndSize(start, n);
1137 if (res != NULL)
1138 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001139 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001140 }
1141
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001142 if (!ENTER_BUFFERED(self))
1143 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001144
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001145 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001146 chunks = PyList_New(0);
1147 if (chunks == NULL)
1148 goto end;
1149 if (n > 0) {
1150 res = PyBytes_FromStringAndSize(start, n);
1151 if (res == NULL)
1152 goto end;
1153 if (PyList_Append(chunks, res) < 0) {
1154 Py_CLEAR(res);
1155 goto end;
1156 }
1157 Py_CLEAR(res);
1158 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001159 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001160 if (limit >= 0)
1161 limit -= n;
1162 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001163 if (self->writable) {
1164 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1165 if (r == NULL)
1166 goto end;
1167 Py_DECREF(r);
1168 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001169
1170 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001171 _bufferedreader_reset_buf(self);
1172 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001173 if (n == -1)
1174 goto end;
1175 if (n <= 0)
1176 break;
1177 if (limit >= 0 && n > limit)
1178 n = limit;
1179 start = self->buffer;
1180 end = start + n;
1181 s = start;
1182 while (s < end) {
1183 if (*s++ == '\n') {
1184 res = PyBytes_FromStringAndSize(start, s - start);
1185 if (res == NULL)
1186 goto end;
1187 self->pos = s - start;
1188 goto found;
1189 }
1190 }
1191 res = PyBytes_FromStringAndSize(start, n);
1192 if (res == NULL)
1193 goto end;
1194 if (n == limit) {
1195 self->pos = n;
1196 break;
1197 }
1198 if (PyList_Append(chunks, res) < 0) {
1199 Py_CLEAR(res);
1200 goto end;
1201 }
1202 Py_CLEAR(res);
1203 written += n;
1204 if (limit >= 0)
1205 limit -= n;
1206 }
1207found:
1208 if (res != NULL && PyList_Append(chunks, res) < 0) {
1209 Py_CLEAR(res);
1210 goto end;
1211 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001212 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001213
1214end:
1215 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001216end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 Py_XDECREF(chunks);
1218 return res;
1219}
1220
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001221/*[clinic input]
1222_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001223 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001224 /
1225[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001227static PyObject *
1228_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001229/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001230{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001232 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001233}
1234
1235
1236static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001237buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001238{
1239 Py_off_t pos;
1240
1241 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001242 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 if (pos == -1)
1244 return NULL;
1245 pos -= RAW_OFFSET(self);
1246 /* TODO: sanity check (pos >= 0) */
1247 return PyLong_FromOff_t(pos);
1248}
1249
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001250/*[clinic input]
1251_io._Buffered.seek
1252 target as targetobj: object
1253 whence: int = 0
1254 /
1255[clinic start generated code]*/
1256
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001257static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001258_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1259/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260{
1261 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001262 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263
1264 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001265
1266 /* Do some error checking instead of trusting OS 'seek()'
1267 ** error detection, just in case.
1268 */
1269 if ((whence < 0 || whence >2)
1270#ifdef SEEK_HOLE
1271 && (whence != SEEK_HOLE)
1272#endif
1273#ifdef SEEK_DATA
1274 && (whence != SEEK_DATA)
1275#endif
1276 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001277 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001278 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001279 return NULL;
1280 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001281
1282 CHECK_CLOSED(self, "seek of closed file")
1283
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001284 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1285 return NULL;
1286
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001287 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1288 if (target == -1 && PyErr_Occurred())
1289 return NULL;
1290
Jesus Cea94363612012-06-22 18:32:07 +02001291 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1292 buffer. Other whence values must be managed without this optimization.
1293 Some Operating Systems can provide additional values, like
1294 SEEK_HOLE/SEEK_DATA. */
1295 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296 Py_off_t current, avail;
1297 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001298 so as to return quickly if possible. Also, we needn't take the
1299 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001301 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1302 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001303 current = RAW_TELL(self);
1304 avail = READAHEAD(self);
1305 if (avail > 0) {
1306 Py_off_t offset;
1307 if (whence == 0)
1308 offset = target - (current - RAW_OFFSET(self));
1309 else
1310 offset = target;
1311 if (offset >= -self->pos && offset <= avail) {
1312 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001313 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 }
1315 }
1316 }
1317
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001318 if (!ENTER_BUFFERED(self))
1319 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001320
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321 /* Fallback: invoke raw seek() method and clear buffer */
1322 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001323 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001324 if (res == NULL)
1325 goto end;
1326 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001327 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328 }
1329
1330 /* TODO: align on block boundary and read buffer if needed? */
1331 if (whence == 1)
1332 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001333 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001334 if (n == -1)
1335 goto end;
1336 self->raw_pos = -1;
1337 res = PyLong_FromOff_t(n);
1338 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001339 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340
1341end:
1342 LEAVE_BUFFERED(self)
1343 return res;
1344}
1345
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001346/*[clinic input]
1347_io._Buffered.truncate
1348 pos: object = None
1349 /
1350[clinic start generated code]*/
1351
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001352static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001353_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1354/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001356 PyObject *res = NULL;
1357
1358 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001359 if (!ENTER_BUFFERED(self))
1360 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361
1362 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001363 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001364 if (res == NULL)
1365 goto end;
1366 Py_CLEAR(res);
1367 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001368 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1369 if (res == NULL)
1370 goto end;
1371 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001372 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001373 PyErr_Clear();
1374
1375end:
1376 LEAVE_BUFFERED(self)
1377 return res;
1378}
1379
1380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001381buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001382{
1383 PyObject *line;
1384 PyTypeObject *tp;
1385
1386 CHECK_INITIALIZED(self);
1387
1388 tp = Py_TYPE(self);
1389 if (tp == &PyBufferedReader_Type ||
1390 tp == &PyBufferedRandom_Type) {
1391 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001392 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393 }
1394 else {
1395 line = PyObject_CallMethodObjArgs((PyObject *)self,
1396 _PyIO_str_readline, NULL);
1397 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001398 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001399 "readline() should have returned a bytes object, "
1400 "not '%.200s'", Py_TYPE(line)->tp_name);
1401 Py_DECREF(line);
1402 return NULL;
1403 }
1404 }
1405
1406 if (line == NULL)
1407 return NULL;
1408
1409 if (PyBytes_GET_SIZE(line) == 0) {
1410 /* Reached EOF or would have blocked */
1411 Py_DECREF(line);
1412 return NULL;
1413 }
1414
1415 return line;
1416}
1417
Antoine Pitrou716c4442009-05-23 19:04:03 +00001418static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001419buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001420{
1421 PyObject *nameobj, *res;
1422
Martin v. Löwis767046a2011-10-14 15:35:36 +02001423 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001424 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001425 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001426 PyErr_Clear();
1427 else
1428 return NULL;
1429 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1430 }
1431 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001432 int status = Py_ReprEnter((PyObject *)self);
1433 res = NULL;
1434 if (status == 0) {
1435 res = PyUnicode_FromFormat("<%s name=%R>",
1436 Py_TYPE(self)->tp_name, nameobj);
1437 Py_ReprLeave((PyObject *)self);
1438 }
1439 else if (status > 0) {
1440 PyErr_Format(PyExc_RuntimeError,
1441 "reentrant call inside %s.__repr__",
1442 Py_TYPE(self)->tp_name);
1443 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001444 Py_DECREF(nameobj);
1445 }
1446 return res;
1447}
1448
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001449/*
1450 * class BufferedReader
1451 */
1452
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001453static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454{
1455 self->read_end = -1;
1456}
1457
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001458/*[clinic input]
1459_io.BufferedReader.__init__
1460 raw: object
1461 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001463Create a new buffered reader using the given readable raw IO object.
1464[clinic start generated code]*/
1465
1466static int
1467_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1468 Py_ssize_t buffer_size)
1469/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1470{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001472 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001473
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001474 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001475 return -1;
1476
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001477 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001478 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 self->buffer_size = buffer_size;
1480 self->readable = 1;
1481 self->writable = 0;
1482
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001483 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001485 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001486
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001487 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1488 Py_TYPE(raw) == &PyFileIO_Type);
1489
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001490 self->ok = 1;
1491 return 0;
1492}
1493
1494static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001495_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001496{
1497 Py_buffer buf;
1498 PyObject *memobj, *res;
1499 Py_ssize_t n;
1500 /* NOTE: the buffer needn't be released as its object is NULL. */
1501 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1502 return -1;
1503 memobj = PyMemoryView_FromBuffer(&buf);
1504 if (memobj == NULL)
1505 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001506 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1507 occurs so we needn't do it ourselves.
1508 We then retry reading, ignoring the signal if no handler has
1509 raised (see issue #10956).
1510 */
1511 do {
1512 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001513 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001514 Py_DECREF(memobj);
1515 if (res == NULL)
1516 return -1;
1517 if (res == Py_None) {
1518 /* Non-blocking stream would have blocked. Special return code! */
1519 Py_DECREF(res);
1520 return -2;
1521 }
1522 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1523 Py_DECREF(res);
1524 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001525 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001526 "raw readinto() returned invalid length %zd "
1527 "(should have been between 0 and %zd)", n, len);
1528 return -1;
1529 }
1530 if (n > 0 && self->abs_pos != -1)
1531 self->abs_pos += n;
1532 return n;
1533}
1534
1535static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001536_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537{
1538 Py_ssize_t start, len, n;
1539 if (VALID_READ_BUFFER(self))
1540 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1541 else
1542 start = 0;
1543 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001544 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001545 if (n <= 0)
1546 return n;
1547 self->read_end = start + n;
1548 self->raw_pos = start + n;
1549 return n;
1550}
1551
1552static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001553_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001554{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001555 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001557
1558 /* First copy what we have in the current buffer. */
1559 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1560 if (current_size) {
1561 data = PyBytes_FromStringAndSize(
1562 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001563 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001564 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001565 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001566 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001567 /* We're going past the buffer's bounds, flush it */
1568 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 tmp = buffered_flush_and_rewind_unlocked(self);
1570 if (tmp == NULL)
1571 goto cleanup;
1572 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001573 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001574 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001575
1576 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001577 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1578 if (tmp == NULL)
1579 goto cleanup;
1580 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001581 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001582 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001583 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001584 if (tmp == Py_None) {
1585 if (current_size == 0) {
1586 res = Py_None;
1587 goto cleanup;
1588 } else {
1589 res = data;
1590 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001591 }
1592 }
1593 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001594 PyBytes_Concat(&data, tmp);
1595 res = data;
1596 goto cleanup;
1597 }
1598 else {
1599 res = tmp;
1600 goto cleanup;
1601 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001602 }
1603
1604 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001605 if (chunks == NULL)
1606 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001607
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608 while (1) {
1609 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001610 if (PyList_Append(chunks, data) < 0)
1611 goto cleanup;
1612 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001613 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001614
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001615 /* Read until EOF or until read() would block. */
1616 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001617 if (data == NULL)
1618 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001619 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001620 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001621 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001622 }
1623 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1624 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001625 res = data;
1626 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001627 }
1628 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001629 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1630 res = tmp;
1631 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001632 }
1633 }
1634 current_size += PyBytes_GET_SIZE(data);
1635 if (self->abs_pos != -1)
1636 self->abs_pos += PyBytes_GET_SIZE(data);
1637 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001638cleanup:
1639 /* res is either NULL or a borrowed ref */
1640 Py_XINCREF(res);
1641 Py_XDECREF(data);
1642 Py_XDECREF(tmp);
1643 Py_XDECREF(chunks);
1644 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001645}
1646
1647/* Read n bytes from the buffer if it can, otherwise return None.
1648 This function is simple enough that it can run unlocked. */
1649static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001650_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001651{
1652 Py_ssize_t current_size;
1653
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001654 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1655 if (n <= current_size) {
1656 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001657 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1658 if (res != NULL)
1659 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001660 return res;
1661 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001662 Py_RETURN_NONE;
1663}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001664
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001665/* Generic read function: read from the stream until enough bytes are read,
1666 * or until an EOF occurs or until read() would block.
1667 */
1668static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001669_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001670{
1671 PyObject *res = NULL;
1672 Py_ssize_t current_size, remaining, written;
1673 char *out;
1674
1675 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1676 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001677 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001678
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001679 res = PyBytes_FromStringAndSize(NULL, n);
1680 if (res == NULL)
1681 goto error;
1682 out = PyBytes_AS_STRING(res);
1683 remaining = n;
1684 written = 0;
1685 if (current_size > 0) {
1686 memcpy(out, self->buffer + self->pos, current_size);
1687 remaining -= current_size;
1688 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001689 self->pos += current_size;
1690 }
1691 /* Flush the write buffer if necessary */
1692 if (self->writable) {
1693 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1694 if (r == NULL)
1695 goto error;
1696 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001697 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001698 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001699 while (remaining > 0) {
1700 /* We want to read a whole block at the end into buffer.
1701 If we had readv() we could do this in one pass. */
1702 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1703 if (r == 0)
1704 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 if (r == -1)
1707 goto error;
1708 if (r == 0 || r == -2) {
1709 /* EOF occurred or read() would block. */
1710 if (r == 0 || written > 0) {
1711 if (_PyBytes_Resize(&res, written))
1712 goto error;
1713 return res;
1714 }
1715 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001716 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001717 }
1718 remaining -= r;
1719 written += r;
1720 }
1721 assert(remaining <= self->buffer_size);
1722 self->pos = 0;
1723 self->raw_pos = 0;
1724 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001725 /* NOTE: when the read is satisfied, we avoid issuing any additional
1726 reads, which could block indefinitely (e.g. on a socket).
1727 See issue #9550. */
1728 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001729 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001730 if (r == -1)
1731 goto error;
1732 if (r == 0 || r == -2) {
1733 /* EOF occurred or read() would block. */
1734 if (r == 0 || written > 0) {
1735 if (_PyBytes_Resize(&res, written))
1736 goto error;
1737 return res;
1738 }
1739 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001740 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001741 }
1742 if (remaining > r) {
1743 memcpy(out + written, self->buffer + self->pos, r);
1744 written += r;
1745 self->pos += r;
1746 remaining -= r;
1747 }
1748 else if (remaining > 0) {
1749 memcpy(out + written, self->buffer + self->pos, remaining);
1750 written += remaining;
1751 self->pos += remaining;
1752 remaining = 0;
1753 }
1754 if (remaining == 0)
1755 break;
1756 }
1757
1758 return res;
1759
1760error:
1761 Py_XDECREF(res);
1762 return NULL;
1763}
1764
1765static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001766_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767{
1768 Py_ssize_t have, r;
1769
1770 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1771 /* Constraints:
1772 1. we don't want to advance the file position.
1773 2. we don't want to lose block alignment, so we can't shift the buffer
1774 to make some place.
1775 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1776 */
1777 if (have > 0) {
1778 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1779 }
1780
1781 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001782 _bufferedreader_reset_buf(self);
1783 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 if (r == -1)
1785 return NULL;
1786 if (r == -2)
1787 r = 0;
1788 self->pos = 0;
1789 return PyBytes_FromStringAndSize(self->buffer, r);
1790}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791
1792
Benjamin Peterson59406a92009-03-26 17:10:29 +00001793
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794/*
1795 * class BufferedWriter
1796 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001798_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799{
1800 self->write_pos = 0;
1801 self->write_end = -1;
1802}
1803
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001804/*[clinic input]
1805_io.BufferedWriter.__init__
1806 raw: object
1807 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001808
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001809A buffer for a writeable sequential RawIO object.
1810
1811The constructor creates a BufferedWriter for the given writeable raw
1812stream. If the buffer_size is not given, it defaults to
1813DEFAULT_BUFFER_SIZE.
1814[clinic start generated code]*/
1815
1816static int
1817_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1818 Py_ssize_t buffer_size)
1819/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1820{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001821 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001822 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 return -1;
1826
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001828 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001829 self->readable = 0;
1830 self->writable = 1;
1831
1832 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001833 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001835 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 self->pos = 0;
1837
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001838 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1839 Py_TYPE(raw) == &PyFileIO_Type);
1840
Neil Schemenauere38d12e2017-09-04 20:18:38 -07001841 if (self->next == NULL) {
1842 self->prev = &buffer_list_end;
1843 self->next = buffer_list_end.next;
1844 buffer_list_end.next->prev = self;
1845 buffer_list_end.next = self;
1846 }
1847
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001848 self->ok = 1;
1849 return 0;
1850}
1851
Neil Schemenauere38d12e2017-09-04 20:18:38 -07001852/*
1853* Ensure all buffered writers are flushed before proceeding with
1854* normal shutdown. Otherwise, if the underlying file objects get
1855* finalized before the buffered writer wrapping it then any buffered
1856* data will be lost.
1857*/
1858void _PyIO_atexit_flush(void)
1859{
1860 while (buffer_list_end.next != &buffer_list_end) {
1861 buffered *buf = buffer_list_end.next;
1862 remove_from_linked_list(buf);
1863 buffered_flush(buf, NULL);
1864 PyErr_Clear();
1865 }
1866}
1867
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001868static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001869_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001870{
1871 Py_buffer buf;
1872 PyObject *memobj, *res;
1873 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001874 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875 /* NOTE: the buffer needn't be released as its object is NULL. */
1876 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1877 return -1;
1878 memobj = PyMemoryView_FromBuffer(&buf);
1879 if (memobj == NULL)
1880 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001881 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1882 occurs so we needn't do it ourselves.
1883 We then retry writing, ignoring the signal if no handler has
1884 raised (see issue #10956).
1885 */
1886 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001887 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001888 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001889 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001890 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001891 Py_DECREF(memobj);
1892 if (res == NULL)
1893 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001894 if (res == Py_None) {
1895 /* Non-blocking stream would have blocked. Special return code!
1896 Being paranoid we reset errno in case it is changed by code
1897 triggered by a decref. errno is used by _set_BlockingIOError(). */
1898 Py_DECREF(res);
1899 errno = errnum;
1900 return -2;
1901 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001902 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1903 Py_DECREF(res);
1904 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001905 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001906 "raw write() returned invalid length %zd "
1907 "(should have been between 0 and %zd)", n, len);
1908 return -1;
1909 }
1910 if (n > 0 && self->abs_pos != -1)
1911 self->abs_pos += n;
1912 return n;
1913}
1914
1915/* `restore_pos` is 1 if we need to restore the raw stream position at
1916 the end, 0 otherwise. */
1917static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001918_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001919{
1920 Py_ssize_t written = 0;
1921 Py_off_t n, rewind;
1922
1923 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1924 goto end;
1925 /* First, rewind */
1926 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1927 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001928 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929 if (n < 0) {
1930 goto error;
1931 }
1932 self->raw_pos -= rewind;
1933 }
1934 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001935 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936 self->buffer + self->write_pos,
1937 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1938 Py_off_t, Py_ssize_t));
1939 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001940 goto error;
1941 }
1942 else if (n == -2) {
1943 _set_BlockingIOError("write could not complete without blocking",
1944 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945 goto error;
1946 }
1947 self->write_pos += n;
1948 self->raw_pos = self->write_pos;
1949 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001950 /* Partial writes can return successfully when interrupted by a
1951 signal (see write(2)). We must run signal handlers before
1952 blocking another time, possibly indefinitely. */
1953 if (PyErr_CheckSignals() < 0)
1954 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955 }
1956
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001957 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958
1959end:
1960 Py_RETURN_NONE;
1961
1962error:
1963 return NULL;
1964}
1965
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001966/*[clinic input]
1967_io.BufferedWriter.write
1968 buffer: Py_buffer
1969 /
1970[clinic start generated code]*/
1971
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001973_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1974/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001975{
1976 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001977 Py_ssize_t written, avail, remaining;
1978 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001979
1980 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001981 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983 return NULL;
1984 }
1985
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001986 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001987 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988
1989 /* Fast path: the data to write can be fully buffered. */
1990 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1991 self->pos = 0;
1992 self->raw_pos = 0;
1993 }
1994 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001995 if (buffer->len <= avail) {
1996 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001997 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998 self->write_pos = self->pos;
1999 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002000 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 if (self->pos > self->write_end)
2002 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002003 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 goto end;
2005 }
2006
2007 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002008 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002009 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002010 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002011 if (w == NULL)
2012 goto error;
2013 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002014 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 /* Make some place by shifting the buffer. */
2016 assert(VALID_WRITE_BUFFER(self));
2017 memmove(self->buffer, self->buffer + self->write_pos,
2018 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2019 Py_off_t, Py_ssize_t));
2020 self->write_end -= self->write_pos;
2021 self->raw_pos -= self->write_pos;
2022 self->pos -= self->write_pos;
2023 self->write_pos = 0;
2024 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2025 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002026 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002027 /* Everything can be buffered */
2028 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002029 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
2030 self->write_end += buffer->len;
2031 self->pos += buffer->len;
2032 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033 goto end;
2034 }
2035 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002036 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002038 self->pos += avail;
2039 /* XXX Modifying the existing exception e using the pointer w
2040 will change e.characters_written but not e.args[2].
2041 Therefore we just replace with a new error. */
2042 _set_BlockingIOError("write could not complete without blocking",
2043 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002044 goto error;
2045 }
2046 Py_CLEAR(res);
2047
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002048 /* Adjust the raw stream position if it is away from the logical stream
2049 position. This happens if the read buffer has been filled but not
2050 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2051 the raw stream by itself).
2052 Fixes issue #6629.
2053 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002054 offset = RAW_OFFSET(self);
2055 if (offset != 0) {
2056 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002057 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002058 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002059 }
2060
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002062 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002063 written = 0;
2064 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002065 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002066 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002067 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002068 goto error;
2069 } else if (n == -2) {
2070 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071 if (remaining > self->buffer_size) {
2072 /* Can't buffer everything, still buffer as much as possible */
2073 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002074 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075 self->raw_pos = 0;
2076 ADJUST_POSITION(self, self->buffer_size);
2077 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002078 written += self->buffer_size;
2079 _set_BlockingIOError("write could not complete without "
2080 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081 goto error;
2082 }
2083 PyErr_Clear();
2084 break;
2085 }
2086 written += n;
2087 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002088 /* Partial writes can return successfully when interrupted by a
2089 signal (see write(2)). We must run signal handlers before
2090 blocking another time, possibly indefinitely. */
2091 if (PyErr_CheckSignals() < 0)
2092 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002093 }
2094 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002095 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002097 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098 written += remaining;
2099 }
2100 self->write_pos = 0;
2101 /* TODO: sanity check (remaining >= 0) */
2102 self->write_end = remaining;
2103 ADJUST_POSITION(self, remaining);
2104 self->raw_pos = 0;
2105
2106end:
2107 res = PyLong_FromSsize_t(written);
2108
2109error:
2110 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 return res;
2112}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113
2114
2115
2116/*
2117 * BufferedRWPair
2118 */
2119
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002120/* XXX The usefulness of this (compared to having two separate IO objects) is
2121 * questionable.
2122 */
2123
2124typedef struct {
2125 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126 buffered *reader;
2127 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128 PyObject *dict;
2129 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002130} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002132/*[clinic input]
2133_io.BufferedRWPair.__init__
2134 reader: object
2135 writer: object
2136 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2137 /
2138
2139A buffered reader and writer object together.
2140
2141A buffered reader object and buffered writer object put together to
2142form a sequential IO object that can read and write. This is typically
2143used with a socket or two-way pipe.
2144
2145reader and writer are RawIOBase objects that are readable and
2146writeable respectively. If the buffer_size is omitted it defaults to
2147DEFAULT_BUFFER_SIZE.
2148[clinic start generated code]*/
2149
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002151_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2152 PyObject *writer, Py_ssize_t buffer_size)
2153/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002155 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002157 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002158 return -1;
2159
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002160 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002161 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002162 if (self->reader == NULL)
2163 return -1;
2164
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002166 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002167 if (self->writer == NULL) {
2168 Py_CLEAR(self->reader);
2169 return -1;
2170 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002171
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172 return 0;
2173}
2174
2175static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002176bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177{
2178 Py_VISIT(self->dict);
2179 return 0;
2180}
2181
2182static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002183bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184{
2185 Py_CLEAR(self->reader);
2186 Py_CLEAR(self->writer);
2187 Py_CLEAR(self->dict);
2188 return 0;
2189}
2190
2191static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193{
2194 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002195 if (self->weakreflist != NULL)
2196 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197 Py_CLEAR(self->reader);
2198 Py_CLEAR(self->writer);
2199 Py_CLEAR(self->dict);
2200 Py_TYPE(self)->tp_free((PyObject *) self);
2201}
2202
2203static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002204_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002206 PyObject *func, *ret;
2207 if (self == NULL) {
2208 PyErr_SetString(PyExc_ValueError,
2209 "I/O operation on uninitialized object");
2210 return NULL;
2211 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002212
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002213 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002215 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216 return NULL;
2217 }
2218
2219 ret = PyObject_CallObject(func, args);
2220 Py_DECREF(func);
2221 return ret;
2222}
2223
2224static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002225bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002227 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002228}
2229
2230static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002231bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002233 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234}
2235
2236static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002237bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002239 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240}
2241
2242static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002243bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002244{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002245 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002246}
2247
2248static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002249bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2250{
2251 return _forward_call(self->reader, &PyId_readinto1, args);
2252}
2253
2254static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002255bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002256{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002257 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002258}
2259
2260static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002261bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002263 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002264}
2265
2266static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002267bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002268{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002269 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270}
2271
2272static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002273bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002274{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002275 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276}
2277
2278static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002279bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002280{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002281 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002282 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002283 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002284 PyErr_Fetch(&exc, &val, &tb);
2285 else
2286 Py_DECREF(ret);
2287 ret = _forward_call(self->reader, &PyId_close, args);
2288 if (exc != NULL) {
2289 _PyErr_ChainExceptions(exc, val, tb);
2290 Py_CLEAR(ret);
2291 }
2292 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293}
2294
2295static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002296bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002298 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002299
2300 if (ret != Py_False) {
2301 /* either True or exception */
2302 return ret;
2303 }
2304 Py_DECREF(ret);
2305
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002306 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307}
2308
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002309static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002310bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002311{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002312 if (self->writer == NULL) {
2313 PyErr_SetString(PyExc_RuntimeError,
2314 "the BufferedRWPair object is being garbage-collected");
2315 return NULL;
2316 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002317 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2318}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002319
2320
2321
2322/*
2323 * BufferedRandom
2324 */
2325
2326/*[clinic input]
2327_io.BufferedRandom.__init__
2328 raw: object
2329 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2330
2331A buffered interface to random access streams.
2332
2333The constructor creates a reader and writer for a seekable stream,
2334raw, given in the first argument. If the buffer_size is omitted it
2335defaults to DEFAULT_BUFFER_SIZE.
2336[clinic start generated code]*/
2337
2338static int
2339_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2340 Py_ssize_t buffer_size)
2341/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2342{
2343 self->ok = 0;
2344 self->detached = 0;
2345
2346 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2347 return -1;
2348 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2349 return -1;
2350 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2351 return -1;
2352
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002353 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002354 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002355 self->buffer_size = buffer_size;
2356 self->readable = 1;
2357 self->writable = 1;
2358
2359 if (_buffered_init(self) < 0)
2360 return -1;
2361 _bufferedreader_reset_buf(self);
2362 _bufferedwriter_reset_buf(self);
2363 self->pos = 0;
2364
2365 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2366 Py_TYPE(raw) == &PyFileIO_Type);
2367
2368 self->ok = 1;
2369 return 0;
2370}
2371
2372#include "clinic/bufferedio.c.h"
2373
2374
2375static PyMethodDef bufferediobase_methods[] = {
2376 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2377 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2378 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2379 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2380 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2381 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2382 {NULL, NULL}
2383};
2384
2385PyTypeObject PyBufferedIOBase_Type = {
2386 PyVarObject_HEAD_INIT(NULL, 0)
2387 "_io._BufferedIOBase", /*tp_name*/
2388 0, /*tp_basicsize*/
2389 0, /*tp_itemsize*/
2390 0, /*tp_dealloc*/
2391 0, /*tp_print*/
2392 0, /*tp_getattr*/
2393 0, /*tp_setattr*/
2394 0, /*tp_compare */
2395 0, /*tp_repr*/
2396 0, /*tp_as_number*/
2397 0, /*tp_as_sequence*/
2398 0, /*tp_as_mapping*/
2399 0, /*tp_hash */
2400 0, /*tp_call*/
2401 0, /*tp_str*/
2402 0, /*tp_getattro*/
2403 0, /*tp_setattro*/
2404 0, /*tp_as_buffer*/
2405 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2406 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2407 bufferediobase_doc, /* tp_doc */
2408 0, /* tp_traverse */
2409 0, /* tp_clear */
2410 0, /* tp_richcompare */
2411 0, /* tp_weaklistoffset */
2412 0, /* tp_iter */
2413 0, /* tp_iternext */
2414 bufferediobase_methods, /* tp_methods */
2415 0, /* tp_members */
2416 0, /* tp_getset */
2417 &PyIOBase_Type, /* tp_base */
2418 0, /* tp_dict */
2419 0, /* tp_descr_get */
2420 0, /* tp_descr_set */
2421 0, /* tp_dictoffset */
2422 0, /* tp_init */
2423 0, /* tp_alloc */
2424 0, /* tp_new */
2425 0, /* tp_free */
2426 0, /* tp_is_gc */
2427 0, /* tp_bases */
2428 0, /* tp_mro */
2429 0, /* tp_cache */
2430 0, /* tp_subclasses */
2431 0, /* tp_weaklist */
2432 0, /* tp_del */
2433 0, /* tp_version_tag */
2434 0, /* tp_finalize */
2435};
2436
2437
2438static PyMethodDef bufferedreader_methods[] = {
2439 /* BufferedIOMixin methods */
2440 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2441 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2442 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2443 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2444 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002445 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2446 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2447 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2448 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2449
2450 _IO__BUFFERED_READ_METHODDEF
2451 _IO__BUFFERED_PEEK_METHODDEF
2452 _IO__BUFFERED_READ1_METHODDEF
2453 _IO__BUFFERED_READINTO_METHODDEF
2454 _IO__BUFFERED_READINTO1_METHODDEF
2455 _IO__BUFFERED_READLINE_METHODDEF
2456 _IO__BUFFERED_SEEK_METHODDEF
2457 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2458 _IO__BUFFERED_TRUNCATE_METHODDEF
2459 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2460 {NULL, NULL}
2461};
2462
2463static PyMemberDef bufferedreader_members[] = {
2464 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2465 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2466 {NULL}
2467};
2468
2469static PyGetSetDef bufferedreader_getset[] = {
2470 {"closed", (getter)buffered_closed_get, NULL, NULL},
2471 {"name", (getter)buffered_name_get, NULL, NULL},
2472 {"mode", (getter)buffered_mode_get, NULL, NULL},
2473 {NULL}
2474};
2475
2476
2477PyTypeObject PyBufferedReader_Type = {
2478 PyVarObject_HEAD_INIT(NULL, 0)
2479 "_io.BufferedReader", /*tp_name*/
2480 sizeof(buffered), /*tp_basicsize*/
2481 0, /*tp_itemsize*/
2482 (destructor)buffered_dealloc, /*tp_dealloc*/
2483 0, /*tp_print*/
2484 0, /*tp_getattr*/
2485 0, /*tp_setattr*/
2486 0, /*tp_compare */
2487 (reprfunc)buffered_repr, /*tp_repr*/
2488 0, /*tp_as_number*/
2489 0, /*tp_as_sequence*/
2490 0, /*tp_as_mapping*/
2491 0, /*tp_hash */
2492 0, /*tp_call*/
2493 0, /*tp_str*/
2494 0, /*tp_getattro*/
2495 0, /*tp_setattro*/
2496 0, /*tp_as_buffer*/
2497 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2498 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2499 _io_BufferedReader___init____doc__, /* tp_doc */
2500 (traverseproc)buffered_traverse, /* tp_traverse */
2501 (inquiry)buffered_clear, /* tp_clear */
2502 0, /* tp_richcompare */
2503 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2504 0, /* tp_iter */
2505 (iternextfunc)buffered_iternext, /* tp_iternext */
2506 bufferedreader_methods, /* tp_methods */
2507 bufferedreader_members, /* tp_members */
2508 bufferedreader_getset, /* tp_getset */
2509 0, /* tp_base */
2510 0, /* tp_dict */
2511 0, /* tp_descr_get */
2512 0, /* tp_descr_set */
2513 offsetof(buffered, dict), /* tp_dictoffset */
2514 _io_BufferedReader___init__, /* tp_init */
2515 0, /* tp_alloc */
2516 PyType_GenericNew, /* tp_new */
2517 0, /* tp_free */
2518 0, /* tp_is_gc */
2519 0, /* tp_bases */
2520 0, /* tp_mro */
2521 0, /* tp_cache */
2522 0, /* tp_subclasses */
2523 0, /* tp_weaklist */
2524 0, /* tp_del */
2525 0, /* tp_version_tag */
2526 0, /* tp_finalize */
2527};
2528
2529
2530static PyMethodDef bufferedwriter_methods[] = {
2531 /* BufferedIOMixin methods */
2532 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2533 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2534 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002535 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2536 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2537 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2538 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2539 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2540
2541 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2542 _IO__BUFFERED_TRUNCATE_METHODDEF
2543 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2544 _IO__BUFFERED_SEEK_METHODDEF
2545 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2546 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2547 {NULL, NULL}
2548};
2549
2550static PyMemberDef bufferedwriter_members[] = {
2551 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2552 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2553 {NULL}
2554};
2555
2556static PyGetSetDef bufferedwriter_getset[] = {
2557 {"closed", (getter)buffered_closed_get, NULL, NULL},
2558 {"name", (getter)buffered_name_get, NULL, NULL},
2559 {"mode", (getter)buffered_mode_get, NULL, NULL},
2560 {NULL}
2561};
2562
2563
2564PyTypeObject PyBufferedWriter_Type = {
2565 PyVarObject_HEAD_INIT(NULL, 0)
2566 "_io.BufferedWriter", /*tp_name*/
2567 sizeof(buffered), /*tp_basicsize*/
2568 0, /*tp_itemsize*/
2569 (destructor)buffered_dealloc, /*tp_dealloc*/
2570 0, /*tp_print*/
2571 0, /*tp_getattr*/
2572 0, /*tp_setattr*/
2573 0, /*tp_compare */
2574 (reprfunc)buffered_repr, /*tp_repr*/
2575 0, /*tp_as_number*/
2576 0, /*tp_as_sequence*/
2577 0, /*tp_as_mapping*/
2578 0, /*tp_hash */
2579 0, /*tp_call*/
2580 0, /*tp_str*/
2581 0, /*tp_getattro*/
2582 0, /*tp_setattro*/
2583 0, /*tp_as_buffer*/
2584 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2585 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2586 _io_BufferedWriter___init____doc__, /* tp_doc */
2587 (traverseproc)buffered_traverse, /* tp_traverse */
2588 (inquiry)buffered_clear, /* tp_clear */
2589 0, /* tp_richcompare */
2590 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2591 0, /* tp_iter */
2592 0, /* tp_iternext */
2593 bufferedwriter_methods, /* tp_methods */
2594 bufferedwriter_members, /* tp_members */
2595 bufferedwriter_getset, /* tp_getset */
2596 0, /* tp_base */
2597 0, /* tp_dict */
2598 0, /* tp_descr_get */
2599 0, /* tp_descr_set */
2600 offsetof(buffered, dict), /* tp_dictoffset */
2601 _io_BufferedWriter___init__, /* tp_init */
2602 0, /* tp_alloc */
2603 PyType_GenericNew, /* tp_new */
2604 0, /* tp_free */
2605 0, /* tp_is_gc */
2606 0, /* tp_bases */
2607 0, /* tp_mro */
2608 0, /* tp_cache */
2609 0, /* tp_subclasses */
2610 0, /* tp_weaklist */
2611 0, /* tp_del */
2612 0, /* tp_version_tag */
2613 0, /* tp_finalize */
2614};
2615
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002617static PyMethodDef bufferedrwpair_methods[] = {
2618 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2619 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2620 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2621 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002622 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002624 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2625 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002626
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002627 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2628 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002630 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2631 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002632
Antoine Pitrou243757e2010-11-05 21:15:39 +00002633 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2634
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635 {NULL, NULL}
2636};
2637
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002638static PyGetSetDef bufferedrwpair_getset[] = {
2639 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002640 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002641};
2642
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002643PyTypeObject PyBufferedRWPair_Type = {
2644 PyVarObject_HEAD_INIT(NULL, 0)
2645 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002646 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002648 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002649 0, /*tp_print*/
2650 0, /*tp_getattr*/
2651 0, /*tp_setattr*/
2652 0, /*tp_compare */
2653 0, /*tp_repr*/
2654 0, /*tp_as_number*/
2655 0, /*tp_as_sequence*/
2656 0, /*tp_as_mapping*/
2657 0, /*tp_hash */
2658 0, /*tp_call*/
2659 0, /*tp_str*/
2660 0, /*tp_getattro*/
2661 0, /*tp_setattro*/
2662 0, /*tp_as_buffer*/
2663 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002664 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002665 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002666 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2667 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002668 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002669 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002670 0, /* tp_iter */
2671 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002672 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002673 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002674 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002675 0, /* tp_base */
2676 0, /* tp_dict */
2677 0, /* tp_descr_get */
2678 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002679 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002680 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002681 0, /* tp_alloc */
2682 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002683 0, /* tp_free */
2684 0, /* tp_is_gc */
2685 0, /* tp_bases */
2686 0, /* tp_mro */
2687 0, /* tp_cache */
2688 0, /* tp_subclasses */
2689 0, /* tp_weaklist */
2690 0, /* tp_del */
2691 0, /* tp_version_tag */
2692 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002693};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002694
2695
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002696static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002697 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002698 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2699 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2700 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2701 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2702 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2703 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2704 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002705 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002706 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002707
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002708 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002709
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002710 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002711 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002712 _IO__BUFFERED_TRUNCATE_METHODDEF
2713 _IO__BUFFERED_READ_METHODDEF
2714 _IO__BUFFERED_READ1_METHODDEF
2715 _IO__BUFFERED_READINTO_METHODDEF
2716 _IO__BUFFERED_READINTO1_METHODDEF
2717 _IO__BUFFERED_READLINE_METHODDEF
2718 _IO__BUFFERED_PEEK_METHODDEF
2719 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002720 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002721 {NULL, NULL}
2722};
2723
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002724static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002725 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002726 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002727 {NULL}
2728};
2729
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002730static PyGetSetDef bufferedrandom_getset[] = {
2731 {"closed", (getter)buffered_closed_get, NULL, NULL},
2732 {"name", (getter)buffered_name_get, NULL, NULL},
2733 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002734 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002735};
2736
2737
2738PyTypeObject PyBufferedRandom_Type = {
2739 PyVarObject_HEAD_INIT(NULL, 0)
2740 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002741 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002742 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002743 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002744 0, /*tp_print*/
2745 0, /*tp_getattr*/
2746 0, /*tp_setattr*/
2747 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002748 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002749 0, /*tp_as_number*/
2750 0, /*tp_as_sequence*/
2751 0, /*tp_as_mapping*/
2752 0, /*tp_hash */
2753 0, /*tp_call*/
2754 0, /*tp_str*/
2755 0, /*tp_getattro*/
2756 0, /*tp_setattro*/
2757 0, /*tp_as_buffer*/
2758 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002759 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002760 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002761 (traverseproc)buffered_traverse, /* tp_traverse */
2762 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002763 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002764 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002765 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002766 (iternextfunc)buffered_iternext, /* tp_iternext */
2767 bufferedrandom_methods, /* tp_methods */
2768 bufferedrandom_members, /* tp_members */
2769 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002770 0, /* tp_base */
2771 0, /*tp_dict*/
2772 0, /* tp_descr_get */
2773 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002774 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002775 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002776 0, /* tp_alloc */
2777 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002778 0, /* tp_free */
2779 0, /* tp_is_gc */
2780 0, /* tp_bases */
2781 0, /* tp_mro */
2782 0, /* tp_cache */
2783 0, /* tp_subclasses */
2784 0, /* tp_weaklist */
2785 0, /* tp_del */
2786 0, /* tp_version_tag */
2787 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002788};