blob: 189b1cd8442827fc08144fdaea0cf6bf699f700c [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030016/*[clinic input]
17module _io
18class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24[clinic start generated code]*/
25/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020027_Py_IDENTIFIER(close);
28_Py_IDENTIFIER(_dealloc_warn);
29_Py_IDENTIFIER(flush);
30_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020031_Py_IDENTIFIER(mode);
32_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020033_Py_IDENTIFIER(peek);
34_Py_IDENTIFIER(read);
35_Py_IDENTIFIER(read1);
36_Py_IDENTIFIER(readable);
37_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070038_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020039_Py_IDENTIFIER(writable);
40_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042/*
43 * BufferedIOBase class, inherits from IOBase.
44 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000045PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000046 "Base class for buffered IO objects.\n"
47 "\n"
48 "The main difference with RawIOBase is that the read() method\n"
49 "supports omitting the size argument, and does not have a default\n"
50 "implementation that defers to readinto().\n"
51 "\n"
52 "In addition, read(), readinto() and write() may raise\n"
53 "BlockingIOError if the underlying raw stream is in non-blocking\n"
54 "mode and not ready; unlike their raw counterparts, they will never\n"
55 "return None.\n"
56 "\n"
57 "A typical implementation should not inherit from a RawIOBase\n"
58 "implementation, but wrap one.\n"
59 );
60
61static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030062_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000063{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064 Py_ssize_t len;
65 PyObject *data;
66
Benjamin Petersona96fea02014-06-22 14:17:44 -070067 data = _PyObject_CallMethodId(self,
68 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030069 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030071 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000072
73 if (!PyBytes_Check(data)) {
74 Py_DECREF(data);
75 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030076 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 }
78
Serhiy Storchakafff9a312017-03-21 08:53:25 +020079 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030080 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030081 PyErr_Format(PyExc_ValueError,
82 "read() returned too much data: "
83 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030084 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030085 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030086 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030087 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030088 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090 Py_DECREF(data);
91
92 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000093}
94
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030095/*[clinic input]
96_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070097 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030098 /
99[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700100
101static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300102_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700103/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700104{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300105 return _bufferediobase_readinto_generic(self, buffer, 0);
106}
107
108/*[clinic input]
109_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700110 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300111 /
112[clinic start generated code]*/
113
114static PyObject *
115_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700116/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300117{
118 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700119}
120
121static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100124 _PyIO_State *state = IO_STATE();
125 if (state != NULL)
126 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000127 return NULL;
128}
129
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300130/*[clinic input]
131_io._BufferedIOBase.detach
132
133Disconnect this buffer from its underlying raw stream and return it.
134
135After the raw stream has been detached, the buffer is in an unusable
136state.
137[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000138
139static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300140_io__BufferedIOBase_detach_impl(PyObject *self)
141/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000142{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000144}
145
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000146PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000147 "Read and return up to n bytes.\n"
148 "\n"
149 "If the argument is omitted, None, or negative, reads and\n"
150 "returns all data until EOF.\n"
151 "\n"
152 "If the argument is positive, and the underlying raw stream is\n"
153 "not 'interactive', multiple raw reads may be issued to satisfy\n"
154 "the byte count (unless EOF is reached first). But for\n"
155 "interactive raw streams (as well as sockets and pipes), at most\n"
156 "one raw read will be issued, and a short result does not imply\n"
157 "that EOF is imminent.\n"
158 "\n"
159 "Returns an empty bytes object on EOF.\n"
160 "\n"
161 "Returns None if the underlying raw stream was open in non-blocking\n"
162 "mode and no data is available at the moment.\n");
163
164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000166{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000168}
169
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000170PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171 "Read and return up to n bytes, with at most one read() call\n"
172 "to the underlying raw stream. A short result does not imply\n"
173 "that EOF is imminent.\n"
174 "\n"
175 "Returns an empty bytes object on EOF.\n");
176
177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000178bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000179{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000180 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181}
182
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000183PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000184 "Write the given buffer to the IO stream.\n"
185 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000186 "Returns the number of bytes written, which is always the length of b\n"
187 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188 "\n"
189 "Raises BlockingIOError if the buffer is full and the\n"
190 "underlying raw stream cannot accept more data at the moment.\n");
191
192static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000193bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000194{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000195 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196}
197
198
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000199typedef struct {
200 PyObject_HEAD
201
202 PyObject *raw;
203 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000204 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000205 int readable;
206 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200207 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200208
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000209 /* True if this is a vanilla Buffered object (rather than a user derived
210 class) *and* the raw stream is a vanilla FileIO object. */
211 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212
213 /* Absolute position inside the raw stream (-1 if unknown). */
214 Py_off_t abs_pos;
215
216 /* A static buffer of size `buffer_size` */
217 char *buffer;
218 /* Current logical position in the buffer. */
219 Py_off_t pos;
220 /* Position of the raw stream in the buffer. */
221 Py_off_t raw_pos;
222
223 /* Just after the last buffered byte in the buffer, or -1 if the buffer
224 isn't ready for reading. */
225 Py_off_t read_end;
226
227 /* Just after the last byte actually written */
228 Py_off_t write_pos;
229 /* Just after the last byte waiting to be written, or -1 if the buffer
230 isn't ready for writing. */
231 Py_off_t write_end;
232
Georg Brandldfd73442009-04-05 11:47:34 +0000233#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000234 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200235 volatile unsigned long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000236#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000237
238 Py_ssize_t buffer_size;
239 Py_ssize_t buffer_mask;
240
241 PyObject *dict;
242 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000243} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000244
245/*
246 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200247
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000248 * BufferedReader, BufferedWriter and BufferedRandom try to share most
249 methods (this is helped by the members `readable` and `writable`, which
250 are initialized in the respective constructors)
251 * They also share a single buffer for reading and writing. This enables
252 interleaved reads and writes without flushing. It also makes the logic
253 a bit trickier to get right.
254 * The absolute position of the raw stream is cached, if possible, in the
255 `abs_pos` member. It must be updated every time an operation is done
256 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000257 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000258 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000259 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
260 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000261
262 NOTE: we should try to maintain block alignment of reads and writes to the
263 raw stream (according to the buffer size), but for now it is only done
264 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200265
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000266*/
267
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000268/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000269
Georg Brandldfd73442009-04-05 11:47:34 +0000270#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000271
272static int
273_enter_buffered_busy(buffered *self)
274{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200275 int relax_locking;
276 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000277 if (self->owner == PyThread_get_thread_ident()) {
278 PyErr_Format(PyExc_RuntimeError,
279 "reentrant call inside %R", self);
280 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000281 }
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200282 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000283 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200284 if (!relax_locking)
285 st = PyThread_acquire_lock(self->lock, 1);
286 else {
287 /* When finalizing, we don't want a deadlock to happen with daemon
288 * threads abruptly shut down while they owned the lock.
289 * Therefore, only wait for a grace period (1 s.).
290 * Note that non-daemon threads have already exited here, so this
291 * shouldn't affect carefully written threaded I/O code.
292 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700293 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200294 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000295 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200296 if (relax_locking && st != PY_LOCK_ACQUIRED) {
297 PyObject *msgobj = PyUnicode_FromFormat(
298 "could not acquire lock for %A at interpreter "
299 "shutdown, possibly due to daemon threads",
300 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200301 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200302 Py_FatalError(msg);
303 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000304 return 1;
305}
306
307#define ENTER_BUFFERED(self) \
308 ( (PyThread_acquire_lock(self->lock, 0) ? \
309 1 : _enter_buffered_busy(self)) \
310 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000311
312#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000313 do { \
314 self->owner = 0; \
315 PyThread_release_lock(self->lock); \
316 } while(0);
317
Georg Brandldfd73442009-04-05 11:47:34 +0000318#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000319#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000320#define LEAVE_BUFFERED(self)
321#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000322
323#define CHECK_INITIALIZED(self) \
324 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000325 if (self->detached) { \
326 PyErr_SetString(PyExc_ValueError, \
327 "raw stream has been detached"); \
328 } else { \
329 PyErr_SetString(PyExc_ValueError, \
330 "I/O operation on uninitialized object"); \
331 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000332 return NULL; \
333 }
334
335#define CHECK_INITIALIZED_INT(self) \
336 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000337 if (self->detached) { \
338 PyErr_SetString(PyExc_ValueError, \
339 "raw stream has been detached"); \
340 } else { \
341 PyErr_SetString(PyExc_ValueError, \
342 "I/O operation on uninitialized object"); \
343 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000344 return -1; \
345 }
346
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000347#define IS_CLOSED(self) \
348 (self->fast_closed_checks \
349 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000350 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000351
352#define CHECK_CLOSED(self, error_msg) \
353 if (IS_CLOSED(self)) { \
354 PyErr_SetString(PyExc_ValueError, error_msg); \
355 return NULL; \
356 }
357
358
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000359#define VALID_READ_BUFFER(self) \
360 (self->readable && self->read_end != -1)
361
362#define VALID_WRITE_BUFFER(self) \
363 (self->writable && self->write_end != -1)
364
365#define ADJUST_POSITION(self, _new_pos) \
366 do { \
367 self->pos = _new_pos; \
368 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
369 self->read_end = self->pos; \
370 } while(0)
371
372#define READAHEAD(self) \
373 ((self->readable && VALID_READ_BUFFER(self)) \
374 ? (self->read_end - self->pos) : 0)
375
376#define RAW_OFFSET(self) \
377 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
378 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
379
380#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000381 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000382
383#define MINUS_LAST_BLOCK(self, size) \
384 (self->buffer_mask ? \
385 (size & ~self->buffer_mask) : \
386 (self->buffer_size * (size / self->buffer_size)))
387
388
389static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000390buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000391{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200392 self->finalizing = 1;
393 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000394 return;
395 _PyObject_GC_UNTRACK(self);
396 self->ok = 0;
397 if (self->weakreflist != NULL)
398 PyObject_ClearWeakRefs((PyObject *)self);
399 Py_CLEAR(self->raw);
400 if (self->buffer) {
401 PyMem_Free(self->buffer);
402 self->buffer = NULL;
403 }
Georg Brandldfd73442009-04-05 11:47:34 +0000404#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000405 if (self->lock) {
406 PyThread_free_lock(self->lock);
407 self->lock = NULL;
408 }
Georg Brandldfd73442009-04-05 11:47:34 +0000409#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000410 Py_CLEAR(self->dict);
411 Py_TYPE(self)->tp_free((PyObject *)self);
412}
413
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200414static PyObject *
415buffered_sizeof(buffered *self, void *unused)
416{
417 Py_ssize_t res;
418
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200419 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200420 if (self->buffer)
421 res += self->buffer_size;
422 return PyLong_FromSsize_t(res);
423}
424
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000426buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000427{
428 Py_VISIT(self->raw);
429 Py_VISIT(self->dict);
430 return 0;
431}
432
433static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000434buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000436 self->ok = 0;
437 Py_CLEAR(self->raw);
438 Py_CLEAR(self->dict);
439 return 0;
440}
441
Antoine Pitroue033e062010-10-29 10:38:18 +0000442/* Because this can call arbitrary code, it shouldn't be called when
443 the refcount is 0 (that is, not directly from tp_dealloc unless
444 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000445static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000446buffered_dealloc_warn(buffered *self, PyObject *source)
447{
448 if (self->ok && self->raw) {
449 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100450 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
451 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000452 if (r)
453 Py_DECREF(r);
454 else
455 PyErr_Clear();
456 }
457 Py_RETURN_NONE;
458}
459
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000460/*
461 * _BufferedIOMixin methods
462 * This is not a class, just a collection of methods that will be reused
463 * by BufferedReader and BufferedWriter
464 */
465
466/* Flush and close */
467
468static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000469buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000470{
471 CHECK_INITIALIZED(self)
472 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
473}
474
475static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000476buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000477{
478 int closed;
479 PyObject *res;
480 CHECK_INITIALIZED_INT(self)
481 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
482 if (res == NULL)
483 return -1;
484 closed = PyObject_IsTrue(res);
485 Py_DECREF(res);
486 return closed;
487}
488
489static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000490buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000491{
492 CHECK_INITIALIZED(self)
493 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
494}
495
496static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498{
Benjamin Peterson68623612012-12-20 11:53:11 -0600499 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000500 int r;
501
502 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000503 if (!ENTER_BUFFERED(self))
504 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000506 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507 if (r < 0)
508 goto end;
509 if (r > 0) {
510 res = Py_None;
511 Py_INCREF(res);
512 goto end;
513 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000514
Antoine Pitrou796564c2013-07-30 19:59:21 +0200515 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000516 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
517 if (r)
518 Py_DECREF(r);
519 else
520 PyErr_Clear();
521 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522 /* flush() will most probably re-take the lock, so drop it first */
523 LEAVE_BUFFERED(self)
524 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000525 if (!ENTER_BUFFERED(self))
526 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600527 if (res == NULL)
528 PyErr_Fetch(&exc, &val, &tb);
529 else
530 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000531
532 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
533
Jesus Ceadc469452012-10-04 12:37:56 +0200534 if (self->buffer) {
535 PyMem_Free(self->buffer);
536 self->buffer = NULL;
537 }
538
Benjamin Peterson68623612012-12-20 11:53:11 -0600539 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300540 _PyErr_ChainExceptions(exc, val, tb);
541 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600542 }
543
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000544end:
545 LEAVE_BUFFERED(self)
546 return res;
547}
548
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000549/* detach */
550
551static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000552buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000553{
554 PyObject *raw, *res;
555 CHECK_INITIALIZED(self)
556 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
557 if (res == NULL)
558 return NULL;
559 Py_DECREF(res);
560 raw = self->raw;
561 self->raw = NULL;
562 self->detached = 1;
563 self->ok = 0;
564 return raw;
565}
566
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000567/* Inquiries */
568
569static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000570buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000571{
572 CHECK_INITIALIZED(self)
573 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
574}
575
576static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000577buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578{
579 CHECK_INITIALIZED(self)
580 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
581}
582
583static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 CHECK_INITIALIZED(self)
587 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
588}
589
590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000591buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200594 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000595}
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200601 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604/* Lower-level APIs */
605
606static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000607buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608{
609 CHECK_INITIALIZED(self)
610 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
611}
612
613static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615{
616 CHECK_INITIALIZED(self)
617 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
618}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000619
Antoine Pitrou243757e2010-11-05 21:15:39 +0000620/* Serialization */
621
622static PyObject *
623buffered_getstate(buffered *self, PyObject *args)
624{
625 PyErr_Format(PyExc_TypeError,
626 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
627 return NULL;
628}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000629
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630/* Forward decls */
631static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100632_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000634_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000638_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200640_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000642_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000643static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000644_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000645static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000646_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200647static Py_ssize_t
648_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649
650/*
651 * Helpers
652 */
653
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100654/* Sets the current error to BlockingIOError */
655static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200656_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100657{
658 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200659 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100660 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
661 errno, msg, written);
662 if (err)
663 PyErr_SetObject(PyExc_BlockingIOError, err);
664 Py_XDECREF(err);
665}
666
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000667/* Returns the address of the `written` member if a BlockingIOError was
668 raised, NULL otherwise. The error is always re-raised. */
669static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000670_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671{
672 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200673 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674
675 PyErr_Fetch(&t, &v, &tb);
676 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
677 PyErr_Restore(t, v, tb);
678 return NULL;
679 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200680 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681 /* TODO: sanity check (err->written >= 0) */
682 PyErr_Restore(t, v, tb);
683 return &err->written;
684}
685
686static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000687_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000690 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
692 if (res == NULL)
693 return -1;
694 n = PyNumber_AsOff_t(res, PyExc_ValueError);
695 Py_DECREF(res);
696 if (n < 0) {
697 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300698 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000699 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200700 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000701 return -1;
702 }
703 self->abs_pos = n;
704 return n;
705}
706
707static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000708_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000709{
710 PyObject *res, *posobj, *whenceobj;
711 Py_off_t n;
712
713 posobj = PyLong_FromOff_t(target);
714 if (posobj == NULL)
715 return -1;
716 whenceobj = PyLong_FromLong(whence);
717 if (whenceobj == NULL) {
718 Py_DECREF(posobj);
719 return -1;
720 }
721 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
722 posobj, whenceobj, NULL);
723 Py_DECREF(posobj);
724 Py_DECREF(whenceobj);
725 if (res == NULL)
726 return -1;
727 n = PyNumber_AsOff_t(res, PyExc_ValueError);
728 Py_DECREF(res);
729 if (n < 0) {
730 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300731 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000732 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200733 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000734 return -1;
735 }
736 self->abs_pos = n;
737 return n;
738}
739
740static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000741_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000742{
743 Py_ssize_t n;
744 if (self->buffer_size <= 0) {
745 PyErr_SetString(PyExc_ValueError,
746 "buffer size must be strictly positive");
747 return -1;
748 }
749 if (self->buffer)
750 PyMem_Free(self->buffer);
751 self->buffer = PyMem_Malloc(self->buffer_size);
752 if (self->buffer == NULL) {
753 PyErr_NoMemory();
754 return -1;
755 }
Georg Brandldfd73442009-04-05 11:47:34 +0000756#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000757 if (self->lock)
758 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000759 self->lock = PyThread_allocate_lock();
760 if (self->lock == NULL) {
761 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
762 return -1;
763 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000764 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000765#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766 /* Find out whether buffer_size is a power of 2 */
767 /* XXX is this optimization useful? */
768 for (n = self->buffer_size - 1; n & 1; n >>= 1)
769 ;
770 if (n == 0)
771 self->buffer_mask = self->buffer_size - 1;
772 else
773 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000774 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000775 PyErr_Clear();
776 return 0;
777}
778
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300779/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000780 clears the error indicator), 0 otherwise.
781 Should only be called when PyErr_Occurred() is true.
782*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700783int
784_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000785{
786 static PyObject *eintr_int = NULL;
787 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300788 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000789
790 if (eintr_int == NULL) {
791 eintr_int = PyLong_FromLong(EINTR);
792 assert(eintr_int != NULL);
793 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300794 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000795 return 0;
796 PyErr_Fetch(&typ, &val, &tb);
797 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300798 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000799 assert(env_err != NULL);
800 if (env_err->myerrno != NULL &&
801 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
802 Py_DECREF(typ);
803 Py_DECREF(val);
804 Py_XDECREF(tb);
805 return 1;
806 }
807 /* This silences any error set by PyObject_RichCompareBool() */
808 PyErr_Restore(typ, val, tb);
809 return 0;
810}
811
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000812/*
813 * Shared methods and wrappers
814 */
815
816static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200817buffered_flush_and_rewind_unlocked(buffered *self)
818{
819 PyObject *res;
820
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100821 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200822 if (res == NULL)
823 return NULL;
824 Py_DECREF(res);
825
826 if (self->readable) {
827 /* Rewind the raw stream so that its position corresponds to
828 the current logical position. */
829 Py_off_t n;
830 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
831 _bufferedreader_reset_buf(self);
832 if (n == -1)
833 return NULL;
834 }
835 Py_RETURN_NONE;
836}
837
838static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000839buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000840{
841 PyObject *res;
842
843 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000844 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000845
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000846 if (!ENTER_BUFFERED(self))
847 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200848 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849 LEAVE_BUFFERED(self)
850
851 return res;
852}
853
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300854/*[clinic input]
855_io._Buffered.peek
856 size: Py_ssize_t = 0
857 /
858
859[clinic start generated code]*/
860
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000861static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300862_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
863/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000864{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000865 PyObject *res = NULL;
866
867 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300868 CHECK_CLOSED(self, "peek of closed file")
869
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000870 if (!ENTER_BUFFERED(self))
871 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000872
873 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200874 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875 if (res == NULL)
876 goto end;
877 Py_CLEAR(res);
878 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200879 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880
881end:
882 LEAVE_BUFFERED(self)
883 return res;
884}
885
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300886/*[clinic input]
887_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300888 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300889 /
890[clinic start generated code]*/
891
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000892static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300893_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300894/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000895{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000896 PyObject *res;
897
898 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899 if (n < -1) {
900 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000901 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902 return NULL;
903 }
904
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000905 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000906
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000907 if (n == -1) {
908 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000909 if (!ENTER_BUFFERED(self))
910 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000911 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000912 }
913 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000914 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200915 if (res != Py_None)
916 return res;
917 Py_DECREF(res);
918 if (!ENTER_BUFFERED(self))
919 return NULL;
920 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000921 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000922
Antoine Pitroue05565e2011-08-20 14:39:23 +0200923 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 return res;
925}
926
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300927/*[clinic input]
928_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000929 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300930 /
931[clinic start generated code]*/
932
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000933static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300934_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000935/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300937 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 PyObject *res = NULL;
939
940 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000941 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000942 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300944
945 CHECK_CLOSED(self, "read of closed file")
946
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947 if (n == 0)
948 return PyBytes_FromStringAndSize(NULL, 0);
949
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950 /* Return up to n bytes. If at least one byte is buffered, we
951 only return buffered bytes. Otherwise, we do one raw read. */
952
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
954 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100955 n = Py_MIN(have, n);
956 res = _bufferedreader_read_fast(self, n);
957 assert(res != Py_None);
958 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100960 res = PyBytes_FromStringAndSize(NULL, n);
961 if (res == NULL)
962 return NULL;
963 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200964 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100965 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200966 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000967 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100968 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
969 LEAVE_BUFFERED(self)
970 if (r == -1) {
971 Py_DECREF(res);
972 return NULL;
973 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000974 if (r == -2)
975 r = 0;
976 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100977 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000978 return res;
979}
980
981static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300982_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200984 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985 PyObject *res = NULL;
986
987 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200988
Antoine Pitrou3486a982011-05-12 01:57:53 +0200989 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
990 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991 if (n >= buffer->len) {
992 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
993 self->pos += buffer->len;
994 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300996 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997 self->pos += n;
998 written = n;
999 }
1000
1001 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001002 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001004 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001005 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001006 if (res == NULL)
1007 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001008 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001009 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001010
1011 _bufferedreader_reset_buf(self);
1012 self->pos = 0;
1013
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001014 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001015 remaining > 0;
1016 written += n, remaining -= n) {
1017 /* If remaining bytes is larger than internal buffer size, copy
1018 * directly into caller's buffer. */
1019 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001020 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001021 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001023
1024 /* In readinto1 mode, we do not want to fill the internal
1025 buffer if we already have some data to return */
1026 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001027 n = _bufferedreader_fill_buffer(self);
1028 if (n > 0) {
1029 if (n > remaining)
1030 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001031 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001032 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001033 self->pos += n;
1034 continue; /* short circuit */
1035 }
1036 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001037 else
1038 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001039
Antoine Pitrou3486a982011-05-12 01:57:53 +02001040 if (n == 0 || (n == -2 && written > 0))
1041 break;
1042 if (n < 0) {
1043 if (n == -2) {
1044 Py_INCREF(Py_None);
1045 res = Py_None;
1046 }
1047 goto end;
1048 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001049
Benjamin Petersona96fea02014-06-22 14:17:44 -07001050 /* At most one read in readinto1 mode */
1051 if (readinto1) {
1052 written += n;
1053 break;
1054 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001055 }
1056 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001057
1058end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001059 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001060 return res;
1061}
1062
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001063/*[clinic input]
1064_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001065 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001066 /
1067[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001068
1069static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001070_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001071/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001072{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001073 return _buffered_readinto_generic(self, buffer, 0);
1074}
1075
1076/*[clinic input]
1077_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001078 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001079 /
1080[clinic start generated code]*/
1081
1082static PyObject *
1083_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001084/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001085{
1086 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001087}
1088
1089
1090static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001091_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001092{
1093 PyObject *res = NULL;
1094 PyObject *chunks = NULL;
1095 Py_ssize_t n, written = 0;
1096 const char *start, *s, *end;
1097
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001098 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001100 /* First, try to find a line in the buffer. This can run unlocked because
1101 the calls to the C API are simple enough that they can't trigger
1102 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001103 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1104 if (limit >= 0 && n > limit)
1105 n = limit;
1106 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001107 s = memchr(start, '\n', n);
1108 if (s != NULL) {
1109 res = PyBytes_FromStringAndSize(start, s - start + 1);
1110 if (res != NULL)
1111 self->pos += s - start + 1;
1112 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113 }
1114 if (n == limit) {
1115 res = PyBytes_FromStringAndSize(start, n);
1116 if (res != NULL)
1117 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001118 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 }
1120
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001121 if (!ENTER_BUFFERED(self))
1122 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001123
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001124 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001125 chunks = PyList_New(0);
1126 if (chunks == NULL)
1127 goto end;
1128 if (n > 0) {
1129 res = PyBytes_FromStringAndSize(start, n);
1130 if (res == NULL)
1131 goto end;
1132 if (PyList_Append(chunks, res) < 0) {
1133 Py_CLEAR(res);
1134 goto end;
1135 }
1136 Py_CLEAR(res);
1137 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001138 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001139 if (limit >= 0)
1140 limit -= n;
1141 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001142 if (self->writable) {
1143 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1144 if (r == NULL)
1145 goto end;
1146 Py_DECREF(r);
1147 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001148
1149 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001150 _bufferedreader_reset_buf(self);
1151 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001152 if (n == -1)
1153 goto end;
1154 if (n <= 0)
1155 break;
1156 if (limit >= 0 && n > limit)
1157 n = limit;
1158 start = self->buffer;
1159 end = start + n;
1160 s = start;
1161 while (s < end) {
1162 if (*s++ == '\n') {
1163 res = PyBytes_FromStringAndSize(start, s - start);
1164 if (res == NULL)
1165 goto end;
1166 self->pos = s - start;
1167 goto found;
1168 }
1169 }
1170 res = PyBytes_FromStringAndSize(start, n);
1171 if (res == NULL)
1172 goto end;
1173 if (n == limit) {
1174 self->pos = n;
1175 break;
1176 }
1177 if (PyList_Append(chunks, res) < 0) {
1178 Py_CLEAR(res);
1179 goto end;
1180 }
1181 Py_CLEAR(res);
1182 written += n;
1183 if (limit >= 0)
1184 limit -= n;
1185 }
1186found:
1187 if (res != NULL && PyList_Append(chunks, res) < 0) {
1188 Py_CLEAR(res);
1189 goto end;
1190 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001191 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192
1193end:
1194 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001195end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001196 Py_XDECREF(chunks);
1197 return res;
1198}
1199
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001200/*[clinic input]
1201_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001202 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001203 /
1204[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001205
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001206static PyObject *
1207_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001208/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001209{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001210 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001211 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001212}
1213
1214
1215static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001216buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217{
1218 Py_off_t pos;
1219
1220 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001221 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222 if (pos == -1)
1223 return NULL;
1224 pos -= RAW_OFFSET(self);
1225 /* TODO: sanity check (pos >= 0) */
1226 return PyLong_FromOff_t(pos);
1227}
1228
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001229/*[clinic input]
1230_io._Buffered.seek
1231 target as targetobj: object
1232 whence: int = 0
1233 /
1234[clinic start generated code]*/
1235
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001236static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001237_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1238/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239{
1240 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001241 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001242
1243 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001244
1245 /* Do some error checking instead of trusting OS 'seek()'
1246 ** error detection, just in case.
1247 */
1248 if ((whence < 0 || whence >2)
1249#ifdef SEEK_HOLE
1250 && (whence != SEEK_HOLE)
1251#endif
1252#ifdef SEEK_DATA
1253 && (whence != SEEK_DATA)
1254#endif
1255 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001257 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001258 return NULL;
1259 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001260
1261 CHECK_CLOSED(self, "seek of closed file")
1262
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001263 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1264 return NULL;
1265
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1267 if (target == -1 && PyErr_Occurred())
1268 return NULL;
1269
Jesus Cea94363612012-06-22 18:32:07 +02001270 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1271 buffer. Other whence values must be managed without this optimization.
1272 Some Operating Systems can provide additional values, like
1273 SEEK_HOLE/SEEK_DATA. */
1274 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275 Py_off_t current, avail;
1276 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001277 so as to return quickly if possible. Also, we needn't take the
1278 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001279 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001280 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1281 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 current = RAW_TELL(self);
1283 avail = READAHEAD(self);
1284 if (avail > 0) {
1285 Py_off_t offset;
1286 if (whence == 0)
1287 offset = target - (current - RAW_OFFSET(self));
1288 else
1289 offset = target;
1290 if (offset >= -self->pos && offset <= avail) {
1291 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001292 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001293 }
1294 }
1295 }
1296
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001297 if (!ENTER_BUFFERED(self))
1298 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001299
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300 /* Fallback: invoke raw seek() method and clear buffer */
1301 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001302 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001303 if (res == NULL)
1304 goto end;
1305 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001306 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307 }
1308
1309 /* TODO: align on block boundary and read buffer if needed? */
1310 if (whence == 1)
1311 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001312 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 if (n == -1)
1314 goto end;
1315 self->raw_pos = -1;
1316 res = PyLong_FromOff_t(n);
1317 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001318 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319
1320end:
1321 LEAVE_BUFFERED(self)
1322 return res;
1323}
1324
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001325/*[clinic input]
1326_io._Buffered.truncate
1327 pos: object = None
1328 /
1329[clinic start generated code]*/
1330
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001332_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1333/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001334{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 PyObject *res = NULL;
1336
1337 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001338 if (!ENTER_BUFFERED(self))
1339 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340
1341 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001342 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343 if (res == NULL)
1344 goto end;
1345 Py_CLEAR(res);
1346 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001347 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1348 if (res == NULL)
1349 goto end;
1350 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001351 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001352 PyErr_Clear();
1353
1354end:
1355 LEAVE_BUFFERED(self)
1356 return res;
1357}
1358
1359static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001360buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361{
1362 PyObject *line;
1363 PyTypeObject *tp;
1364
1365 CHECK_INITIALIZED(self);
1366
1367 tp = Py_TYPE(self);
1368 if (tp == &PyBufferedReader_Type ||
1369 tp == &PyBufferedRandom_Type) {
1370 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001371 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001372 }
1373 else {
1374 line = PyObject_CallMethodObjArgs((PyObject *)self,
1375 _PyIO_str_readline, NULL);
1376 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001377 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001378 "readline() should have returned a bytes object, "
1379 "not '%.200s'", Py_TYPE(line)->tp_name);
1380 Py_DECREF(line);
1381 return NULL;
1382 }
1383 }
1384
1385 if (line == NULL)
1386 return NULL;
1387
1388 if (PyBytes_GET_SIZE(line) == 0) {
1389 /* Reached EOF or would have blocked */
1390 Py_DECREF(line);
1391 return NULL;
1392 }
1393
1394 return line;
1395}
1396
Antoine Pitrou716c4442009-05-23 19:04:03 +00001397static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001398buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001399{
1400 PyObject *nameobj, *res;
1401
Martin v. Löwis767046a2011-10-14 15:35:36 +02001402 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001403 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001404 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001405 PyErr_Clear();
1406 else
1407 return NULL;
1408 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1409 }
1410 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001411 int status = Py_ReprEnter((PyObject *)self);
1412 res = NULL;
1413 if (status == 0) {
1414 res = PyUnicode_FromFormat("<%s name=%R>",
1415 Py_TYPE(self)->tp_name, nameobj);
1416 Py_ReprLeave((PyObject *)self);
1417 }
1418 else if (status > 0) {
1419 PyErr_Format(PyExc_RuntimeError,
1420 "reentrant call inside %s.__repr__",
1421 Py_TYPE(self)->tp_name);
1422 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001423 Py_DECREF(nameobj);
1424 }
1425 return res;
1426}
1427
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001428/*
1429 * class BufferedReader
1430 */
1431
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001432static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001433{
1434 self->read_end = -1;
1435}
1436
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001437/*[clinic input]
1438_io.BufferedReader.__init__
1439 raw: object
1440 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001442Create a new buffered reader using the given readable raw IO object.
1443[clinic start generated code]*/
1444
1445static int
1446_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1447 Py_ssize_t buffer_size)
1448/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1449{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001451 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001452
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001453 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454 return -1;
1455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001456 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001457 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458 self->buffer_size = buffer_size;
1459 self->readable = 1;
1460 self->writable = 0;
1461
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001462 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001464 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001466 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1467 Py_TYPE(raw) == &PyFileIO_Type);
1468
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001469 self->ok = 1;
1470 return 0;
1471}
1472
1473static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001474_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001475{
1476 Py_buffer buf;
1477 PyObject *memobj, *res;
1478 Py_ssize_t n;
1479 /* NOTE: the buffer needn't be released as its object is NULL. */
1480 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1481 return -1;
1482 memobj = PyMemoryView_FromBuffer(&buf);
1483 if (memobj == NULL)
1484 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001485 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1486 occurs so we needn't do it ourselves.
1487 We then retry reading, ignoring the signal if no handler has
1488 raised (see issue #10956).
1489 */
1490 do {
1491 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001492 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001493 Py_DECREF(memobj);
1494 if (res == NULL)
1495 return -1;
1496 if (res == Py_None) {
1497 /* Non-blocking stream would have blocked. Special return code! */
1498 Py_DECREF(res);
1499 return -2;
1500 }
1501 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1502 Py_DECREF(res);
1503 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001504 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001505 "raw readinto() returned invalid length %zd "
1506 "(should have been between 0 and %zd)", n, len);
1507 return -1;
1508 }
1509 if (n > 0 && self->abs_pos != -1)
1510 self->abs_pos += n;
1511 return n;
1512}
1513
1514static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001515_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001516{
1517 Py_ssize_t start, len, n;
1518 if (VALID_READ_BUFFER(self))
1519 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1520 else
1521 start = 0;
1522 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001523 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001524 if (n <= 0)
1525 return n;
1526 self->read_end = start + n;
1527 self->raw_pos = start + n;
1528 return n;
1529}
1530
1531static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001532_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001533{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001534 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001535 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001536
1537 /* First copy what we have in the current buffer. */
1538 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1539 if (current_size) {
1540 data = PyBytes_FromStringAndSize(
1541 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001542 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001543 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001544 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001545 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001546 /* We're going past the buffer's bounds, flush it */
1547 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001548 tmp = buffered_flush_and_rewind_unlocked(self);
1549 if (tmp == NULL)
1550 goto cleanup;
1551 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001552 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001553 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001554
1555 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1557 if (tmp == NULL)
1558 goto cleanup;
1559 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001560 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001561 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001562 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001563 if (tmp == Py_None) {
1564 if (current_size == 0) {
1565 res = Py_None;
1566 goto cleanup;
1567 } else {
1568 res = data;
1569 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001570 }
1571 }
1572 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001573 PyBytes_Concat(&data, tmp);
1574 res = data;
1575 goto cleanup;
1576 }
1577 else {
1578 res = tmp;
1579 goto cleanup;
1580 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001581 }
1582
1583 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001584 if (chunks == NULL)
1585 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001586
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001587 while (1) {
1588 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001589 if (PyList_Append(chunks, data) < 0)
1590 goto cleanup;
1591 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001592 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001593
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594 /* Read until EOF or until read() would block. */
1595 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001596 if (data == NULL)
1597 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001598 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001600 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001601 }
1602 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1603 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001604 res = data;
1605 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001606 }
1607 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001608 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1609 res = tmp;
1610 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611 }
1612 }
1613 current_size += PyBytes_GET_SIZE(data);
1614 if (self->abs_pos != -1)
1615 self->abs_pos += PyBytes_GET_SIZE(data);
1616 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001617cleanup:
1618 /* res is either NULL or a borrowed ref */
1619 Py_XINCREF(res);
1620 Py_XDECREF(data);
1621 Py_XDECREF(tmp);
1622 Py_XDECREF(chunks);
1623 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001624}
1625
1626/* Read n bytes from the buffer if it can, otherwise return None.
1627 This function is simple enough that it can run unlocked. */
1628static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001630{
1631 Py_ssize_t current_size;
1632
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001633 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1634 if (n <= current_size) {
1635 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001636 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1637 if (res != NULL)
1638 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001639 return res;
1640 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001641 Py_RETURN_NONE;
1642}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001643
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001644/* Generic read function: read from the stream until enough bytes are read,
1645 * or until an EOF occurs or until read() would block.
1646 */
1647static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001648_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001649{
1650 PyObject *res = NULL;
1651 Py_ssize_t current_size, remaining, written;
1652 char *out;
1653
1654 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1655 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001656 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001657
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001658 res = PyBytes_FromStringAndSize(NULL, n);
1659 if (res == NULL)
1660 goto error;
1661 out = PyBytes_AS_STRING(res);
1662 remaining = n;
1663 written = 0;
1664 if (current_size > 0) {
1665 memcpy(out, self->buffer + self->pos, current_size);
1666 remaining -= current_size;
1667 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001668 self->pos += current_size;
1669 }
1670 /* Flush the write buffer if necessary */
1671 if (self->writable) {
1672 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1673 if (r == NULL)
1674 goto error;
1675 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001676 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001677 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001678 while (remaining > 0) {
1679 /* We want to read a whole block at the end into buffer.
1680 If we had readv() we could do this in one pass. */
1681 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1682 if (r == 0)
1683 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001684 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685 if (r == -1)
1686 goto error;
1687 if (r == 0 || r == -2) {
1688 /* EOF occurred or read() would block. */
1689 if (r == 0 || written > 0) {
1690 if (_PyBytes_Resize(&res, written))
1691 goto error;
1692 return res;
1693 }
1694 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001695 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001696 }
1697 remaining -= r;
1698 written += r;
1699 }
1700 assert(remaining <= self->buffer_size);
1701 self->pos = 0;
1702 self->raw_pos = 0;
1703 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001704 /* NOTE: when the read is satisfied, we avoid issuing any additional
1705 reads, which could block indefinitely (e.g. on a socket).
1706 See issue #9550. */
1707 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001708 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001709 if (r == -1)
1710 goto error;
1711 if (r == 0 || r == -2) {
1712 /* EOF occurred or read() would block. */
1713 if (r == 0 || written > 0) {
1714 if (_PyBytes_Resize(&res, written))
1715 goto error;
1716 return res;
1717 }
1718 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001719 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001720 }
1721 if (remaining > r) {
1722 memcpy(out + written, self->buffer + self->pos, r);
1723 written += r;
1724 self->pos += r;
1725 remaining -= r;
1726 }
1727 else if (remaining > 0) {
1728 memcpy(out + written, self->buffer + self->pos, remaining);
1729 written += remaining;
1730 self->pos += remaining;
1731 remaining = 0;
1732 }
1733 if (remaining == 0)
1734 break;
1735 }
1736
1737 return res;
1738
1739error:
1740 Py_XDECREF(res);
1741 return NULL;
1742}
1743
1744static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001745_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001746{
1747 Py_ssize_t have, r;
1748
1749 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1750 /* Constraints:
1751 1. we don't want to advance the file position.
1752 2. we don't want to lose block alignment, so we can't shift the buffer
1753 to make some place.
1754 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1755 */
1756 if (have > 0) {
1757 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1758 }
1759
1760 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001761 _bufferedreader_reset_buf(self);
1762 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763 if (r == -1)
1764 return NULL;
1765 if (r == -2)
1766 r = 0;
1767 self->pos = 0;
1768 return PyBytes_FromStringAndSize(self->buffer, r);
1769}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770
1771
Benjamin Peterson59406a92009-03-26 17:10:29 +00001772
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773/*
1774 * class BufferedWriter
1775 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001777_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778{
1779 self->write_pos = 0;
1780 self->write_end = -1;
1781}
1782
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001783/*[clinic input]
1784_io.BufferedWriter.__init__
1785 raw: object
1786 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001788A buffer for a writeable sequential RawIO object.
1789
1790The constructor creates a BufferedWriter for the given writeable raw
1791stream. If the buffer_size is not given, it defaults to
1792DEFAULT_BUFFER_SIZE.
1793[clinic start generated code]*/
1794
1795static int
1796_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1797 Py_ssize_t buffer_size)
1798/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1799{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001801 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001803 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 return -1;
1805
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001807 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001808 self->readable = 0;
1809 self->writable = 1;
1810
1811 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001814 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 self->pos = 0;
1816
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001817 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1818 Py_TYPE(raw) == &PyFileIO_Type);
1819
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 self->ok = 1;
1821 return 0;
1822}
1823
1824static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001825_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001826{
1827 Py_buffer buf;
1828 PyObject *memobj, *res;
1829 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001830 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001831 /* NOTE: the buffer needn't be released as its object is NULL. */
1832 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1833 return -1;
1834 memobj = PyMemoryView_FromBuffer(&buf);
1835 if (memobj == NULL)
1836 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001837 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1838 occurs so we needn't do it ourselves.
1839 We then retry writing, ignoring the signal if no handler has
1840 raised (see issue #10956).
1841 */
1842 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001843 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001844 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001845 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001846 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001847 Py_DECREF(memobj);
1848 if (res == NULL)
1849 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001850 if (res == Py_None) {
1851 /* Non-blocking stream would have blocked. Special return code!
1852 Being paranoid we reset errno in case it is changed by code
1853 triggered by a decref. errno is used by _set_BlockingIOError(). */
1854 Py_DECREF(res);
1855 errno = errnum;
1856 return -2;
1857 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1859 Py_DECREF(res);
1860 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001861 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862 "raw write() returned invalid length %zd "
1863 "(should have been between 0 and %zd)", n, len);
1864 return -1;
1865 }
1866 if (n > 0 && self->abs_pos != -1)
1867 self->abs_pos += n;
1868 return n;
1869}
1870
1871/* `restore_pos` is 1 if we need to restore the raw stream position at
1872 the end, 0 otherwise. */
1873static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001874_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001875{
1876 Py_ssize_t written = 0;
1877 Py_off_t n, rewind;
1878
1879 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1880 goto end;
1881 /* First, rewind */
1882 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1883 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001884 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885 if (n < 0) {
1886 goto error;
1887 }
1888 self->raw_pos -= rewind;
1889 }
1890 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001891 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001892 self->buffer + self->write_pos,
1893 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1894 Py_off_t, Py_ssize_t));
1895 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001896 goto error;
1897 }
1898 else if (n == -2) {
1899 _set_BlockingIOError("write could not complete without blocking",
1900 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001901 goto error;
1902 }
1903 self->write_pos += n;
1904 self->raw_pos = self->write_pos;
1905 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001906 /* Partial writes can return successfully when interrupted by a
1907 signal (see write(2)). We must run signal handlers before
1908 blocking another time, possibly indefinitely. */
1909 if (PyErr_CheckSignals() < 0)
1910 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001911 }
1912
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001913 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001914
1915end:
1916 Py_RETURN_NONE;
1917
1918error:
1919 return NULL;
1920}
1921
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001922/*[clinic input]
1923_io.BufferedWriter.write
1924 buffer: Py_buffer
1925 /
1926[clinic start generated code]*/
1927
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001929_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1930/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001931{
1932 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001933 Py_ssize_t written, avail, remaining;
1934 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935
1936 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001937 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939 return NULL;
1940 }
1941
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001942 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001943 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944
1945 /* Fast path: the data to write can be fully buffered. */
1946 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1947 self->pos = 0;
1948 self->raw_pos = 0;
1949 }
1950 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001951 if (buffer->len <= avail) {
1952 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001953 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 self->write_pos = self->pos;
1955 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001956 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957 if (self->pos > self->write_end)
1958 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001959 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001960 goto end;
1961 }
1962
1963 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001964 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001966 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 if (w == NULL)
1968 goto error;
1969 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001970 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001971 /* Make some place by shifting the buffer. */
1972 assert(VALID_WRITE_BUFFER(self));
1973 memmove(self->buffer, self->buffer + self->write_pos,
1974 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1975 Py_off_t, Py_ssize_t));
1976 self->write_end -= self->write_pos;
1977 self->raw_pos -= self->write_pos;
1978 self->pos -= self->write_pos;
1979 self->write_pos = 0;
1980 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1981 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001982 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001983 /* Everything can be buffered */
1984 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001985 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1986 self->write_end += buffer->len;
1987 self->pos += buffer->len;
1988 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001989 goto end;
1990 }
1991 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001992 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001994 self->pos += avail;
1995 /* XXX Modifying the existing exception e using the pointer w
1996 will change e.characters_written but not e.args[2].
1997 Therefore we just replace with a new error. */
1998 _set_BlockingIOError("write could not complete without blocking",
1999 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000 goto error;
2001 }
2002 Py_CLEAR(res);
2003
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002004 /* Adjust the raw stream position if it is away from the logical stream
2005 position. This happens if the read buffer has been filled but not
2006 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2007 the raw stream by itself).
2008 Fixes issue #6629.
2009 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002010 offset = RAW_OFFSET(self);
2011 if (offset != 0) {
2012 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002013 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002014 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002015 }
2016
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002018 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002019 written = 0;
2020 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002021 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002022 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002023 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002024 goto error;
2025 } else if (n == -2) {
2026 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002027 if (remaining > self->buffer_size) {
2028 /* Can't buffer everything, still buffer as much as possible */
2029 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002030 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002031 self->raw_pos = 0;
2032 ADJUST_POSITION(self, self->buffer_size);
2033 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002034 written += self->buffer_size;
2035 _set_BlockingIOError("write could not complete without "
2036 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 goto error;
2038 }
2039 PyErr_Clear();
2040 break;
2041 }
2042 written += n;
2043 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002044 /* Partial writes can return successfully when interrupted by a
2045 signal (see write(2)). We must run signal handlers before
2046 blocking another time, possibly indefinitely. */
2047 if (PyErr_CheckSignals() < 0)
2048 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002049 }
2050 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002051 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002052 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002053 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 written += remaining;
2055 }
2056 self->write_pos = 0;
2057 /* TODO: sanity check (remaining >= 0) */
2058 self->write_end = remaining;
2059 ADJUST_POSITION(self, remaining);
2060 self->raw_pos = 0;
2061
2062end:
2063 res = PyLong_FromSsize_t(written);
2064
2065error:
2066 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002067 return res;
2068}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002069
2070
2071
2072/*
2073 * BufferedRWPair
2074 */
2075
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076/* XXX The usefulness of this (compared to having two separate IO objects) is
2077 * questionable.
2078 */
2079
2080typedef struct {
2081 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002082 buffered *reader;
2083 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002084 PyObject *dict;
2085 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002086} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002087
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002088/*[clinic input]
2089_io.BufferedRWPair.__init__
2090 reader: object
2091 writer: object
2092 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2093 /
2094
2095A buffered reader and writer object together.
2096
2097A buffered reader object and buffered writer object put together to
2098form a sequential IO object that can read and write. This is typically
2099used with a socket or two-way pipe.
2100
2101reader and writer are RawIOBase objects that are readable and
2102writeable respectively. If the buffer_size is omitted it defaults to
2103DEFAULT_BUFFER_SIZE.
2104[clinic start generated code]*/
2105
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002107_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2108 PyObject *writer, Py_ssize_t buffer_size)
2109/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002111 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002112 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002113 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002114 return -1;
2115
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002116 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002117 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118 if (self->reader == NULL)
2119 return -1;
2120
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002122 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002123 if (self->writer == NULL) {
2124 Py_CLEAR(self->reader);
2125 return -1;
2126 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002127
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128 return 0;
2129}
2130
2131static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002132bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133{
2134 Py_VISIT(self->dict);
2135 return 0;
2136}
2137
2138static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140{
2141 Py_CLEAR(self->reader);
2142 Py_CLEAR(self->writer);
2143 Py_CLEAR(self->dict);
2144 return 0;
2145}
2146
2147static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002148bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149{
2150 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002151 if (self->weakreflist != NULL)
2152 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 Py_CLEAR(self->reader);
2154 Py_CLEAR(self->writer);
2155 Py_CLEAR(self->dict);
2156 Py_TYPE(self)->tp_free((PyObject *) self);
2157}
2158
2159static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002160_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002161{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002162 PyObject *func, *ret;
2163 if (self == NULL) {
2164 PyErr_SetString(PyExc_ValueError,
2165 "I/O operation on uninitialized object");
2166 return NULL;
2167 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002169 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002171 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172 return NULL;
2173 }
2174
2175 ret = PyObject_CallObject(func, args);
2176 Py_DECREF(func);
2177 return ret;
2178}
2179
2180static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002181bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002183 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184}
2185
2186static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002189 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002190}
2191
2192static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002193bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002195 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002196}
2197
2198static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002199bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002200{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002201 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002202}
2203
2204static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002205bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2206{
2207 return _forward_call(self->reader, &PyId_readinto1, args);
2208}
2209
2210static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002211bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002212{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002213 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214}
2215
2216static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002219 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220}
2221
2222static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002225 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226}
2227
2228static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002229bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002231 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002232}
2233
2234static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002235bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002237 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002238 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002240 PyErr_Fetch(&exc, &val, &tb);
2241 else
2242 Py_DECREF(ret);
2243 ret = _forward_call(self->reader, &PyId_close, args);
2244 if (exc != NULL) {
2245 _PyErr_ChainExceptions(exc, val, tb);
2246 Py_CLEAR(ret);
2247 }
2248 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249}
2250
2251static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002252bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002253{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002254 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255
2256 if (ret != Py_False) {
2257 /* either True or exception */
2258 return ret;
2259 }
2260 Py_DECREF(ret);
2261
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002262 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263}
2264
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002265static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002266bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002267{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002268 if (self->writer == NULL) {
2269 PyErr_SetString(PyExc_RuntimeError,
2270 "the BufferedRWPair object is being garbage-collected");
2271 return NULL;
2272 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002273 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2274}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002275
2276
2277
2278/*
2279 * BufferedRandom
2280 */
2281
2282/*[clinic input]
2283_io.BufferedRandom.__init__
2284 raw: object
2285 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2286
2287A buffered interface to random access streams.
2288
2289The constructor creates a reader and writer for a seekable stream,
2290raw, given in the first argument. If the buffer_size is omitted it
2291defaults to DEFAULT_BUFFER_SIZE.
2292[clinic start generated code]*/
2293
2294static int
2295_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2296 Py_ssize_t buffer_size)
2297/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2298{
2299 self->ok = 0;
2300 self->detached = 0;
2301
2302 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2303 return -1;
2304 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2305 return -1;
2306 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2307 return -1;
2308
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002309 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002310 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002311 self->buffer_size = buffer_size;
2312 self->readable = 1;
2313 self->writable = 1;
2314
2315 if (_buffered_init(self) < 0)
2316 return -1;
2317 _bufferedreader_reset_buf(self);
2318 _bufferedwriter_reset_buf(self);
2319 self->pos = 0;
2320
2321 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2322 Py_TYPE(raw) == &PyFileIO_Type);
2323
2324 self->ok = 1;
2325 return 0;
2326}
2327
2328#include "clinic/bufferedio.c.h"
2329
2330
2331static PyMethodDef bufferediobase_methods[] = {
2332 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2333 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2334 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2335 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2336 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2337 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2338 {NULL, NULL}
2339};
2340
2341PyTypeObject PyBufferedIOBase_Type = {
2342 PyVarObject_HEAD_INIT(NULL, 0)
2343 "_io._BufferedIOBase", /*tp_name*/
2344 0, /*tp_basicsize*/
2345 0, /*tp_itemsize*/
2346 0, /*tp_dealloc*/
2347 0, /*tp_print*/
2348 0, /*tp_getattr*/
2349 0, /*tp_setattr*/
2350 0, /*tp_compare */
2351 0, /*tp_repr*/
2352 0, /*tp_as_number*/
2353 0, /*tp_as_sequence*/
2354 0, /*tp_as_mapping*/
2355 0, /*tp_hash */
2356 0, /*tp_call*/
2357 0, /*tp_str*/
2358 0, /*tp_getattro*/
2359 0, /*tp_setattro*/
2360 0, /*tp_as_buffer*/
2361 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2362 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2363 bufferediobase_doc, /* tp_doc */
2364 0, /* tp_traverse */
2365 0, /* tp_clear */
2366 0, /* tp_richcompare */
2367 0, /* tp_weaklistoffset */
2368 0, /* tp_iter */
2369 0, /* tp_iternext */
2370 bufferediobase_methods, /* tp_methods */
2371 0, /* tp_members */
2372 0, /* tp_getset */
2373 &PyIOBase_Type, /* tp_base */
2374 0, /* tp_dict */
2375 0, /* tp_descr_get */
2376 0, /* tp_descr_set */
2377 0, /* tp_dictoffset */
2378 0, /* tp_init */
2379 0, /* tp_alloc */
2380 0, /* tp_new */
2381 0, /* tp_free */
2382 0, /* tp_is_gc */
2383 0, /* tp_bases */
2384 0, /* tp_mro */
2385 0, /* tp_cache */
2386 0, /* tp_subclasses */
2387 0, /* tp_weaklist */
2388 0, /* tp_del */
2389 0, /* tp_version_tag */
2390 0, /* tp_finalize */
2391};
2392
2393
2394static PyMethodDef bufferedreader_methods[] = {
2395 /* BufferedIOMixin methods */
2396 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2397 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2398 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2399 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2400 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002401 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2402 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2403 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2404 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2405
2406 _IO__BUFFERED_READ_METHODDEF
2407 _IO__BUFFERED_PEEK_METHODDEF
2408 _IO__BUFFERED_READ1_METHODDEF
2409 _IO__BUFFERED_READINTO_METHODDEF
2410 _IO__BUFFERED_READINTO1_METHODDEF
2411 _IO__BUFFERED_READLINE_METHODDEF
2412 _IO__BUFFERED_SEEK_METHODDEF
2413 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2414 _IO__BUFFERED_TRUNCATE_METHODDEF
2415 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2416 {NULL, NULL}
2417};
2418
2419static PyMemberDef bufferedreader_members[] = {
2420 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2421 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2422 {NULL}
2423};
2424
2425static PyGetSetDef bufferedreader_getset[] = {
2426 {"closed", (getter)buffered_closed_get, NULL, NULL},
2427 {"name", (getter)buffered_name_get, NULL, NULL},
2428 {"mode", (getter)buffered_mode_get, NULL, NULL},
2429 {NULL}
2430};
2431
2432
2433PyTypeObject PyBufferedReader_Type = {
2434 PyVarObject_HEAD_INIT(NULL, 0)
2435 "_io.BufferedReader", /*tp_name*/
2436 sizeof(buffered), /*tp_basicsize*/
2437 0, /*tp_itemsize*/
2438 (destructor)buffered_dealloc, /*tp_dealloc*/
2439 0, /*tp_print*/
2440 0, /*tp_getattr*/
2441 0, /*tp_setattr*/
2442 0, /*tp_compare */
2443 (reprfunc)buffered_repr, /*tp_repr*/
2444 0, /*tp_as_number*/
2445 0, /*tp_as_sequence*/
2446 0, /*tp_as_mapping*/
2447 0, /*tp_hash */
2448 0, /*tp_call*/
2449 0, /*tp_str*/
2450 0, /*tp_getattro*/
2451 0, /*tp_setattro*/
2452 0, /*tp_as_buffer*/
2453 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2454 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2455 _io_BufferedReader___init____doc__, /* tp_doc */
2456 (traverseproc)buffered_traverse, /* tp_traverse */
2457 (inquiry)buffered_clear, /* tp_clear */
2458 0, /* tp_richcompare */
2459 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2460 0, /* tp_iter */
2461 (iternextfunc)buffered_iternext, /* tp_iternext */
2462 bufferedreader_methods, /* tp_methods */
2463 bufferedreader_members, /* tp_members */
2464 bufferedreader_getset, /* tp_getset */
2465 0, /* tp_base */
2466 0, /* tp_dict */
2467 0, /* tp_descr_get */
2468 0, /* tp_descr_set */
2469 offsetof(buffered, dict), /* tp_dictoffset */
2470 _io_BufferedReader___init__, /* tp_init */
2471 0, /* tp_alloc */
2472 PyType_GenericNew, /* tp_new */
2473 0, /* tp_free */
2474 0, /* tp_is_gc */
2475 0, /* tp_bases */
2476 0, /* tp_mro */
2477 0, /* tp_cache */
2478 0, /* tp_subclasses */
2479 0, /* tp_weaklist */
2480 0, /* tp_del */
2481 0, /* tp_version_tag */
2482 0, /* tp_finalize */
2483};
2484
2485
2486static PyMethodDef bufferedwriter_methods[] = {
2487 /* BufferedIOMixin methods */
2488 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2489 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2490 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002491 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2492 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2493 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2494 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2495 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2496
2497 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2498 _IO__BUFFERED_TRUNCATE_METHODDEF
2499 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2500 _IO__BUFFERED_SEEK_METHODDEF
2501 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2502 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2503 {NULL, NULL}
2504};
2505
2506static PyMemberDef bufferedwriter_members[] = {
2507 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2508 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2509 {NULL}
2510};
2511
2512static PyGetSetDef bufferedwriter_getset[] = {
2513 {"closed", (getter)buffered_closed_get, NULL, NULL},
2514 {"name", (getter)buffered_name_get, NULL, NULL},
2515 {"mode", (getter)buffered_mode_get, NULL, NULL},
2516 {NULL}
2517};
2518
2519
2520PyTypeObject PyBufferedWriter_Type = {
2521 PyVarObject_HEAD_INIT(NULL, 0)
2522 "_io.BufferedWriter", /*tp_name*/
2523 sizeof(buffered), /*tp_basicsize*/
2524 0, /*tp_itemsize*/
2525 (destructor)buffered_dealloc, /*tp_dealloc*/
2526 0, /*tp_print*/
2527 0, /*tp_getattr*/
2528 0, /*tp_setattr*/
2529 0, /*tp_compare */
2530 (reprfunc)buffered_repr, /*tp_repr*/
2531 0, /*tp_as_number*/
2532 0, /*tp_as_sequence*/
2533 0, /*tp_as_mapping*/
2534 0, /*tp_hash */
2535 0, /*tp_call*/
2536 0, /*tp_str*/
2537 0, /*tp_getattro*/
2538 0, /*tp_setattro*/
2539 0, /*tp_as_buffer*/
2540 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2541 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2542 _io_BufferedWriter___init____doc__, /* tp_doc */
2543 (traverseproc)buffered_traverse, /* tp_traverse */
2544 (inquiry)buffered_clear, /* tp_clear */
2545 0, /* tp_richcompare */
2546 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2547 0, /* tp_iter */
2548 0, /* tp_iternext */
2549 bufferedwriter_methods, /* tp_methods */
2550 bufferedwriter_members, /* tp_members */
2551 bufferedwriter_getset, /* tp_getset */
2552 0, /* tp_base */
2553 0, /* tp_dict */
2554 0, /* tp_descr_get */
2555 0, /* tp_descr_set */
2556 offsetof(buffered, dict), /* tp_dictoffset */
2557 _io_BufferedWriter___init__, /* tp_init */
2558 0, /* tp_alloc */
2559 PyType_GenericNew, /* tp_new */
2560 0, /* tp_free */
2561 0, /* tp_is_gc */
2562 0, /* tp_bases */
2563 0, /* tp_mro */
2564 0, /* tp_cache */
2565 0, /* tp_subclasses */
2566 0, /* tp_weaklist */
2567 0, /* tp_del */
2568 0, /* tp_version_tag */
2569 0, /* tp_finalize */
2570};
2571
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573static PyMethodDef bufferedrwpair_methods[] = {
2574 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2575 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2576 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2577 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002578 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2581 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002583 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2584 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002585
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002586 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2587 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002588
Antoine Pitrou243757e2010-11-05 21:15:39 +00002589 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2590
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002591 {NULL, NULL}
2592};
2593
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002594static PyGetSetDef bufferedrwpair_getset[] = {
2595 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002596 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002597};
2598
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002599PyTypeObject PyBufferedRWPair_Type = {
2600 PyVarObject_HEAD_INIT(NULL, 0)
2601 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002602 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002603 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002604 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002605 0, /*tp_print*/
2606 0, /*tp_getattr*/
2607 0, /*tp_setattr*/
2608 0, /*tp_compare */
2609 0, /*tp_repr*/
2610 0, /*tp_as_number*/
2611 0, /*tp_as_sequence*/
2612 0, /*tp_as_mapping*/
2613 0, /*tp_hash */
2614 0, /*tp_call*/
2615 0, /*tp_str*/
2616 0, /*tp_getattro*/
2617 0, /*tp_setattro*/
2618 0, /*tp_as_buffer*/
2619 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002620 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002621 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2623 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002624 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002625 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002626 0, /* tp_iter */
2627 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002628 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002630 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002631 0, /* tp_base */
2632 0, /* tp_dict */
2633 0, /* tp_descr_get */
2634 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002635 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002636 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002637 0, /* tp_alloc */
2638 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002639 0, /* tp_free */
2640 0, /* tp_is_gc */
2641 0, /* tp_bases */
2642 0, /* tp_mro */
2643 0, /* tp_cache */
2644 0, /* tp_subclasses */
2645 0, /* tp_weaklist */
2646 0, /* tp_del */
2647 0, /* tp_version_tag */
2648 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002649};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650
2651
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002652static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002653 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002654 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2655 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2656 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2657 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2658 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2659 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2660 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002661 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002662 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002664 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002665
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002666 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002667 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002668 _IO__BUFFERED_TRUNCATE_METHODDEF
2669 _IO__BUFFERED_READ_METHODDEF
2670 _IO__BUFFERED_READ1_METHODDEF
2671 _IO__BUFFERED_READINTO_METHODDEF
2672 _IO__BUFFERED_READINTO1_METHODDEF
2673 _IO__BUFFERED_READLINE_METHODDEF
2674 _IO__BUFFERED_PEEK_METHODDEF
2675 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002676 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002677 {NULL, NULL}
2678};
2679
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002680static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002681 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002682 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002683 {NULL}
2684};
2685
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002686static PyGetSetDef bufferedrandom_getset[] = {
2687 {"closed", (getter)buffered_closed_get, NULL, NULL},
2688 {"name", (getter)buffered_name_get, NULL, NULL},
2689 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002690 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002691};
2692
2693
2694PyTypeObject PyBufferedRandom_Type = {
2695 PyVarObject_HEAD_INIT(NULL, 0)
2696 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002697 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002698 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002699 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002700 0, /*tp_print*/
2701 0, /*tp_getattr*/
2702 0, /*tp_setattr*/
2703 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002704 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002705 0, /*tp_as_number*/
2706 0, /*tp_as_sequence*/
2707 0, /*tp_as_mapping*/
2708 0, /*tp_hash */
2709 0, /*tp_call*/
2710 0, /*tp_str*/
2711 0, /*tp_getattro*/
2712 0, /*tp_setattro*/
2713 0, /*tp_as_buffer*/
2714 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002715 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002716 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002717 (traverseproc)buffered_traverse, /* tp_traverse */
2718 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002720 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002721 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002722 (iternextfunc)buffered_iternext, /* tp_iternext */
2723 bufferedrandom_methods, /* tp_methods */
2724 bufferedrandom_members, /* tp_members */
2725 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002726 0, /* tp_base */
2727 0, /*tp_dict*/
2728 0, /* tp_descr_get */
2729 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002730 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002731 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002732 0, /* tp_alloc */
2733 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002734 0, /* tp_free */
2735 0, /* tp_is_gc */
2736 0, /* tp_bases */
2737 0, /* tp_mro */
2738 0, /* tp_cache */
2739 0, /* tp_subclasses */
2740 0, /* tp_weaklist */
2741 0, /* tp_del */
2742 0, /* tp_version_tag */
2743 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002744};