blob: 2b7aaaf7c7d03ec67708c176ccabb7be05cb4e53 [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"
Eric Snow2ebc5ce2017-09-07 23:51:28 -060012#include "internal/pystate.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000013#include "structmember.h"
14#include "pythread.h"
15#include "_iomodule.h"
16
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030017/*[clinic input]
18module _io
19class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
20class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
21class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
22class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
23class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
24class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
25[clinic start generated code]*/
26/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
27
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020028_Py_IDENTIFIER(close);
29_Py_IDENTIFIER(_dealloc_warn);
30_Py_IDENTIFIER(flush);
31_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020032_Py_IDENTIFIER(mode);
33_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020034_Py_IDENTIFIER(peek);
35_Py_IDENTIFIER(read);
36_Py_IDENTIFIER(read1);
37_Py_IDENTIFIER(readable);
38_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070039_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020040_Py_IDENTIFIER(writable);
41_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020042
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000043/*
44 * BufferedIOBase class, inherits from IOBase.
45 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000046PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000047 "Base class for buffered IO objects.\n"
48 "\n"
49 "The main difference with RawIOBase is that the read() method\n"
50 "supports omitting the size argument, and does not have a default\n"
51 "implementation that defers to readinto().\n"
52 "\n"
53 "In addition, read(), readinto() and write() may raise\n"
54 "BlockingIOError if the underlying raw stream is in non-blocking\n"
55 "mode and not ready; unlike their raw counterparts, they will never\n"
56 "return None.\n"
57 "\n"
58 "A typical implementation should not inherit from a RawIOBase\n"
59 "implementation, but wrap one.\n"
60 );
61
62static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030063_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000065 Py_ssize_t len;
66 PyObject *data;
67
Benjamin Petersona96fea02014-06-22 14:17:44 -070068 data = _PyObject_CallMethodId(self,
69 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030070 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030072 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000073
74 if (!PyBytes_Check(data)) {
75 Py_DECREF(data);
76 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030077 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000078 }
79
Serhiy Storchakafff9a312017-03-21 08:53:25 +020080 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030081 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030082 PyErr_Format(PyExc_ValueError,
83 "read() returned too much data: "
84 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030085 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030086 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030087 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030088 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030089 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000091 Py_DECREF(data);
92
93 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094}
95
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030096/*[clinic input]
97_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070098 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030099 /
100[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700101
102static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300103_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700104/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700105{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300106 return _bufferediobase_readinto_generic(self, buffer, 0);
107}
108
109/*[clinic input]
110_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700111 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300112 /
113[clinic start generated code]*/
114
115static PyObject *
116_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700117/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300118{
119 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700120}
121
122static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000123bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000124{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100125 _PyIO_State *state = IO_STATE();
126 if (state != NULL)
127 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000128 return NULL;
129}
130
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300131/*[clinic input]
132_io._BufferedIOBase.detach
133
134Disconnect this buffer from its underlying raw stream and return it.
135
136After the raw stream has been detached, the buffer is in an unusable
137state.
138[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000139
140static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300141_io__BufferedIOBase_detach_impl(PyObject *self)
142/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000143{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000145}
146
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000147PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000148 "Read and return up to n bytes.\n"
149 "\n"
150 "If the argument is omitted, None, or negative, reads and\n"
151 "returns all data until EOF.\n"
152 "\n"
153 "If the argument is positive, and the underlying raw stream is\n"
154 "not 'interactive', multiple raw reads may be issued to satisfy\n"
155 "the byte count (unless EOF is reached first). But for\n"
156 "interactive raw streams (as well as sockets and pipes), at most\n"
157 "one raw read will be issued, and a short result does not imply\n"
158 "that EOF is imminent.\n"
159 "\n"
160 "Returns an empty bytes object on EOF.\n"
161 "\n"
162 "Returns None if the underlying raw stream was open in non-blocking\n"
163 "mode and no data is available at the moment.\n");
164
165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000166bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000167{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000168 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000169}
170
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000171PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000172 "Read and return up to n bytes, with at most one read() call\n"
173 "to the underlying raw stream. A short result does not imply\n"
174 "that EOF is imminent.\n"
175 "\n"
176 "Returns an empty bytes object on EOF.\n");
177
178static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000179bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000181 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000182}
183
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000184PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000185 "Write the given buffer to the IO stream.\n"
186 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000187 "Returns the number of bytes written, which is always the length of b\n"
188 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000189 "\n"
190 "Raises BlockingIOError if the buffer is full and the\n"
191 "underlying raw stream cannot accept more data at the moment.\n");
192
193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197}
198
199
Antoine Pitrou317def92017-12-13 01:39:26 +0100200typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000201 PyObject_HEAD
202
203 PyObject *raw;
204 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000205 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206 int readable;
207 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200208 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200209
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000210 /* True if this is a vanilla Buffered object (rather than a user derived
211 class) *and* the raw stream is a vanilla FileIO object. */
212 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213
214 /* Absolute position inside the raw stream (-1 if unknown). */
215 Py_off_t abs_pos;
216
217 /* A static buffer of size `buffer_size` */
218 char *buffer;
219 /* Current logical position in the buffer. */
220 Py_off_t pos;
221 /* Position of the raw stream in the buffer. */
222 Py_off_t raw_pos;
223
224 /* Just after the last buffered byte in the buffer, or -1 if the buffer
225 isn't ready for reading. */
226 Py_off_t read_end;
227
228 /* Just after the last byte actually written */
229 Py_off_t write_pos;
230 /* Just after the last byte waiting to be written, or -1 if the buffer
231 isn't ready for writing. */
232 Py_off_t write_end;
233
234 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200235 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000236
237 Py_ssize_t buffer_size;
238 Py_ssize_t buffer_mask;
239
240 PyObject *dict;
241 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000242} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000243
244/*
245 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200246
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000247 * BufferedReader, BufferedWriter and BufferedRandom try to share most
248 methods (this is helped by the members `readable` and `writable`, which
249 are initialized in the respective constructors)
250 * They also share a single buffer for reading and writing. This enables
251 interleaved reads and writes without flushing. It also makes the logic
252 a bit trickier to get right.
253 * The absolute position of the raw stream is cached, if possible, in the
254 `abs_pos` member. It must be updated every time an operation is done
255 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000256 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000257 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000258 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
259 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260
261 NOTE: we should try to maintain block alignment of reads and writes to the
262 raw stream (according to the buffer size), but for now it is only done
263 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200264
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000265*/
266
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000267/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000269static int
270_enter_buffered_busy(buffered *self)
271{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200272 int relax_locking;
273 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000274 if (self->owner == PyThread_get_thread_ident()) {
275 PyErr_Format(PyExc_RuntimeError,
276 "reentrant call inside %R", self);
277 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000278 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600279 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000280 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200281 if (!relax_locking)
282 st = PyThread_acquire_lock(self->lock, 1);
283 else {
284 /* When finalizing, we don't want a deadlock to happen with daemon
285 * threads abruptly shut down while they owned the lock.
286 * Therefore, only wait for a grace period (1 s.).
287 * Note that non-daemon threads have already exited here, so this
288 * shouldn't affect carefully written threaded I/O code.
289 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700290 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200291 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000292 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200293 if (relax_locking && st != PY_LOCK_ACQUIRED) {
294 PyObject *msgobj = PyUnicode_FromFormat(
295 "could not acquire lock for %A at interpreter "
296 "shutdown, possibly due to daemon threads",
297 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200298 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200299 Py_FatalError(msg);
300 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000301 return 1;
302}
303
304#define ENTER_BUFFERED(self) \
305 ( (PyThread_acquire_lock(self->lock, 0) ? \
306 1 : _enter_buffered_busy(self)) \
307 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000308
309#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000310 do { \
311 self->owner = 0; \
312 PyThread_release_lock(self->lock); \
313 } while(0);
314
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000315#define CHECK_INITIALIZED(self) \
316 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000317 if (self->detached) { \
318 PyErr_SetString(PyExc_ValueError, \
319 "raw stream has been detached"); \
320 } else { \
321 PyErr_SetString(PyExc_ValueError, \
322 "I/O operation on uninitialized object"); \
323 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000324 return NULL; \
325 }
326
327#define CHECK_INITIALIZED_INT(self) \
328 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000329 if (self->detached) { \
330 PyErr_SetString(PyExc_ValueError, \
331 "raw stream has been detached"); \
332 } else { \
333 PyErr_SetString(PyExc_ValueError, \
334 "I/O operation on uninitialized object"); \
335 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336 return -1; \
337 }
338
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000339#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500340 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000341 (self->fast_closed_checks \
342 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500343 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000344
345#define CHECK_CLOSED(self, error_msg) \
346 if (IS_CLOSED(self)) { \
347 PyErr_SetString(PyExc_ValueError, error_msg); \
348 return NULL; \
349 }
350
351
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000352#define VALID_READ_BUFFER(self) \
353 (self->readable && self->read_end != -1)
354
355#define VALID_WRITE_BUFFER(self) \
356 (self->writable && self->write_end != -1)
357
358#define ADJUST_POSITION(self, _new_pos) \
359 do { \
360 self->pos = _new_pos; \
361 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
362 self->read_end = self->pos; \
363 } while(0)
364
365#define READAHEAD(self) \
366 ((self->readable && VALID_READ_BUFFER(self)) \
367 ? (self->read_end - self->pos) : 0)
368
369#define RAW_OFFSET(self) \
370 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
371 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
372
373#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000374 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000375
376#define MINUS_LAST_BLOCK(self, size) \
377 (self->buffer_mask ? \
378 (size & ~self->buffer_mask) : \
379 (self->buffer_size * (size / self->buffer_size)))
380
381
382static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000383buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000384{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200385 self->finalizing = 1;
386 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387 return;
388 _PyObject_GC_UNTRACK(self);
389 self->ok = 0;
390 if (self->weakreflist != NULL)
391 PyObject_ClearWeakRefs((PyObject *)self);
392 Py_CLEAR(self->raw);
393 if (self->buffer) {
394 PyMem_Free(self->buffer);
395 self->buffer = NULL;
396 }
397 if (self->lock) {
398 PyThread_free_lock(self->lock);
399 self->lock = NULL;
400 }
401 Py_CLEAR(self->dict);
402 Py_TYPE(self)->tp_free((PyObject *)self);
403}
404
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200405static PyObject *
406buffered_sizeof(buffered *self, void *unused)
407{
408 Py_ssize_t res;
409
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200410 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200411 if (self->buffer)
412 res += self->buffer_size;
413 return PyLong_FromSsize_t(res);
414}
415
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000417buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000418{
419 Py_VISIT(self->raw);
420 Py_VISIT(self->dict);
421 return 0;
422}
423
424static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000425buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000426{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000427 self->ok = 0;
428 Py_CLEAR(self->raw);
429 Py_CLEAR(self->dict);
430 return 0;
431}
432
Antoine Pitroue033e062010-10-29 10:38:18 +0000433/* Because this can call arbitrary code, it shouldn't be called when
434 the refcount is 0 (that is, not directly from tp_dealloc unless
435 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000436static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000437buffered_dealloc_warn(buffered *self, PyObject *source)
438{
439 if (self->ok && self->raw) {
440 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100441 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
442 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000443 if (r)
444 Py_DECREF(r);
445 else
446 PyErr_Clear();
447 }
448 Py_RETURN_NONE;
449}
450
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000451/*
452 * _BufferedIOMixin methods
453 * This is not a class, just a collection of methods that will be reused
454 * by BufferedReader and BufferedWriter
455 */
456
457/* Flush and close */
458
459static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000460buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461{
462 CHECK_INITIALIZED(self)
463 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
464}
465
466static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000467buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000468{
469 int closed;
470 PyObject *res;
471 CHECK_INITIALIZED_INT(self)
472 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
473 if (res == NULL)
474 return -1;
475 closed = PyObject_IsTrue(res);
476 Py_DECREF(res);
477 return closed;
478}
479
480static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000481buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482{
483 CHECK_INITIALIZED(self)
484 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
485}
486
487static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000488buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489{
Benjamin Peterson68623612012-12-20 11:53:11 -0600490 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491 int r;
492
493 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000494 if (!ENTER_BUFFERED(self))
495 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498 if (r < 0)
499 goto end;
500 if (r > 0) {
501 res = Py_None;
502 Py_INCREF(res);
503 goto end;
504 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000505
Antoine Pitrou796564c2013-07-30 19:59:21 +0200506 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000507 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
508 if (r)
509 Py_DECREF(r);
510 else
511 PyErr_Clear();
512 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513 /* flush() will most probably re-take the lock, so drop it first */
514 LEAVE_BUFFERED(self)
515 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000516 if (!ENTER_BUFFERED(self))
517 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600518 if (res == NULL)
519 PyErr_Fetch(&exc, &val, &tb);
520 else
521 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522
523 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
524
Jesus Ceadc469452012-10-04 12:37:56 +0200525 if (self->buffer) {
526 PyMem_Free(self->buffer);
527 self->buffer = NULL;
528 }
529
Benjamin Peterson68623612012-12-20 11:53:11 -0600530 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300531 _PyErr_ChainExceptions(exc, val, tb);
532 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600533 }
534
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000535end:
536 LEAVE_BUFFERED(self)
537 return res;
538}
539
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000540/* detach */
541
542static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000543buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000544{
545 PyObject *raw, *res;
546 CHECK_INITIALIZED(self)
547 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
548 if (res == NULL)
549 return NULL;
550 Py_DECREF(res);
551 raw = self->raw;
552 self->raw = NULL;
553 self->detached = 1;
554 self->ok = 0;
555 return raw;
556}
557
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000558/* Inquiries */
559
560static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000561buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562{
563 CHECK_INITIALIZED(self)
564 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
565}
566
567static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000568buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 CHECK_INITIALIZED(self)
571 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
572}
573
574static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000575buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576{
577 CHECK_INITIALIZED(self)
578 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
579}
580
581static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000582buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583{
584 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200585 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586}
587
588static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000589buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590{
591 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200592 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593}
594
595/* Lower-level APIs */
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
601 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
602}
603
604static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
608 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
609}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000610
Antoine Pitrou243757e2010-11-05 21:15:39 +0000611/* Serialization */
612
613static PyObject *
614buffered_getstate(buffered *self, PyObject *args)
615{
616 PyErr_Format(PyExc_TypeError,
617 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
618 return NULL;
619}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000620
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000621/* Forward decls */
622static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100623_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000624static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000626static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000628static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000629_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200631_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000632static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000633_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000634static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000635_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000636static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000637_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200638static Py_ssize_t
639_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640
641/*
642 * Helpers
643 */
644
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100645/* Sets the current error to BlockingIOError */
646static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200647_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100648{
649 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200650 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100651 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
652 errno, msg, written);
653 if (err)
654 PyErr_SetObject(PyExc_BlockingIOError, err);
655 Py_XDECREF(err);
656}
657
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658/* Returns the address of the `written` member if a BlockingIOError was
659 raised, NULL otherwise. The error is always re-raised. */
660static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000661_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000662{
663 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200664 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665
666 PyErr_Fetch(&t, &v, &tb);
667 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
668 PyErr_Restore(t, v, tb);
669 return NULL;
670 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200671 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672 /* TODO: sanity check (err->written >= 0) */
673 PyErr_Restore(t, v, tb);
674 return &err->written;
675}
676
677static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000678_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000679{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000681 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
683 if (res == NULL)
684 return -1;
685 n = PyNumber_AsOff_t(res, PyExc_ValueError);
686 Py_DECREF(res);
687 if (n < 0) {
688 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300689 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000690 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200691 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 return -1;
693 }
694 self->abs_pos = n;
695 return n;
696}
697
698static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000699_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700{
701 PyObject *res, *posobj, *whenceobj;
702 Py_off_t n;
703
704 posobj = PyLong_FromOff_t(target);
705 if (posobj == NULL)
706 return -1;
707 whenceobj = PyLong_FromLong(whence);
708 if (whenceobj == NULL) {
709 Py_DECREF(posobj);
710 return -1;
711 }
712 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
713 posobj, whenceobj, NULL);
714 Py_DECREF(posobj);
715 Py_DECREF(whenceobj);
716 if (res == NULL)
717 return -1;
718 n = PyNumber_AsOff_t(res, PyExc_ValueError);
719 Py_DECREF(res);
720 if (n < 0) {
721 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300722 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000723 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200724 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000725 return -1;
726 }
727 self->abs_pos = n;
728 return n;
729}
730
731static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000732_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000733{
734 Py_ssize_t n;
735 if (self->buffer_size <= 0) {
736 PyErr_SetString(PyExc_ValueError,
737 "buffer size must be strictly positive");
738 return -1;
739 }
740 if (self->buffer)
741 PyMem_Free(self->buffer);
742 self->buffer = PyMem_Malloc(self->buffer_size);
743 if (self->buffer == NULL) {
744 PyErr_NoMemory();
745 return -1;
746 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000747 if (self->lock)
748 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000749 self->lock = PyThread_allocate_lock();
750 if (self->lock == NULL) {
751 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
752 return -1;
753 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000754 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000755 /* Find out whether buffer_size is a power of 2 */
756 /* XXX is this optimization useful? */
757 for (n = self->buffer_size - 1; n & 1; n >>= 1)
758 ;
759 if (n == 0)
760 self->buffer_mask = self->buffer_size - 1;
761 else
762 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000763 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000764 PyErr_Clear();
765 return 0;
766}
767
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300768/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000769 clears the error indicator), 0 otherwise.
770 Should only be called when PyErr_Occurred() is true.
771*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700772int
773_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000774{
775 static PyObject *eintr_int = NULL;
776 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300777 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000778
779 if (eintr_int == NULL) {
780 eintr_int = PyLong_FromLong(EINTR);
781 assert(eintr_int != NULL);
782 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300783 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000784 return 0;
785 PyErr_Fetch(&typ, &val, &tb);
786 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300787 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000788 assert(env_err != NULL);
789 if (env_err->myerrno != NULL &&
790 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
791 Py_DECREF(typ);
792 Py_DECREF(val);
793 Py_XDECREF(tb);
794 return 1;
795 }
796 /* This silences any error set by PyObject_RichCompareBool() */
797 PyErr_Restore(typ, val, tb);
798 return 0;
799}
800
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000801/*
802 * Shared methods and wrappers
803 */
804
805static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200806buffered_flush_and_rewind_unlocked(buffered *self)
807{
808 PyObject *res;
809
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100810 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200811 if (res == NULL)
812 return NULL;
813 Py_DECREF(res);
814
815 if (self->readable) {
816 /* Rewind the raw stream so that its position corresponds to
817 the current logical position. */
818 Py_off_t n;
819 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
820 _bufferedreader_reset_buf(self);
821 if (n == -1)
822 return NULL;
823 }
824 Py_RETURN_NONE;
825}
826
827static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000828buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000829{
830 PyObject *res;
831
832 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000833 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000834
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000835 if (!ENTER_BUFFERED(self))
836 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200837 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000838 LEAVE_BUFFERED(self)
839
840 return res;
841}
842
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300843/*[clinic input]
844_io._Buffered.peek
845 size: Py_ssize_t = 0
846 /
847
848[clinic start generated code]*/
849
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300851_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
852/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000853{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000854 PyObject *res = NULL;
855
856 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300857 CHECK_CLOSED(self, "peek of closed file")
858
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000859 if (!ENTER_BUFFERED(self))
860 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000861
862 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200863 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864 if (res == NULL)
865 goto end;
866 Py_CLEAR(res);
867 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200868 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000869
870end:
871 LEAVE_BUFFERED(self)
872 return res;
873}
874
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300875/*[clinic input]
876_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300877 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300878 /
879[clinic start generated code]*/
880
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300882_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300883/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000884{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885 PyObject *res;
886
887 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000888 if (n < -1) {
889 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000890 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000891 return NULL;
892 }
893
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000894 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000895
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000896 if (n == -1) {
897 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000898 if (!ENTER_BUFFERED(self))
899 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000900 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000901 }
902 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000903 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200904 if (res != Py_None)
905 return res;
906 Py_DECREF(res);
907 if (!ENTER_BUFFERED(self))
908 return NULL;
909 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000910 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000911
Antoine Pitroue05565e2011-08-20 14:39:23 +0200912 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913 return res;
914}
915
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300916/*[clinic input]
917_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000918 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300919 /
920[clinic start generated code]*/
921
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300923_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000924/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000925{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300926 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927 PyObject *res = NULL;
928
929 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000931 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300933
934 CHECK_CLOSED(self, "read of closed file")
935
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936 if (n == 0)
937 return PyBytes_FromStringAndSize(NULL, 0);
938
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939 /* Return up to n bytes. If at least one byte is buffered, we
940 only return buffered bytes. Otherwise, we do one raw read. */
941
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
943 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100944 n = Py_MIN(have, n);
945 res = _bufferedreader_read_fast(self, n);
946 assert(res != Py_None);
947 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100949 res = PyBytes_FromStringAndSize(NULL, n);
950 if (res == NULL)
951 return NULL;
952 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200953 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100954 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200955 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000956 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100957 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
958 LEAVE_BUFFERED(self)
959 if (r == -1) {
960 Py_DECREF(res);
961 return NULL;
962 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 if (r == -2)
964 r = 0;
965 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100966 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 return res;
968}
969
970static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300971_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200973 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000974 PyObject *res = NULL;
975
976 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200977
Antoine Pitrou3486a982011-05-12 01:57:53 +0200978 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
979 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300980 if (n >= buffer->len) {
981 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
982 self->pos += buffer->len;
983 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200984 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300985 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200986 self->pos += n;
987 written = n;
988 }
989
990 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200992
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200994 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995 if (res == NULL)
996 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000998 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200999
1000 _bufferedreader_reset_buf(self);
1001 self->pos = 0;
1002
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001003 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001004 remaining > 0;
1005 written += n, remaining -= n) {
1006 /* If remaining bytes is larger than internal buffer size, copy
1007 * directly into caller's buffer. */
1008 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001009 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001010 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001011 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001012
1013 /* In readinto1 mode, we do not want to fill the internal
1014 buffer if we already have some data to return */
1015 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016 n = _bufferedreader_fill_buffer(self);
1017 if (n > 0) {
1018 if (n > remaining)
1019 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001020 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001021 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022 self->pos += n;
1023 continue; /* short circuit */
1024 }
1025 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001026 else
1027 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001028
Antoine Pitrou3486a982011-05-12 01:57:53 +02001029 if (n == 0 || (n == -2 && written > 0))
1030 break;
1031 if (n < 0) {
1032 if (n == -2) {
1033 Py_INCREF(Py_None);
1034 res = Py_None;
1035 }
1036 goto end;
1037 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001038
Benjamin Petersona96fea02014-06-22 14:17:44 -07001039 /* At most one read in readinto1 mode */
1040 if (readinto1) {
1041 written += n;
1042 break;
1043 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001044 }
1045 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046
1047end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001048 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049 return res;
1050}
1051
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001052/*[clinic input]
1053_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001054 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001055 /
1056[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001057
1058static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001059_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001060/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001061{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001062 return _buffered_readinto_generic(self, buffer, 0);
1063}
1064
1065/*[clinic input]
1066_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001067 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001068 /
1069[clinic start generated code]*/
1070
1071static PyObject *
1072_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001073/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001074{
1075 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001076}
1077
1078
1079static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001080_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001081{
1082 PyObject *res = NULL;
1083 PyObject *chunks = NULL;
1084 Py_ssize_t n, written = 0;
1085 const char *start, *s, *end;
1086
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001088
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001089 /* First, try to find a line in the buffer. This can run unlocked because
1090 the calls to the C API are simple enough that they can't trigger
1091 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001092 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1093 if (limit >= 0 && n > limit)
1094 n = limit;
1095 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001096 s = memchr(start, '\n', n);
1097 if (s != NULL) {
1098 res = PyBytes_FromStringAndSize(start, s - start + 1);
1099 if (res != NULL)
1100 self->pos += s - start + 1;
1101 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102 }
1103 if (n == limit) {
1104 res = PyBytes_FromStringAndSize(start, n);
1105 if (res != NULL)
1106 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001107 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001108 }
1109
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001110 if (!ENTER_BUFFERED(self))
1111 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001112
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001114 chunks = PyList_New(0);
1115 if (chunks == NULL)
1116 goto end;
1117 if (n > 0) {
1118 res = PyBytes_FromStringAndSize(start, n);
1119 if (res == NULL)
1120 goto end;
1121 if (PyList_Append(chunks, res) < 0) {
1122 Py_CLEAR(res);
1123 goto end;
1124 }
1125 Py_CLEAR(res);
1126 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001127 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128 if (limit >= 0)
1129 limit -= n;
1130 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001131 if (self->writable) {
1132 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1133 if (r == NULL)
1134 goto end;
1135 Py_DECREF(r);
1136 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001137
1138 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001139 _bufferedreader_reset_buf(self);
1140 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001141 if (n == -1)
1142 goto end;
1143 if (n <= 0)
1144 break;
1145 if (limit >= 0 && n > limit)
1146 n = limit;
1147 start = self->buffer;
1148 end = start + n;
1149 s = start;
1150 while (s < end) {
1151 if (*s++ == '\n') {
1152 res = PyBytes_FromStringAndSize(start, s - start);
1153 if (res == NULL)
1154 goto end;
1155 self->pos = s - start;
1156 goto found;
1157 }
1158 }
1159 res = PyBytes_FromStringAndSize(start, n);
1160 if (res == NULL)
1161 goto end;
1162 if (n == limit) {
1163 self->pos = n;
1164 break;
1165 }
1166 if (PyList_Append(chunks, res) < 0) {
1167 Py_CLEAR(res);
1168 goto end;
1169 }
1170 Py_CLEAR(res);
1171 written += n;
1172 if (limit >= 0)
1173 limit -= n;
1174 }
1175found:
1176 if (res != NULL && PyList_Append(chunks, res) < 0) {
1177 Py_CLEAR(res);
1178 goto end;
1179 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001180 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001181
1182end:
1183 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001184end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001185 Py_XDECREF(chunks);
1186 return res;
1187}
1188
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001189/*[clinic input]
1190_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001191 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001192 /
1193[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001194
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001195static PyObject *
1196_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001197/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001198{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001200 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201}
1202
1203
1204static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001205buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206{
1207 Py_off_t pos;
1208
1209 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001210 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001211 if (pos == -1)
1212 return NULL;
1213 pos -= RAW_OFFSET(self);
1214 /* TODO: sanity check (pos >= 0) */
1215 return PyLong_FromOff_t(pos);
1216}
1217
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001218/*[clinic input]
1219_io._Buffered.seek
1220 target as targetobj: object
1221 whence: int = 0
1222 /
1223[clinic start generated code]*/
1224
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001226_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1227/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001228{
1229 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001230 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231
1232 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001233
1234 /* Do some error checking instead of trusting OS 'seek()'
1235 ** error detection, just in case.
1236 */
1237 if ((whence < 0 || whence >2)
1238#ifdef SEEK_HOLE
1239 && (whence != SEEK_HOLE)
1240#endif
1241#ifdef SEEK_DATA
1242 && (whence != SEEK_DATA)
1243#endif
1244 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001246 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001247 return NULL;
1248 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001249
1250 CHECK_CLOSED(self, "seek of closed file")
1251
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001252 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1253 return NULL;
1254
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001255 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1256 if (target == -1 && PyErr_Occurred())
1257 return NULL;
1258
Jesus Cea94363612012-06-22 18:32:07 +02001259 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1260 buffer. Other whence values must be managed without this optimization.
1261 Some Operating Systems can provide additional values, like
1262 SEEK_HOLE/SEEK_DATA. */
1263 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 Py_off_t current, avail;
1265 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001266 so as to return quickly if possible. Also, we needn't take the
1267 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001268 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001269 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1270 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001271 current = RAW_TELL(self);
1272 avail = READAHEAD(self);
1273 if (avail > 0) {
1274 Py_off_t offset;
1275 if (whence == 0)
1276 offset = target - (current - RAW_OFFSET(self));
1277 else
1278 offset = target;
1279 if (offset >= -self->pos && offset <= avail) {
1280 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001281 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 }
1283 }
1284 }
1285
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001286 if (!ENTER_BUFFERED(self))
1287 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001288
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 /* Fallback: invoke raw seek() method and clear buffer */
1290 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001291 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 if (res == NULL)
1293 goto end;
1294 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001295 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001296 }
1297
1298 /* TODO: align on block boundary and read buffer if needed? */
1299 if (whence == 1)
1300 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001301 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001302 if (n == -1)
1303 goto end;
1304 self->raw_pos = -1;
1305 res = PyLong_FromOff_t(n);
1306 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001307 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308
1309end:
1310 LEAVE_BUFFERED(self)
1311 return res;
1312}
1313
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001314/*[clinic input]
1315_io._Buffered.truncate
1316 pos: object = None
1317 /
1318[clinic start generated code]*/
1319
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001321_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1322/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001323{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001324 PyObject *res = NULL;
1325
1326 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001327 if (!ENTER_BUFFERED(self))
1328 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001329
1330 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001331 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001332 if (res == NULL)
1333 goto end;
1334 Py_CLEAR(res);
1335 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1337 if (res == NULL)
1338 goto end;
1339 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001340 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341 PyErr_Clear();
1342
1343end:
1344 LEAVE_BUFFERED(self)
1345 return res;
1346}
1347
1348static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001349buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350{
1351 PyObject *line;
1352 PyTypeObject *tp;
1353
1354 CHECK_INITIALIZED(self);
1355
1356 tp = Py_TYPE(self);
1357 if (tp == &PyBufferedReader_Type ||
1358 tp == &PyBufferedRandom_Type) {
1359 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001360 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361 }
1362 else {
1363 line = PyObject_CallMethodObjArgs((PyObject *)self,
1364 _PyIO_str_readline, NULL);
1365 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001366 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367 "readline() should have returned a bytes object, "
1368 "not '%.200s'", Py_TYPE(line)->tp_name);
1369 Py_DECREF(line);
1370 return NULL;
1371 }
1372 }
1373
1374 if (line == NULL)
1375 return NULL;
1376
1377 if (PyBytes_GET_SIZE(line) == 0) {
1378 /* Reached EOF or would have blocked */
1379 Py_DECREF(line);
1380 return NULL;
1381 }
1382
1383 return line;
1384}
1385
Antoine Pitrou716c4442009-05-23 19:04:03 +00001386static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001387buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001388{
1389 PyObject *nameobj, *res;
1390
Martin v. Löwis767046a2011-10-14 15:35:36 +02001391 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001392 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001393 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001394 PyErr_Clear();
1395 else
1396 return NULL;
1397 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1398 }
1399 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001400 int status = Py_ReprEnter((PyObject *)self);
1401 res = NULL;
1402 if (status == 0) {
1403 res = PyUnicode_FromFormat("<%s name=%R>",
1404 Py_TYPE(self)->tp_name, nameobj);
1405 Py_ReprLeave((PyObject *)self);
1406 }
1407 else if (status > 0) {
1408 PyErr_Format(PyExc_RuntimeError,
1409 "reentrant call inside %s.__repr__",
1410 Py_TYPE(self)->tp_name);
1411 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001412 Py_DECREF(nameobj);
1413 }
1414 return res;
1415}
1416
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001417/*
1418 * class BufferedReader
1419 */
1420
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001421static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001422{
1423 self->read_end = -1;
1424}
1425
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001426/*[clinic input]
1427_io.BufferedReader.__init__
1428 raw: object
1429 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001430
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001431Create a new buffered reader using the given readable raw IO object.
1432[clinic start generated code]*/
1433
1434static int
1435_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1436 Py_ssize_t buffer_size)
1437/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1438{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001439 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001440 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001442 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443 return -1;
1444
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001445 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001446 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001447 self->buffer_size = buffer_size;
1448 self->readable = 1;
1449 self->writable = 0;
1450
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001451 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001452 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001453 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001455 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1456 Py_TYPE(raw) == &PyFileIO_Type);
1457
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458 self->ok = 1;
1459 return 0;
1460}
1461
1462static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001463_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001464{
1465 Py_buffer buf;
1466 PyObject *memobj, *res;
1467 Py_ssize_t n;
1468 /* NOTE: the buffer needn't be released as its object is NULL. */
1469 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1470 return -1;
1471 memobj = PyMemoryView_FromBuffer(&buf);
1472 if (memobj == NULL)
1473 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001474 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1475 occurs so we needn't do it ourselves.
1476 We then retry reading, ignoring the signal if no handler has
1477 raised (see issue #10956).
1478 */
1479 do {
1480 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001481 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001482 Py_DECREF(memobj);
1483 if (res == NULL)
1484 return -1;
1485 if (res == Py_None) {
1486 /* Non-blocking stream would have blocked. Special return code! */
1487 Py_DECREF(res);
1488 return -2;
1489 }
1490 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1491 Py_DECREF(res);
1492 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001493 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001494 "raw readinto() returned invalid length %zd "
1495 "(should have been between 0 and %zd)", n, len);
1496 return -1;
1497 }
1498 if (n > 0 && self->abs_pos != -1)
1499 self->abs_pos += n;
1500 return n;
1501}
1502
1503static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001504_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001505{
1506 Py_ssize_t start, len, n;
1507 if (VALID_READ_BUFFER(self))
1508 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1509 else
1510 start = 0;
1511 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001512 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001513 if (n <= 0)
1514 return n;
1515 self->read_end = start + n;
1516 self->raw_pos = start + n;
1517 return n;
1518}
1519
1520static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001521_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001522{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001523 Py_ssize_t current_size;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001524 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001525
1526 /* First copy what we have in the current buffer. */
1527 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1528 if (current_size) {
1529 data = PyBytes_FromStringAndSize(
1530 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001531 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001533 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001534 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001535 /* We're going past the buffer's bounds, flush it */
1536 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001537 tmp = buffered_flush_and_rewind_unlocked(self);
1538 if (tmp == NULL)
1539 goto cleanup;
1540 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001541 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001542 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001543
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001544 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1545 goto cleanup;
1546 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001547 if (readall) {
1548 tmp = _PyObject_CallNoArg(readall);
1549 Py_DECREF(readall);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001550 if (tmp == NULL)
1551 goto cleanup;
1552 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001553 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001554 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001555 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001556 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 res = tmp;
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001558 } else {
1559 if (tmp != Py_None) {
1560 PyBytes_Concat(&data, tmp);
1561 }
1562 res = data;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001563 }
Serhiy Storchaka4d9aec02018-01-16 18:34:21 +02001564 goto cleanup;
1565 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001566
1567 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001568 if (chunks == NULL)
1569 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001570
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001571 while (1) {
1572 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001573 if (PyList_Append(chunks, data) < 0)
1574 goto cleanup;
1575 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001576 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001577
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001578 /* Read until EOF or until read() would block. */
1579 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001580 if (data == NULL)
1581 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001582 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001584 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001585 }
1586 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1587 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001588 res = data;
1589 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001590 }
1591 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001592 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1593 res = tmp;
1594 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595 }
1596 }
1597 current_size += PyBytes_GET_SIZE(data);
1598 if (self->abs_pos != -1)
1599 self->abs_pos += PyBytes_GET_SIZE(data);
1600 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001601cleanup:
1602 /* res is either NULL or a borrowed ref */
1603 Py_XINCREF(res);
1604 Py_XDECREF(data);
1605 Py_XDECREF(tmp);
1606 Py_XDECREF(chunks);
1607 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608}
1609
1610/* Read n bytes from the buffer if it can, otherwise return None.
1611 This function is simple enough that it can run unlocked. */
1612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001613_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001614{
1615 Py_ssize_t current_size;
1616
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001617 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1618 if (n <= current_size) {
1619 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001620 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1621 if (res != NULL)
1622 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001623 return res;
1624 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001625 Py_RETURN_NONE;
1626}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001627
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001628/* Generic read function: read from the stream until enough bytes are read,
1629 * or until an EOF occurs or until read() would block.
1630 */
1631static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001632_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001633{
1634 PyObject *res = NULL;
1635 Py_ssize_t current_size, remaining, written;
1636 char *out;
1637
1638 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1639 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001640 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001641
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001642 res = PyBytes_FromStringAndSize(NULL, n);
1643 if (res == NULL)
1644 goto error;
1645 out = PyBytes_AS_STRING(res);
1646 remaining = n;
1647 written = 0;
1648 if (current_size > 0) {
1649 memcpy(out, self->buffer + self->pos, current_size);
1650 remaining -= current_size;
1651 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001652 self->pos += current_size;
1653 }
1654 /* Flush the write buffer if necessary */
1655 if (self->writable) {
1656 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1657 if (r == NULL)
1658 goto error;
1659 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001660 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001661 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001662 while (remaining > 0) {
1663 /* We want to read a whole block at the end into buffer.
1664 If we had readv() we could do this in one pass. */
1665 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1666 if (r == 0)
1667 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001668 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001669 if (r == -1)
1670 goto error;
1671 if (r == 0 || r == -2) {
1672 /* EOF occurred or read() would block. */
1673 if (r == 0 || written > 0) {
1674 if (_PyBytes_Resize(&res, written))
1675 goto error;
1676 return res;
1677 }
1678 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001679 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001680 }
1681 remaining -= r;
1682 written += r;
1683 }
1684 assert(remaining <= self->buffer_size);
1685 self->pos = 0;
1686 self->raw_pos = 0;
1687 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001688 /* NOTE: when the read is satisfied, we avoid issuing any additional
1689 reads, which could block indefinitely (e.g. on a socket).
1690 See issue #9550. */
1691 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001692 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693 if (r == -1)
1694 goto error;
1695 if (r == 0 || r == -2) {
1696 /* EOF occurred or read() would block. */
1697 if (r == 0 || written > 0) {
1698 if (_PyBytes_Resize(&res, written))
1699 goto error;
1700 return res;
1701 }
1702 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001703 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001704 }
1705 if (remaining > r) {
1706 memcpy(out + written, self->buffer + self->pos, r);
1707 written += r;
1708 self->pos += r;
1709 remaining -= r;
1710 }
1711 else if (remaining > 0) {
1712 memcpy(out + written, self->buffer + self->pos, remaining);
1713 written += remaining;
1714 self->pos += remaining;
1715 remaining = 0;
1716 }
1717 if (remaining == 0)
1718 break;
1719 }
1720
1721 return res;
1722
1723error:
1724 Py_XDECREF(res);
1725 return NULL;
1726}
1727
1728static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001729_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001730{
1731 Py_ssize_t have, r;
1732
1733 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1734 /* Constraints:
1735 1. we don't want to advance the file position.
1736 2. we don't want to lose block alignment, so we can't shift the buffer
1737 to make some place.
1738 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1739 */
1740 if (have > 0) {
1741 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1742 }
1743
1744 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001745 _bufferedreader_reset_buf(self);
1746 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001747 if (r == -1)
1748 return NULL;
1749 if (r == -2)
1750 r = 0;
1751 self->pos = 0;
1752 return PyBytes_FromStringAndSize(self->buffer, r);
1753}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001754
1755
Benjamin Peterson59406a92009-03-26 17:10:29 +00001756
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757/*
1758 * class BufferedWriter
1759 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001761_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001762{
1763 self->write_pos = 0;
1764 self->write_end = -1;
1765}
1766
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001767/*[clinic input]
1768_io.BufferedWriter.__init__
1769 raw: object
1770 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001771
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001772A buffer for a writeable sequential RawIO object.
1773
1774The constructor creates a BufferedWriter for the given writeable raw
1775stream. If the buffer_size is not given, it defaults to
1776DEFAULT_BUFFER_SIZE.
1777[clinic start generated code]*/
1778
1779static int
1780_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1781 Py_ssize_t buffer_size)
1782/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1783{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001785 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 return -1;
1789
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001791 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001792 self->readable = 0;
1793 self->writable = 1;
1794
1795 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001796 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001798 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001799 self->pos = 0;
1800
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001801 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1802 Py_TYPE(raw) == &PyFileIO_Type);
1803
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 self->ok = 1;
1805 return 0;
1806}
1807
1808static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001809_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810{
1811 Py_buffer buf;
1812 PyObject *memobj, *res;
1813 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001814 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 /* NOTE: the buffer needn't be released as its object is NULL. */
1816 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1817 return -1;
1818 memobj = PyMemoryView_FromBuffer(&buf);
1819 if (memobj == NULL)
1820 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001821 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1822 occurs so we needn't do it ourselves.
1823 We then retry writing, ignoring the signal if no handler has
1824 raised (see issue #10956).
1825 */
1826 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001827 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001828 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001829 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001830 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 Py_DECREF(memobj);
1832 if (res == NULL)
1833 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001834 if (res == Py_None) {
1835 /* Non-blocking stream would have blocked. Special return code!
1836 Being paranoid we reset errno in case it is changed by code
1837 triggered by a decref. errno is used by _set_BlockingIOError(). */
1838 Py_DECREF(res);
1839 errno = errnum;
1840 return -2;
1841 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001842 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1843 Py_DECREF(res);
1844 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001845 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 "raw write() returned invalid length %zd "
1847 "(should have been between 0 and %zd)", n, len);
1848 return -1;
1849 }
1850 if (n > 0 && self->abs_pos != -1)
1851 self->abs_pos += n;
1852 return n;
1853}
1854
1855/* `restore_pos` is 1 if we need to restore the raw stream position at
1856 the end, 0 otherwise. */
1857static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001858_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001859{
1860 Py_ssize_t written = 0;
1861 Py_off_t n, rewind;
1862
1863 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1864 goto end;
1865 /* First, rewind */
1866 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1867 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001868 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001869 if (n < 0) {
1870 goto error;
1871 }
1872 self->raw_pos -= rewind;
1873 }
1874 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001875 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001876 self->buffer + self->write_pos,
1877 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1878 Py_off_t, Py_ssize_t));
1879 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001880 goto error;
1881 }
1882 else if (n == -2) {
1883 _set_BlockingIOError("write could not complete without blocking",
1884 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885 goto error;
1886 }
1887 self->write_pos += n;
1888 self->raw_pos = self->write_pos;
1889 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001890 /* Partial writes can return successfully when interrupted by a
1891 signal (see write(2)). We must run signal handlers before
1892 blocking another time, possibly indefinitely. */
1893 if (PyErr_CheckSignals() < 0)
1894 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001895 }
1896
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001897 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898
1899end:
1900 Py_RETURN_NONE;
1901
1902error:
1903 return NULL;
1904}
1905
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001906/*[clinic input]
1907_io.BufferedWriter.write
1908 buffer: Py_buffer
1909 /
1910[clinic start generated code]*/
1911
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001913_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1914/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915{
1916 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001917 Py_ssize_t written, avail, remaining;
1918 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001919
1920 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001922 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001923 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924
benfogle9703f092017-11-10 16:03:40 -05001925 /* Issue #31976: Check for closed file after acquiring the lock. Another
1926 thread could be holding the lock while closing the file. */
1927 if (IS_CLOSED(self)) {
1928 PyErr_SetString(PyExc_ValueError, "write to closed file");
1929 goto error;
1930 }
1931
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001932 /* Fast path: the data to write can be fully buffered. */
1933 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1934 self->pos = 0;
1935 self->raw_pos = 0;
1936 }
1937 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001938 if (buffer->len <= avail) {
1939 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001940 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941 self->write_pos = self->pos;
1942 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001943 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 if (self->pos > self->write_end)
1945 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001946 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947 goto end;
1948 }
1949
1950 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001951 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001953 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 if (w == NULL)
1955 goto error;
1956 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001957 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 /* Make some place by shifting the buffer. */
1959 assert(VALID_WRITE_BUFFER(self));
1960 memmove(self->buffer, self->buffer + self->write_pos,
1961 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1962 Py_off_t, Py_ssize_t));
1963 self->write_end -= self->write_pos;
1964 self->raw_pos -= self->write_pos;
1965 self->pos -= self->write_pos;
1966 self->write_pos = 0;
1967 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1968 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001969 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 /* Everything can be buffered */
1971 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001972 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1973 self->write_end += buffer->len;
1974 self->pos += buffer->len;
1975 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976 goto end;
1977 }
1978 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001979 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001980 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001981 self->pos += avail;
1982 /* XXX Modifying the existing exception e using the pointer w
1983 will change e.characters_written but not e.args[2].
1984 Therefore we just replace with a new error. */
1985 _set_BlockingIOError("write could not complete without blocking",
1986 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001987 goto error;
1988 }
1989 Py_CLEAR(res);
1990
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001991 /* Adjust the raw stream position if it is away from the logical stream
1992 position. This happens if the read buffer has been filled but not
1993 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1994 the raw stream by itself).
1995 Fixes issue #6629.
1996 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001997 offset = RAW_OFFSET(self);
1998 if (offset != 0) {
1999 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002000 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002001 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002002 }
2003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002005 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002006 written = 0;
2007 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002008 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002009 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002011 goto error;
2012 } else if (n == -2) {
2013 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 if (remaining > self->buffer_size) {
2015 /* Can't buffer everything, still buffer as much as possible */
2016 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002017 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 self->raw_pos = 0;
2019 ADJUST_POSITION(self, self->buffer_size);
2020 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002021 written += self->buffer_size;
2022 _set_BlockingIOError("write could not complete without "
2023 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 goto error;
2025 }
2026 PyErr_Clear();
2027 break;
2028 }
2029 written += n;
2030 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002031 /* Partial writes can return successfully when interrupted by a
2032 signal (see write(2)). We must run signal handlers before
2033 blocking another time, possibly indefinitely. */
2034 if (PyErr_CheckSignals() < 0)
2035 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002036 }
2037 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002038 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002039 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002040 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 written += remaining;
2042 }
2043 self->write_pos = 0;
2044 /* TODO: sanity check (remaining >= 0) */
2045 self->write_end = remaining;
2046 ADJUST_POSITION(self, remaining);
2047 self->raw_pos = 0;
2048
2049end:
2050 res = PyLong_FromSsize_t(written);
2051
2052error:
2053 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 return res;
2055}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056
2057
2058
2059/*
2060 * BufferedRWPair
2061 */
2062
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002063/* XXX The usefulness of this (compared to having two separate IO objects) is
2064 * questionable.
2065 */
2066
2067typedef struct {
2068 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002069 buffered *reader;
2070 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071 PyObject *dict;
2072 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002073} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002075/*[clinic input]
2076_io.BufferedRWPair.__init__
2077 reader: object
2078 writer: object
2079 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2080 /
2081
2082A buffered reader and writer object together.
2083
2084A buffered reader object and buffered writer object put together to
2085form a sequential IO object that can read and write. This is typically
2086used with a socket or two-way pipe.
2087
2088reader and writer are RawIOBase objects that are readable and
2089writeable respectively. If the buffer_size is omitted it defaults to
2090DEFAULT_BUFFER_SIZE.
2091[clinic start generated code]*/
2092
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002093static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002094_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2095 PyObject *writer, Py_ssize_t buffer_size)
2096/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002098 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002099 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 return -1;
2102
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002104 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002105 if (self->reader == NULL)
2106 return -1;
2107
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002108 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002109 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110 if (self->writer == NULL) {
2111 Py_CLEAR(self->reader);
2112 return -1;
2113 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002114
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002115 return 0;
2116}
2117
2118static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002119bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002120{
2121 Py_VISIT(self->dict);
2122 return 0;
2123}
2124
2125static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002127{
2128 Py_CLEAR(self->reader);
2129 Py_CLEAR(self->writer);
2130 Py_CLEAR(self->dict);
2131 return 0;
2132}
2133
2134static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002135bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002136{
2137 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002138 if (self->weakreflist != NULL)
2139 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140 Py_CLEAR(self->reader);
2141 Py_CLEAR(self->writer);
2142 Py_CLEAR(self->dict);
2143 Py_TYPE(self)->tp_free((PyObject *) self);
2144}
2145
2146static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002147_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002149 PyObject *func, *ret;
2150 if (self == NULL) {
2151 PyErr_SetString(PyExc_ValueError,
2152 "I/O operation on uninitialized object");
2153 return NULL;
2154 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002156 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002157 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002158 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 return NULL;
2160 }
2161
2162 ret = PyObject_CallObject(func, args);
2163 Py_DECREF(func);
2164 return ret;
2165}
2166
2167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002170 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171}
2172
2173static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002174bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002176 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177}
2178
2179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002182 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183}
2184
2185static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002187{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002188 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002189}
2190
2191static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002192bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2193{
2194 return _forward_call(self->reader, &PyId_readinto1, args);
2195}
2196
2197static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002198bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002200 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201}
2202
2203static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002204bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002206 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207}
2208
2209static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002212 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213}
2214
2215static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002216bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002218 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219}
2220
2221static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002224 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002225 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002227 PyErr_Fetch(&exc, &val, &tb);
2228 else
2229 Py_DECREF(ret);
2230 ret = _forward_call(self->reader, &PyId_close, args);
2231 if (exc != NULL) {
2232 _PyErr_ChainExceptions(exc, val, tb);
2233 Py_CLEAR(ret);
2234 }
2235 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236}
2237
2238static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002239bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002241 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242
2243 if (ret != Py_False) {
2244 /* either True or exception */
2245 return ret;
2246 }
2247 Py_DECREF(ret);
2248
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002249 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250}
2251
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002252static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002253bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002254{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002255 if (self->writer == NULL) {
2256 PyErr_SetString(PyExc_RuntimeError,
2257 "the BufferedRWPair object is being garbage-collected");
2258 return NULL;
2259 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002260 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2261}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002262
2263
2264
2265/*
2266 * BufferedRandom
2267 */
2268
2269/*[clinic input]
2270_io.BufferedRandom.__init__
2271 raw: object
2272 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2273
2274A buffered interface to random access streams.
2275
2276The constructor creates a reader and writer for a seekable stream,
2277raw, given in the first argument. If the buffer_size is omitted it
2278defaults to DEFAULT_BUFFER_SIZE.
2279[clinic start generated code]*/
2280
2281static int
2282_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2283 Py_ssize_t buffer_size)
2284/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2285{
2286 self->ok = 0;
2287 self->detached = 0;
2288
2289 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2290 return -1;
2291 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2292 return -1;
2293 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2294 return -1;
2295
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002296 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002297 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002298 self->buffer_size = buffer_size;
2299 self->readable = 1;
2300 self->writable = 1;
2301
2302 if (_buffered_init(self) < 0)
2303 return -1;
2304 _bufferedreader_reset_buf(self);
2305 _bufferedwriter_reset_buf(self);
2306 self->pos = 0;
2307
2308 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2309 Py_TYPE(raw) == &PyFileIO_Type);
2310
2311 self->ok = 1;
2312 return 0;
2313}
2314
2315#include "clinic/bufferedio.c.h"
2316
2317
2318static PyMethodDef bufferediobase_methods[] = {
2319 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2320 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2321 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2322 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2323 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2324 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2325 {NULL, NULL}
2326};
2327
2328PyTypeObject PyBufferedIOBase_Type = {
2329 PyVarObject_HEAD_INIT(NULL, 0)
2330 "_io._BufferedIOBase", /*tp_name*/
2331 0, /*tp_basicsize*/
2332 0, /*tp_itemsize*/
2333 0, /*tp_dealloc*/
2334 0, /*tp_print*/
2335 0, /*tp_getattr*/
2336 0, /*tp_setattr*/
2337 0, /*tp_compare */
2338 0, /*tp_repr*/
2339 0, /*tp_as_number*/
2340 0, /*tp_as_sequence*/
2341 0, /*tp_as_mapping*/
2342 0, /*tp_hash */
2343 0, /*tp_call*/
2344 0, /*tp_str*/
2345 0, /*tp_getattro*/
2346 0, /*tp_setattro*/
2347 0, /*tp_as_buffer*/
2348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2349 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2350 bufferediobase_doc, /* tp_doc */
2351 0, /* tp_traverse */
2352 0, /* tp_clear */
2353 0, /* tp_richcompare */
2354 0, /* tp_weaklistoffset */
2355 0, /* tp_iter */
2356 0, /* tp_iternext */
2357 bufferediobase_methods, /* tp_methods */
2358 0, /* tp_members */
2359 0, /* tp_getset */
2360 &PyIOBase_Type, /* tp_base */
2361 0, /* tp_dict */
2362 0, /* tp_descr_get */
2363 0, /* tp_descr_set */
2364 0, /* tp_dictoffset */
2365 0, /* tp_init */
2366 0, /* tp_alloc */
2367 0, /* tp_new */
2368 0, /* tp_free */
2369 0, /* tp_is_gc */
2370 0, /* tp_bases */
2371 0, /* tp_mro */
2372 0, /* tp_cache */
2373 0, /* tp_subclasses */
2374 0, /* tp_weaklist */
2375 0, /* tp_del */
2376 0, /* tp_version_tag */
2377 0, /* tp_finalize */
2378};
2379
2380
2381static PyMethodDef bufferedreader_methods[] = {
2382 /* BufferedIOMixin methods */
2383 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2384 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2385 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2386 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2387 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002388 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2389 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2390 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2391 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2392
2393 _IO__BUFFERED_READ_METHODDEF
2394 _IO__BUFFERED_PEEK_METHODDEF
2395 _IO__BUFFERED_READ1_METHODDEF
2396 _IO__BUFFERED_READINTO_METHODDEF
2397 _IO__BUFFERED_READINTO1_METHODDEF
2398 _IO__BUFFERED_READLINE_METHODDEF
2399 _IO__BUFFERED_SEEK_METHODDEF
2400 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2401 _IO__BUFFERED_TRUNCATE_METHODDEF
2402 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2403 {NULL, NULL}
2404};
2405
2406static PyMemberDef bufferedreader_members[] = {
2407 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2408 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2409 {NULL}
2410};
2411
2412static PyGetSetDef bufferedreader_getset[] = {
2413 {"closed", (getter)buffered_closed_get, NULL, NULL},
2414 {"name", (getter)buffered_name_get, NULL, NULL},
2415 {"mode", (getter)buffered_mode_get, NULL, NULL},
2416 {NULL}
2417};
2418
2419
2420PyTypeObject PyBufferedReader_Type = {
2421 PyVarObject_HEAD_INIT(NULL, 0)
2422 "_io.BufferedReader", /*tp_name*/
2423 sizeof(buffered), /*tp_basicsize*/
2424 0, /*tp_itemsize*/
2425 (destructor)buffered_dealloc, /*tp_dealloc*/
2426 0, /*tp_print*/
2427 0, /*tp_getattr*/
2428 0, /*tp_setattr*/
2429 0, /*tp_compare */
2430 (reprfunc)buffered_repr, /*tp_repr*/
2431 0, /*tp_as_number*/
2432 0, /*tp_as_sequence*/
2433 0, /*tp_as_mapping*/
2434 0, /*tp_hash */
2435 0, /*tp_call*/
2436 0, /*tp_str*/
2437 0, /*tp_getattro*/
2438 0, /*tp_setattro*/
2439 0, /*tp_as_buffer*/
2440 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2441 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2442 _io_BufferedReader___init____doc__, /* tp_doc */
2443 (traverseproc)buffered_traverse, /* tp_traverse */
2444 (inquiry)buffered_clear, /* tp_clear */
2445 0, /* tp_richcompare */
2446 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2447 0, /* tp_iter */
2448 (iternextfunc)buffered_iternext, /* tp_iternext */
2449 bufferedreader_methods, /* tp_methods */
2450 bufferedreader_members, /* tp_members */
2451 bufferedreader_getset, /* tp_getset */
2452 0, /* tp_base */
2453 0, /* tp_dict */
2454 0, /* tp_descr_get */
2455 0, /* tp_descr_set */
2456 offsetof(buffered, dict), /* tp_dictoffset */
2457 _io_BufferedReader___init__, /* tp_init */
2458 0, /* tp_alloc */
2459 PyType_GenericNew, /* tp_new */
2460 0, /* tp_free */
2461 0, /* tp_is_gc */
2462 0, /* tp_bases */
2463 0, /* tp_mro */
2464 0, /* tp_cache */
2465 0, /* tp_subclasses */
2466 0, /* tp_weaklist */
2467 0, /* tp_del */
2468 0, /* tp_version_tag */
2469 0, /* tp_finalize */
2470};
2471
2472
2473static PyMethodDef bufferedwriter_methods[] = {
2474 /* BufferedIOMixin methods */
2475 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2476 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2477 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002478 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2479 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2480 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2481 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2482 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2483
2484 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2485 _IO__BUFFERED_TRUNCATE_METHODDEF
2486 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2487 _IO__BUFFERED_SEEK_METHODDEF
2488 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2489 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2490 {NULL, NULL}
2491};
2492
2493static PyMemberDef bufferedwriter_members[] = {
2494 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2495 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2496 {NULL}
2497};
2498
2499static PyGetSetDef bufferedwriter_getset[] = {
2500 {"closed", (getter)buffered_closed_get, NULL, NULL},
2501 {"name", (getter)buffered_name_get, NULL, NULL},
2502 {"mode", (getter)buffered_mode_get, NULL, NULL},
2503 {NULL}
2504};
2505
2506
2507PyTypeObject PyBufferedWriter_Type = {
2508 PyVarObject_HEAD_INIT(NULL, 0)
2509 "_io.BufferedWriter", /*tp_name*/
2510 sizeof(buffered), /*tp_basicsize*/
2511 0, /*tp_itemsize*/
2512 (destructor)buffered_dealloc, /*tp_dealloc*/
2513 0, /*tp_print*/
2514 0, /*tp_getattr*/
2515 0, /*tp_setattr*/
2516 0, /*tp_compare */
2517 (reprfunc)buffered_repr, /*tp_repr*/
2518 0, /*tp_as_number*/
2519 0, /*tp_as_sequence*/
2520 0, /*tp_as_mapping*/
2521 0, /*tp_hash */
2522 0, /*tp_call*/
2523 0, /*tp_str*/
2524 0, /*tp_getattro*/
2525 0, /*tp_setattro*/
2526 0, /*tp_as_buffer*/
2527 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2528 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2529 _io_BufferedWriter___init____doc__, /* tp_doc */
2530 (traverseproc)buffered_traverse, /* tp_traverse */
2531 (inquiry)buffered_clear, /* tp_clear */
2532 0, /* tp_richcompare */
2533 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2534 0, /* tp_iter */
2535 0, /* tp_iternext */
2536 bufferedwriter_methods, /* tp_methods */
2537 bufferedwriter_members, /* tp_members */
2538 bufferedwriter_getset, /* tp_getset */
2539 0, /* tp_base */
2540 0, /* tp_dict */
2541 0, /* tp_descr_get */
2542 0, /* tp_descr_set */
2543 offsetof(buffered, dict), /* tp_dictoffset */
2544 _io_BufferedWriter___init__, /* tp_init */
2545 0, /* tp_alloc */
2546 PyType_GenericNew, /* tp_new */
2547 0, /* tp_free */
2548 0, /* tp_is_gc */
2549 0, /* tp_bases */
2550 0, /* tp_mro */
2551 0, /* tp_cache */
2552 0, /* tp_subclasses */
2553 0, /* tp_weaklist */
2554 0, /* tp_del */
2555 0, /* tp_version_tag */
2556 0, /* tp_finalize */
2557};
2558
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002560static PyMethodDef bufferedrwpair_methods[] = {
2561 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2562 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2563 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2564 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002565 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2568 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2571 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2574 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575
Antoine Pitrou243757e2010-11-05 21:15:39 +00002576 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2577
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002578 {NULL, NULL}
2579};
2580
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002581static PyGetSetDef bufferedrwpair_getset[] = {
2582 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002583 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002584};
2585
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586PyTypeObject PyBufferedRWPair_Type = {
2587 PyVarObject_HEAD_INIT(NULL, 0)
2588 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002589 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002590 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002591 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002592 0, /*tp_print*/
2593 0, /*tp_getattr*/
2594 0, /*tp_setattr*/
2595 0, /*tp_compare */
2596 0, /*tp_repr*/
2597 0, /*tp_as_number*/
2598 0, /*tp_as_sequence*/
2599 0, /*tp_as_mapping*/
2600 0, /*tp_hash */
2601 0, /*tp_call*/
2602 0, /*tp_str*/
2603 0, /*tp_getattro*/
2604 0, /*tp_setattro*/
2605 0, /*tp_as_buffer*/
2606 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002607 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002608 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002609 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2610 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002611 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002612 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613 0, /* tp_iter */
2614 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002615 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002617 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002618 0, /* tp_base */
2619 0, /* tp_dict */
2620 0, /* tp_descr_get */
2621 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002623 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002624 0, /* tp_alloc */
2625 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002626 0, /* tp_free */
2627 0, /* tp_is_gc */
2628 0, /* tp_bases */
2629 0, /* tp_mro */
2630 0, /* tp_cache */
2631 0, /* tp_subclasses */
2632 0, /* tp_weaklist */
2633 0, /* tp_del */
2634 0, /* tp_version_tag */
2635 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002637
2638
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002639static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002640 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002641 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2642 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2643 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2644 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2645 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2646 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2647 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002648 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002649 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002651 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002652
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002653 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002654 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002655 _IO__BUFFERED_TRUNCATE_METHODDEF
2656 _IO__BUFFERED_READ_METHODDEF
2657 _IO__BUFFERED_READ1_METHODDEF
2658 _IO__BUFFERED_READINTO_METHODDEF
2659 _IO__BUFFERED_READINTO1_METHODDEF
2660 _IO__BUFFERED_READLINE_METHODDEF
2661 _IO__BUFFERED_PEEK_METHODDEF
2662 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002663 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002664 {NULL, NULL}
2665};
2666
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002667static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002668 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002669 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002670 {NULL}
2671};
2672
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002673static PyGetSetDef bufferedrandom_getset[] = {
2674 {"closed", (getter)buffered_closed_get, NULL, NULL},
2675 {"name", (getter)buffered_name_get, NULL, NULL},
2676 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002677 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002678};
2679
2680
2681PyTypeObject PyBufferedRandom_Type = {
2682 PyVarObject_HEAD_INIT(NULL, 0)
2683 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002684 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002685 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002686 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002687 0, /*tp_print*/
2688 0, /*tp_getattr*/
2689 0, /*tp_setattr*/
2690 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002691 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002692 0, /*tp_as_number*/
2693 0, /*tp_as_sequence*/
2694 0, /*tp_as_mapping*/
2695 0, /*tp_hash */
2696 0, /*tp_call*/
2697 0, /*tp_str*/
2698 0, /*tp_getattro*/
2699 0, /*tp_setattro*/
2700 0, /*tp_as_buffer*/
2701 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002702 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002703 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002704 (traverseproc)buffered_traverse, /* tp_traverse */
2705 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002706 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002707 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002708 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002709 (iternextfunc)buffered_iternext, /* tp_iternext */
2710 bufferedrandom_methods, /* tp_methods */
2711 bufferedrandom_members, /* tp_members */
2712 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002713 0, /* tp_base */
2714 0, /*tp_dict*/
2715 0, /* tp_descr_get */
2716 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002717 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002718 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719 0, /* tp_alloc */
2720 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002721 0, /* tp_free */
2722 0, /* tp_is_gc */
2723 0, /* tp_bases */
2724 0, /* tp_mro */
2725 0, /* tp_cache */
2726 0, /* tp_subclasses */
2727 0, /* tp_weaklist */
2728 0, /* tp_del */
2729 0, /* tp_version_tag */
2730 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002731};