blob: ba0932c5d819b4cf8adffb0d781476a2d9cfd28c [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030016/*[clinic input]
17module _io
18class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24[clinic start generated code]*/
25/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020027_Py_IDENTIFIER(close);
28_Py_IDENTIFIER(_dealloc_warn);
29_Py_IDENTIFIER(flush);
30_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020031_Py_IDENTIFIER(mode);
32_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020033_Py_IDENTIFIER(peek);
34_Py_IDENTIFIER(read);
35_Py_IDENTIFIER(read1);
36_Py_IDENTIFIER(readable);
37_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070038_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020039_Py_IDENTIFIER(writable);
40_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042/*
43 * BufferedIOBase class, inherits from IOBase.
44 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000045PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000046 "Base class for buffered IO objects.\n"
47 "\n"
48 "The main difference with RawIOBase is that the read() method\n"
49 "supports omitting the size argument, and does not have a default\n"
50 "implementation that defers to readinto().\n"
51 "\n"
52 "In addition, read(), readinto() and write() may raise\n"
53 "BlockingIOError if the underlying raw stream is in non-blocking\n"
54 "mode and not ready; unlike their raw counterparts, they will never\n"
55 "return None.\n"
56 "\n"
57 "A typical implementation should not inherit from a RawIOBase\n"
58 "implementation, but wrap one.\n"
59 );
60
61static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030062_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000063{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064 Py_ssize_t len;
65 PyObject *data;
66
Benjamin Petersona96fea02014-06-22 14:17:44 -070067 data = _PyObject_CallMethodId(self,
68 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030069 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030071 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000072
73 if (!PyBytes_Check(data)) {
74 Py_DECREF(data);
75 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030076 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 }
78
Serhiy Storchakafff9a312017-03-21 08:53:25 +020079 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030080 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030081 PyErr_Format(PyExc_ValueError,
82 "read() returned too much data: "
83 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030084 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030085 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030086 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030087 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030088 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090 Py_DECREF(data);
91
92 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000093}
94
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030095/*[clinic input]
96_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070097 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030098 /
99[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700100
101static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300102_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700103/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700104{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300105 return _bufferediobase_readinto_generic(self, buffer, 0);
106}
107
108/*[clinic input]
109_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700110 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300111 /
112[clinic start generated code]*/
113
114static PyObject *
115_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700116/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300117{
118 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700119}
120
121static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000122bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000123{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100124 _PyIO_State *state = IO_STATE();
125 if (state != NULL)
126 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000127 return NULL;
128}
129
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300130/*[clinic input]
131_io._BufferedIOBase.detach
132
133Disconnect this buffer from its underlying raw stream and return it.
134
135After the raw stream has been detached, the buffer is in an unusable
136state.
137[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000138
139static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300140_io__BufferedIOBase_detach_impl(PyObject *self)
141/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000142{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000143 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000144}
145
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000146PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000147 "Read and return up to n bytes.\n"
148 "\n"
149 "If the argument is omitted, None, or negative, reads and\n"
150 "returns all data until EOF.\n"
151 "\n"
152 "If the argument is positive, and the underlying raw stream is\n"
153 "not 'interactive', multiple raw reads may be issued to satisfy\n"
154 "the byte count (unless EOF is reached first). But for\n"
155 "interactive raw streams (as well as sockets and pipes), at most\n"
156 "one raw read will be issued, and a short result does not imply\n"
157 "that EOF is imminent.\n"
158 "\n"
159 "Returns an empty bytes object on EOF.\n"
160 "\n"
161 "Returns None if the underlying raw stream was open in non-blocking\n"
162 "mode and no data is available at the moment.\n");
163
164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000166{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000167 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000168}
169
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000170PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171 "Read and return up to n bytes, with at most one read() call\n"
172 "to the underlying raw stream. A short result does not imply\n"
173 "that EOF is imminent.\n"
174 "\n"
175 "Returns an empty bytes object on EOF.\n");
176
177static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000178bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000179{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000180 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181}
182
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000183PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000184 "Write the given buffer to the IO stream.\n"
185 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000186 "Returns the number of bytes written, which is always the length of b\n"
187 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188 "\n"
189 "Raises BlockingIOError if the buffer is full and the\n"
190 "underlying raw stream cannot accept more data at the moment.\n");
191
192static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000193bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000194{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000195 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000196}
197
198
Neil Schemenauerdb564232017-09-04 22:13:17 -0700199typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000200 PyObject_HEAD
201
202 PyObject *raw;
203 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000204 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000205 int readable;
206 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200207 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200208
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000209 /* True if this is a vanilla Buffered object (rather than a user derived
210 class) *and* the raw stream is a vanilla FileIO object. */
211 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212
213 /* Absolute position inside the raw stream (-1 if unknown). */
214 Py_off_t abs_pos;
215
216 /* A static buffer of size `buffer_size` */
217 char *buffer;
218 /* Current logical position in the buffer. */
219 Py_off_t pos;
220 /* Position of the raw stream in the buffer. */
221 Py_off_t raw_pos;
222
223 /* Just after the last buffered byte in the buffer, or -1 if the buffer
224 isn't ready for reading. */
225 Py_off_t read_end;
226
227 /* Just after the last byte actually written */
228 Py_off_t write_pos;
229 /* Just after the last byte waiting to be written, or -1 if the buffer
230 isn't ready for writing. */
231 Py_off_t write_end;
232
233 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200234 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000235
236 Py_ssize_t buffer_size;
237 Py_ssize_t buffer_mask;
238
239 PyObject *dict;
240 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000241} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000242
243/*
244 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000246 * BufferedReader, BufferedWriter and BufferedRandom try to share most
247 methods (this is helped by the members `readable` and `writable`, which
248 are initialized in the respective constructors)
249 * They also share a single buffer for reading and writing. This enables
250 interleaved reads and writes without flushing. It also makes the logic
251 a bit trickier to get right.
252 * The absolute position of the raw stream is cached, if possible, in the
253 `abs_pos` member. It must be updated every time an operation is done
254 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000255 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000256 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000257 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
258 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000259
260 NOTE: we should try to maintain block alignment of reads and writes to the
261 raw stream (according to the buffer size), but for now it is only done
262 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200263
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000264*/
265
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000266/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000267
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000268static int
269_enter_buffered_busy(buffered *self)
270{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200271 int relax_locking;
272 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000273 if (self->owner == PyThread_get_thread_ident()) {
274 PyErr_Format(PyExc_RuntimeError,
275 "reentrant call inside %R", self);
276 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000277 }
Eric Snow05351c12017-09-05 21:43:08 -0700278 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000279 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200280 if (!relax_locking)
281 st = PyThread_acquire_lock(self->lock, 1);
282 else {
283 /* When finalizing, we don't want a deadlock to happen with daemon
284 * threads abruptly shut down while they owned the lock.
285 * Therefore, only wait for a grace period (1 s.).
286 * Note that non-daemon threads have already exited here, so this
287 * shouldn't affect carefully written threaded I/O code.
288 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700289 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200290 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000291 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200292 if (relax_locking && st != PY_LOCK_ACQUIRED) {
293 PyObject *msgobj = PyUnicode_FromFormat(
294 "could not acquire lock for %A at interpreter "
295 "shutdown, possibly due to daemon threads",
296 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200297 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200298 Py_FatalError(msg);
299 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000300 return 1;
301}
302
303#define ENTER_BUFFERED(self) \
304 ( (PyThread_acquire_lock(self->lock, 0) ? \
305 1 : _enter_buffered_busy(self)) \
306 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000307
308#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000309 do { \
310 self->owner = 0; \
311 PyThread_release_lock(self->lock); \
312 } while(0);
313
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000314#define CHECK_INITIALIZED(self) \
315 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000316 if (self->detached) { \
317 PyErr_SetString(PyExc_ValueError, \
318 "raw stream has been detached"); \
319 } else { \
320 PyErr_SetString(PyExc_ValueError, \
321 "I/O operation on uninitialized object"); \
322 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000323 return NULL; \
324 }
325
326#define CHECK_INITIALIZED_INT(self) \
327 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000328 if (self->detached) { \
329 PyErr_SetString(PyExc_ValueError, \
330 "raw stream has been detached"); \
331 } else { \
332 PyErr_SetString(PyExc_ValueError, \
333 "I/O operation on uninitialized object"); \
334 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000335 return -1; \
336 }
337
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000338#define IS_CLOSED(self) \
339 (self->fast_closed_checks \
340 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000341 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000342
343#define CHECK_CLOSED(self, error_msg) \
344 if (IS_CLOSED(self)) { \
345 PyErr_SetString(PyExc_ValueError, error_msg); \
346 return NULL; \
347 }
348
349
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000350#define VALID_READ_BUFFER(self) \
351 (self->readable && self->read_end != -1)
352
353#define VALID_WRITE_BUFFER(self) \
354 (self->writable && self->write_end != -1)
355
356#define ADJUST_POSITION(self, _new_pos) \
357 do { \
358 self->pos = _new_pos; \
359 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
360 self->read_end = self->pos; \
361 } while(0)
362
363#define READAHEAD(self) \
364 ((self->readable && VALID_READ_BUFFER(self)) \
365 ? (self->read_end - self->pos) : 0)
366
367#define RAW_OFFSET(self) \
368 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
369 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
370
371#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000372 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000373
374#define MINUS_LAST_BLOCK(self, size) \
375 (self->buffer_mask ? \
376 (size & ~self->buffer_mask) : \
377 (self->buffer_size * (size / self->buffer_size)))
378
379
380static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000381buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000382{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200383 self->finalizing = 1;
384 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385 return;
386 _PyObject_GC_UNTRACK(self);
387 self->ok = 0;
388 if (self->weakreflist != NULL)
389 PyObject_ClearWeakRefs((PyObject *)self);
390 Py_CLEAR(self->raw);
391 if (self->buffer) {
392 PyMem_Free(self->buffer);
393 self->buffer = NULL;
394 }
395 if (self->lock) {
396 PyThread_free_lock(self->lock);
397 self->lock = NULL;
398 }
399 Py_CLEAR(self->dict);
400 Py_TYPE(self)->tp_free((PyObject *)self);
401}
402
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200403static PyObject *
404buffered_sizeof(buffered *self, void *unused)
405{
406 Py_ssize_t res;
407
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200408 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200409 if (self->buffer)
410 res += self->buffer_size;
411 return PyLong_FromSsize_t(res);
412}
413
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000414static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000415buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000416{
417 Py_VISIT(self->raw);
418 Py_VISIT(self->dict);
419 return 0;
420}
421
422static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000423buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000424{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425 self->ok = 0;
426 Py_CLEAR(self->raw);
427 Py_CLEAR(self->dict);
428 return 0;
429}
430
Antoine Pitroue033e062010-10-29 10:38:18 +0000431/* Because this can call arbitrary code, it shouldn't be called when
432 the refcount is 0 (that is, not directly from tp_dealloc unless
433 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000434static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000435buffered_dealloc_warn(buffered *self, PyObject *source)
436{
437 if (self->ok && self->raw) {
438 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100439 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
440 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000441 if (r)
442 Py_DECREF(r);
443 else
444 PyErr_Clear();
445 }
446 Py_RETURN_NONE;
447}
448
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000449/*
450 * _BufferedIOMixin methods
451 * This is not a class, just a collection of methods that will be reused
452 * by BufferedReader and BufferedWriter
453 */
454
455/* Flush and close */
456
457static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000458buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000459{
460 CHECK_INITIALIZED(self)
461 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
462}
463
464static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000465buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466{
467 int closed;
468 PyObject *res;
469 CHECK_INITIALIZED_INT(self)
470 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
471 if (res == NULL)
472 return -1;
473 closed = PyObject_IsTrue(res);
474 Py_DECREF(res);
475 return closed;
476}
477
478static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000479buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000480{
481 CHECK_INITIALIZED(self)
482 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
483}
484
485static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000486buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487{
Benjamin Peterson68623612012-12-20 11:53:11 -0600488 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489 int r;
490
491 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000492 if (!ENTER_BUFFERED(self))
493 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000494
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000495 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000496 if (r < 0)
497 goto end;
498 if (r > 0) {
499 res = Py_None;
500 Py_INCREF(res);
501 goto end;
502 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000503
Antoine Pitrou796564c2013-07-30 19:59:21 +0200504 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000505 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
506 if (r)
507 Py_DECREF(r);
508 else
509 PyErr_Clear();
510 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511 /* flush() will most probably re-take the lock, so drop it first */
512 LEAVE_BUFFERED(self)
513 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000514 if (!ENTER_BUFFERED(self))
515 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600516 if (res == NULL)
517 PyErr_Fetch(&exc, &val, &tb);
518 else
519 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000520
521 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
522
Jesus Ceadc469452012-10-04 12:37:56 +0200523 if (self->buffer) {
524 PyMem_Free(self->buffer);
525 self->buffer = NULL;
526 }
527
Benjamin Peterson68623612012-12-20 11:53:11 -0600528 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300529 _PyErr_ChainExceptions(exc, val, tb);
530 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600531 }
532
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000533end:
534 LEAVE_BUFFERED(self)
535 return res;
536}
537
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000538/* detach */
539
540static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000541buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000542{
543 PyObject *raw, *res;
544 CHECK_INITIALIZED(self)
545 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
546 if (res == NULL)
547 return NULL;
548 Py_DECREF(res);
549 raw = self->raw;
550 self->raw = NULL;
551 self->detached = 1;
552 self->ok = 0;
553 return raw;
554}
555
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000556/* Inquiries */
557
558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000560{
561 CHECK_INITIALIZED(self)
562 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
563}
564
565static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000566buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000567{
568 CHECK_INITIALIZED(self)
569 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
570}
571
572static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000573buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574{
575 CHECK_INITIALIZED(self)
576 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
577}
578
579static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000580buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000581{
582 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200583 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584}
585
586static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000587buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000588{
589 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200590 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591}
592
593/* Lower-level APIs */
594
595static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000596buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597{
598 CHECK_INITIALIZED(self)
599 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
600}
601
602static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000603buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604{
605 CHECK_INITIALIZED(self)
606 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
607}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000608
Antoine Pitrou243757e2010-11-05 21:15:39 +0000609/* Serialization */
610
611static PyObject *
612buffered_getstate(buffered *self, PyObject *args)
613{
614 PyErr_Format(PyExc_TypeError,
615 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
616 return NULL;
617}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000618
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619/* Forward decls */
620static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100621_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000623_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000624static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000626static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000628static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200629_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000630static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000631_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000632static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000633_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000634static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000635_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200636static Py_ssize_t
637_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000638
639/*
640 * Helpers
641 */
642
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100643/* Sets the current error to BlockingIOError */
644static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200645_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100646{
647 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200648 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100649 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
650 errno, msg, written);
651 if (err)
652 PyErr_SetObject(PyExc_BlockingIOError, err);
653 Py_XDECREF(err);
654}
655
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656/* Returns the address of the `written` member if a BlockingIOError was
657 raised, NULL otherwise. The error is always re-raised. */
658static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000659_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660{
661 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200662 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000663
664 PyErr_Fetch(&t, &v, &tb);
665 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
666 PyErr_Restore(t, v, tb);
667 return NULL;
668 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200669 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000670 /* TODO: sanity check (err->written >= 0) */
671 PyErr_Restore(t, v, tb);
672 return &err->written;
673}
674
675static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000676_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000679 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
681 if (res == NULL)
682 return -1;
683 n = PyNumber_AsOff_t(res, PyExc_ValueError);
684 Py_DECREF(res);
685 if (n < 0) {
686 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300687 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000688 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200689 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690 return -1;
691 }
692 self->abs_pos = n;
693 return n;
694}
695
696static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000697_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698{
699 PyObject *res, *posobj, *whenceobj;
700 Py_off_t n;
701
702 posobj = PyLong_FromOff_t(target);
703 if (posobj == NULL)
704 return -1;
705 whenceobj = PyLong_FromLong(whence);
706 if (whenceobj == NULL) {
707 Py_DECREF(posobj);
708 return -1;
709 }
710 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
711 posobj, whenceobj, NULL);
712 Py_DECREF(posobj);
713 Py_DECREF(whenceobj);
714 if (res == NULL)
715 return -1;
716 n = PyNumber_AsOff_t(res, PyExc_ValueError);
717 Py_DECREF(res);
718 if (n < 0) {
719 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300720 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000721 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200722 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723 return -1;
724 }
725 self->abs_pos = n;
726 return n;
727}
728
729static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000730_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731{
732 Py_ssize_t n;
733 if (self->buffer_size <= 0) {
734 PyErr_SetString(PyExc_ValueError,
735 "buffer size must be strictly positive");
736 return -1;
737 }
738 if (self->buffer)
739 PyMem_Free(self->buffer);
740 self->buffer = PyMem_Malloc(self->buffer_size);
741 if (self->buffer == NULL) {
742 PyErr_NoMemory();
743 return -1;
744 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000745 if (self->lock)
746 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000747 self->lock = PyThread_allocate_lock();
748 if (self->lock == NULL) {
749 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
750 return -1;
751 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000752 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000753 /* Find out whether buffer_size is a power of 2 */
754 /* XXX is this optimization useful? */
755 for (n = self->buffer_size - 1; n & 1; n >>= 1)
756 ;
757 if (n == 0)
758 self->buffer_mask = self->buffer_size - 1;
759 else
760 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000761 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000762 PyErr_Clear();
763 return 0;
764}
765
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300766/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000767 clears the error indicator), 0 otherwise.
768 Should only be called when PyErr_Occurred() is true.
769*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700770int
771_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000772{
773 static PyObject *eintr_int = NULL;
774 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300775 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000776
777 if (eintr_int == NULL) {
778 eintr_int = PyLong_FromLong(EINTR);
779 assert(eintr_int != NULL);
780 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300781 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000782 return 0;
783 PyErr_Fetch(&typ, &val, &tb);
784 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300785 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000786 assert(env_err != NULL);
787 if (env_err->myerrno != NULL &&
788 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
789 Py_DECREF(typ);
790 Py_DECREF(val);
791 Py_XDECREF(tb);
792 return 1;
793 }
794 /* This silences any error set by PyObject_RichCompareBool() */
795 PyErr_Restore(typ, val, tb);
796 return 0;
797}
798
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000799/*
800 * Shared methods and wrappers
801 */
802
803static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200804buffered_flush_and_rewind_unlocked(buffered *self)
805{
806 PyObject *res;
807
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100808 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200809 if (res == NULL)
810 return NULL;
811 Py_DECREF(res);
812
813 if (self->readable) {
814 /* Rewind the raw stream so that its position corresponds to
815 the current logical position. */
816 Py_off_t n;
817 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
818 _bufferedreader_reset_buf(self);
819 if (n == -1)
820 return NULL;
821 }
822 Py_RETURN_NONE;
823}
824
825static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000826buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000827{
828 PyObject *res;
829
830 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000831 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000832
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000833 if (!ENTER_BUFFERED(self))
834 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200835 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000836 LEAVE_BUFFERED(self)
837
838 return res;
839}
840
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300841/*[clinic input]
842_io._Buffered.peek
843 size: Py_ssize_t = 0
844 /
845
846[clinic start generated code]*/
847
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000848static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300849_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
850/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852 PyObject *res = NULL;
853
854 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300855 CHECK_CLOSED(self, "peek of closed file")
856
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000857 if (!ENTER_BUFFERED(self))
858 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859
860 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200861 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000862 if (res == NULL)
863 goto end;
864 Py_CLEAR(res);
865 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200866 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000867
868end:
869 LEAVE_BUFFERED(self)
870 return res;
871}
872
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300873/*[clinic input]
874_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300875 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300876 /
877[clinic start generated code]*/
878
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000879static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300880_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300881/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000883 PyObject *res;
884
885 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886 if (n < -1) {
887 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000888 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889 return NULL;
890 }
891
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000892 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000893
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000894 if (n == -1) {
895 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000896 if (!ENTER_BUFFERED(self))
897 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000898 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000899 }
900 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000901 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200902 if (res != Py_None)
903 return res;
904 Py_DECREF(res);
905 if (!ENTER_BUFFERED(self))
906 return NULL;
907 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000908 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909
Antoine Pitroue05565e2011-08-20 14:39:23 +0200910 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000911 return res;
912}
913
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300914/*[clinic input]
915_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000916 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300917 /
918[clinic start generated code]*/
919
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000920static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300921_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000922/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300924 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000925 PyObject *res = NULL;
926
927 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000928 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000929 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300931
932 CHECK_CLOSED(self, "read of closed file")
933
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000934 if (n == 0)
935 return PyBytes_FromStringAndSize(NULL, 0);
936
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000937 /* Return up to n bytes. If at least one byte is buffered, we
938 only return buffered bytes. Otherwise, we do one raw read. */
939
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
941 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100942 n = Py_MIN(have, n);
943 res = _bufferedreader_read_fast(self, n);
944 assert(res != Py_None);
945 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000946 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100947 res = PyBytes_FromStringAndSize(NULL, n);
948 if (res == NULL)
949 return NULL;
950 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200951 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100952 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200953 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000954 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100955 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
956 LEAVE_BUFFERED(self)
957 if (r == -1) {
958 Py_DECREF(res);
959 return NULL;
960 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961 if (r == -2)
962 r = 0;
963 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100964 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000965 return res;
966}
967
968static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300969_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000970{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200971 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 PyObject *res = NULL;
973
974 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200975
Antoine Pitrou3486a982011-05-12 01:57:53 +0200976 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
977 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300978 if (n >= buffer->len) {
979 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
980 self->pos += buffer->len;
981 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200982 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300983 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200984 self->pos += n;
985 written = n;
986 }
987
988 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300989 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200990
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000991 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200992 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993 if (res == NULL)
994 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000996 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997
998 _bufferedreader_reset_buf(self);
999 self->pos = 0;
1000
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001001 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 remaining > 0;
1003 written += n, remaining -= n) {
1004 /* If remaining bytes is larger than internal buffer size, copy
1005 * directly into caller's buffer. */
1006 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001007 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001008 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001009 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001010
1011 /* In readinto1 mode, we do not want to fill the internal
1012 buffer if we already have some data to return */
1013 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001014 n = _bufferedreader_fill_buffer(self);
1015 if (n > 0) {
1016 if (n > remaining)
1017 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001018 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001019 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001020 self->pos += n;
1021 continue; /* short circuit */
1022 }
1023 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001024 else
1025 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001026
Antoine Pitrou3486a982011-05-12 01:57:53 +02001027 if (n == 0 || (n == -2 && written > 0))
1028 break;
1029 if (n < 0) {
1030 if (n == -2) {
1031 Py_INCREF(Py_None);
1032 res = Py_None;
1033 }
1034 goto end;
1035 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001036
Benjamin Petersona96fea02014-06-22 14:17:44 -07001037 /* At most one read in readinto1 mode */
1038 if (readinto1) {
1039 written += n;
1040 break;
1041 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001042 }
1043 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001044
1045end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001046 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 return res;
1048}
1049
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001050/*[clinic input]
1051_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001052 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001053 /
1054[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001055
1056static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001057_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001058/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001059{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001060 return _buffered_readinto_generic(self, buffer, 0);
1061}
1062
1063/*[clinic input]
1064_io._Buffered.readinto1
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]*/
1068
1069static PyObject *
1070_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001071/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001072{
1073 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001074}
1075
1076
1077static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001078_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001079{
1080 PyObject *res = NULL;
1081 PyObject *chunks = NULL;
1082 Py_ssize_t n, written = 0;
1083 const char *start, *s, *end;
1084
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001085 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001086
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001087 /* First, try to find a line in the buffer. This can run unlocked because
1088 the calls to the C API are simple enough that they can't trigger
1089 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1091 if (limit >= 0 && n > limit)
1092 n = limit;
1093 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001094 s = memchr(start, '\n', n);
1095 if (s != NULL) {
1096 res = PyBytes_FromStringAndSize(start, s - start + 1);
1097 if (res != NULL)
1098 self->pos += s - start + 1;
1099 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100 }
1101 if (n == limit) {
1102 res = PyBytes_FromStringAndSize(start, n);
1103 if (res != NULL)
1104 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001105 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106 }
1107
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001108 if (!ENTER_BUFFERED(self))
1109 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001110
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001111 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001112 chunks = PyList_New(0);
1113 if (chunks == NULL)
1114 goto end;
1115 if (n > 0) {
1116 res = PyBytes_FromStringAndSize(start, n);
1117 if (res == NULL)
1118 goto end;
1119 if (PyList_Append(chunks, res) < 0) {
1120 Py_CLEAR(res);
1121 goto end;
1122 }
1123 Py_CLEAR(res);
1124 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001125 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126 if (limit >= 0)
1127 limit -= n;
1128 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001129 if (self->writable) {
1130 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1131 if (r == NULL)
1132 goto end;
1133 Py_DECREF(r);
1134 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001135
1136 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001137 _bufferedreader_reset_buf(self);
1138 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001139 if (n == -1)
1140 goto end;
1141 if (n <= 0)
1142 break;
1143 if (limit >= 0 && n > limit)
1144 n = limit;
1145 start = self->buffer;
1146 end = start + n;
1147 s = start;
1148 while (s < end) {
1149 if (*s++ == '\n') {
1150 res = PyBytes_FromStringAndSize(start, s - start);
1151 if (res == NULL)
1152 goto end;
1153 self->pos = s - start;
1154 goto found;
1155 }
1156 }
1157 res = PyBytes_FromStringAndSize(start, n);
1158 if (res == NULL)
1159 goto end;
1160 if (n == limit) {
1161 self->pos = n;
1162 break;
1163 }
1164 if (PyList_Append(chunks, res) < 0) {
1165 Py_CLEAR(res);
1166 goto end;
1167 }
1168 Py_CLEAR(res);
1169 written += n;
1170 if (limit >= 0)
1171 limit -= n;
1172 }
1173found:
1174 if (res != NULL && PyList_Append(chunks, res) < 0) {
1175 Py_CLEAR(res);
1176 goto end;
1177 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001178 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001179
1180end:
1181 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001182end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183 Py_XDECREF(chunks);
1184 return res;
1185}
1186
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001187/*[clinic input]
1188_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001189 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001190 /
1191[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001193static PyObject *
1194_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001195/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001196{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001198 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199}
1200
1201
1202static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001203buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204{
1205 Py_off_t pos;
1206
1207 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001208 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209 if (pos == -1)
1210 return NULL;
1211 pos -= RAW_OFFSET(self);
1212 /* TODO: sanity check (pos >= 0) */
1213 return PyLong_FromOff_t(pos);
1214}
1215
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001216/*[clinic input]
1217_io._Buffered.seek
1218 target as targetobj: object
1219 whence: int = 0
1220 /
1221[clinic start generated code]*/
1222
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001223static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001224_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1225/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226{
1227 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001228 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001229
1230 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001231
1232 /* Do some error checking instead of trusting OS 'seek()'
1233 ** error detection, just in case.
1234 */
1235 if ((whence < 0 || whence >2)
1236#ifdef SEEK_HOLE
1237 && (whence != SEEK_HOLE)
1238#endif
1239#ifdef SEEK_DATA
1240 && (whence != SEEK_DATA)
1241#endif
1242 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001244 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245 return NULL;
1246 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001247
1248 CHECK_CLOSED(self, "seek of closed file")
1249
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001250 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1251 return NULL;
1252
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001253 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1254 if (target == -1 && PyErr_Occurred())
1255 return NULL;
1256
Jesus Cea94363612012-06-22 18:32:07 +02001257 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1258 buffer. Other whence values must be managed without this optimization.
1259 Some Operating Systems can provide additional values, like
1260 SEEK_HOLE/SEEK_DATA. */
1261 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262 Py_off_t current, avail;
1263 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001264 so as to return quickly if possible. Also, we needn't take the
1265 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001267 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1268 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001269 current = RAW_TELL(self);
1270 avail = READAHEAD(self);
1271 if (avail > 0) {
1272 Py_off_t offset;
1273 if (whence == 0)
1274 offset = target - (current - RAW_OFFSET(self));
1275 else
1276 offset = target;
1277 if (offset >= -self->pos && offset <= avail) {
1278 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001279 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001280 }
1281 }
1282 }
1283
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001284 if (!ENTER_BUFFERED(self))
1285 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001286
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001287 /* Fallback: invoke raw seek() method and clear buffer */
1288 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001289 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290 if (res == NULL)
1291 goto end;
1292 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001293 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001294 }
1295
1296 /* TODO: align on block boundary and read buffer if needed? */
1297 if (whence == 1)
1298 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001299 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300 if (n == -1)
1301 goto end;
1302 self->raw_pos = -1;
1303 res = PyLong_FromOff_t(n);
1304 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001305 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001306
1307end:
1308 LEAVE_BUFFERED(self)
1309 return res;
1310}
1311
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001312/*[clinic input]
1313_io._Buffered.truncate
1314 pos: object = None
1315 /
1316[clinic start generated code]*/
1317
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001318static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001319_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1320/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 PyObject *res = NULL;
1323
1324 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001325 if (!ENTER_BUFFERED(self))
1326 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001327
1328 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001329 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330 if (res == NULL)
1331 goto end;
1332 Py_CLEAR(res);
1333 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001334 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1335 if (res == NULL)
1336 goto end;
1337 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001338 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339 PyErr_Clear();
1340
1341end:
1342 LEAVE_BUFFERED(self)
1343 return res;
1344}
1345
1346static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001347buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001348{
1349 PyObject *line;
1350 PyTypeObject *tp;
1351
1352 CHECK_INITIALIZED(self);
1353
1354 tp = Py_TYPE(self);
1355 if (tp == &PyBufferedReader_Type ||
1356 tp == &PyBufferedRandom_Type) {
1357 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001358 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359 }
1360 else {
1361 line = PyObject_CallMethodObjArgs((PyObject *)self,
1362 _PyIO_str_readline, NULL);
1363 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001364 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001365 "readline() should have returned a bytes object, "
1366 "not '%.200s'", Py_TYPE(line)->tp_name);
1367 Py_DECREF(line);
1368 return NULL;
1369 }
1370 }
1371
1372 if (line == NULL)
1373 return NULL;
1374
1375 if (PyBytes_GET_SIZE(line) == 0) {
1376 /* Reached EOF or would have blocked */
1377 Py_DECREF(line);
1378 return NULL;
1379 }
1380
1381 return line;
1382}
1383
Antoine Pitrou716c4442009-05-23 19:04:03 +00001384static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001385buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001386{
1387 PyObject *nameobj, *res;
1388
Martin v. Löwis767046a2011-10-14 15:35:36 +02001389 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001390 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001391 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001392 PyErr_Clear();
1393 else
1394 return NULL;
1395 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1396 }
1397 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001398 int status = Py_ReprEnter((PyObject *)self);
1399 res = NULL;
1400 if (status == 0) {
1401 res = PyUnicode_FromFormat("<%s name=%R>",
1402 Py_TYPE(self)->tp_name, nameobj);
1403 Py_ReprLeave((PyObject *)self);
1404 }
1405 else if (status > 0) {
1406 PyErr_Format(PyExc_RuntimeError,
1407 "reentrant call inside %s.__repr__",
1408 Py_TYPE(self)->tp_name);
1409 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001410 Py_DECREF(nameobj);
1411 }
1412 return res;
1413}
1414
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001415/*
1416 * class BufferedReader
1417 */
1418
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001419static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001420{
1421 self->read_end = -1;
1422}
1423
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001424/*[clinic input]
1425_io.BufferedReader.__init__
1426 raw: object
1427 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001428
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001429Create a new buffered reader using the given readable raw IO object.
1430[clinic start generated code]*/
1431
1432static int
1433_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1434 Py_ssize_t buffer_size)
1435/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1436{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001438 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001439
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001440 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441 return -1;
1442
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001444 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001445 self->buffer_size = buffer_size;
1446 self->readable = 1;
1447 self->writable = 0;
1448
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001449 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001451 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001452
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001453 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1454 Py_TYPE(raw) == &PyFileIO_Type);
1455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001456 self->ok = 1;
1457 return 0;
1458}
1459
1460static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001461_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462{
1463 Py_buffer buf;
1464 PyObject *memobj, *res;
1465 Py_ssize_t n;
1466 /* NOTE: the buffer needn't be released as its object is NULL. */
1467 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1468 return -1;
1469 memobj = PyMemoryView_FromBuffer(&buf);
1470 if (memobj == NULL)
1471 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001472 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1473 occurs so we needn't do it ourselves.
1474 We then retry reading, ignoring the signal if no handler has
1475 raised (see issue #10956).
1476 */
1477 do {
1478 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001479 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001480 Py_DECREF(memobj);
1481 if (res == NULL)
1482 return -1;
1483 if (res == Py_None) {
1484 /* Non-blocking stream would have blocked. Special return code! */
1485 Py_DECREF(res);
1486 return -2;
1487 }
1488 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1489 Py_DECREF(res);
1490 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001491 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001492 "raw readinto() returned invalid length %zd "
1493 "(should have been between 0 and %zd)", n, len);
1494 return -1;
1495 }
1496 if (n > 0 && self->abs_pos != -1)
1497 self->abs_pos += n;
1498 return n;
1499}
1500
1501static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001502_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001503{
1504 Py_ssize_t start, len, n;
1505 if (VALID_READ_BUFFER(self))
1506 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1507 else
1508 start = 0;
1509 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001510 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001511 if (n <= 0)
1512 return n;
1513 self->read_end = start + n;
1514 self->raw_pos = start + n;
1515 return n;
1516}
1517
1518static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001519_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001520{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001521 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001522 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001523
1524 /* First copy what we have in the current buffer. */
1525 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1526 if (current_size) {
1527 data = PyBytes_FromStringAndSize(
1528 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001529 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001530 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001531 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001533 /* We're going past the buffer's bounds, flush it */
1534 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001535 tmp = buffered_flush_and_rewind_unlocked(self);
1536 if (tmp == NULL)
1537 goto cleanup;
1538 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001539 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001540 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001541
1542 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001543 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1544 if (tmp == NULL)
1545 goto cleanup;
1546 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001547 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001548 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001549 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001550 if (tmp == Py_None) {
1551 if (current_size == 0) {
1552 res = Py_None;
1553 goto cleanup;
1554 } else {
1555 res = data;
1556 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001557 }
1558 }
1559 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001560 PyBytes_Concat(&data, tmp);
1561 res = data;
1562 goto cleanup;
1563 }
1564 else {
1565 res = tmp;
1566 goto cleanup;
1567 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001568 }
1569
1570 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001571 if (chunks == NULL)
1572 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001573
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001574 while (1) {
1575 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001576 if (PyList_Append(chunks, data) < 0)
1577 goto cleanup;
1578 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001579 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001580
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001581 /* Read until EOF or until read() would block. */
1582 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001583 if (data == NULL)
1584 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001585 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001587 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001588 }
1589 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1590 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001591 res = data;
1592 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001593 }
1594 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001595 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1596 res = tmp;
1597 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001598 }
1599 }
1600 current_size += PyBytes_GET_SIZE(data);
1601 if (self->abs_pos != -1)
1602 self->abs_pos += PyBytes_GET_SIZE(data);
1603 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001604cleanup:
1605 /* res is either NULL or a borrowed ref */
1606 Py_XINCREF(res);
1607 Py_XDECREF(data);
1608 Py_XDECREF(tmp);
1609 Py_XDECREF(chunks);
1610 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611}
1612
1613/* Read n bytes from the buffer if it can, otherwise return None.
1614 This function is simple enough that it can run unlocked. */
1615static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001616_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001617{
1618 Py_ssize_t current_size;
1619
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1621 if (n <= current_size) {
1622 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001623 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1624 if (res != NULL)
1625 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001626 return res;
1627 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001628 Py_RETURN_NONE;
1629}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001631/* Generic read function: read from the stream until enough bytes are read,
1632 * or until an EOF occurs or until read() would block.
1633 */
1634static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001635_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001636{
1637 PyObject *res = NULL;
1638 Py_ssize_t current_size, remaining, written;
1639 char *out;
1640
1641 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1642 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001643 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001644
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001645 res = PyBytes_FromStringAndSize(NULL, n);
1646 if (res == NULL)
1647 goto error;
1648 out = PyBytes_AS_STRING(res);
1649 remaining = n;
1650 written = 0;
1651 if (current_size > 0) {
1652 memcpy(out, self->buffer + self->pos, current_size);
1653 remaining -= current_size;
1654 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001655 self->pos += current_size;
1656 }
1657 /* Flush the write buffer if necessary */
1658 if (self->writable) {
1659 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1660 if (r == NULL)
1661 goto error;
1662 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001663 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001664 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001665 while (remaining > 0) {
1666 /* We want to read a whole block at the end into buffer.
1667 If we had readv() we could do this in one pass. */
1668 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1669 if (r == 0)
1670 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001671 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001672 if (r == -1)
1673 goto error;
1674 if (r == 0 || r == -2) {
1675 /* EOF occurred or read() would block. */
1676 if (r == 0 || written > 0) {
1677 if (_PyBytes_Resize(&res, written))
1678 goto error;
1679 return res;
1680 }
1681 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001682 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683 }
1684 remaining -= r;
1685 written += r;
1686 }
1687 assert(remaining <= self->buffer_size);
1688 self->pos = 0;
1689 self->raw_pos = 0;
1690 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001691 /* NOTE: when the read is satisfied, we avoid issuing any additional
1692 reads, which could block indefinitely (e.g. on a socket).
1693 See issue #9550. */
1694 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001695 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001696 if (r == -1)
1697 goto error;
1698 if (r == 0 || r == -2) {
1699 /* EOF occurred or read() would block. */
1700 if (r == 0 || written > 0) {
1701 if (_PyBytes_Resize(&res, written))
1702 goto error;
1703 return res;
1704 }
1705 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001706 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001707 }
1708 if (remaining > r) {
1709 memcpy(out + written, self->buffer + self->pos, r);
1710 written += r;
1711 self->pos += r;
1712 remaining -= r;
1713 }
1714 else if (remaining > 0) {
1715 memcpy(out + written, self->buffer + self->pos, remaining);
1716 written += remaining;
1717 self->pos += remaining;
1718 remaining = 0;
1719 }
1720 if (remaining == 0)
1721 break;
1722 }
1723
1724 return res;
1725
1726error:
1727 Py_XDECREF(res);
1728 return NULL;
1729}
1730
1731static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001732_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001733{
1734 Py_ssize_t have, r;
1735
1736 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1737 /* Constraints:
1738 1. we don't want to advance the file position.
1739 2. we don't want to lose block alignment, so we can't shift the buffer
1740 to make some place.
1741 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1742 */
1743 if (have > 0) {
1744 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1745 }
1746
1747 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001748 _bufferedreader_reset_buf(self);
1749 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750 if (r == -1)
1751 return NULL;
1752 if (r == -2)
1753 r = 0;
1754 self->pos = 0;
1755 return PyBytes_FromStringAndSize(self->buffer, r);
1756}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001757
1758
Benjamin Peterson59406a92009-03-26 17:10:29 +00001759
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001760/*
1761 * class BufferedWriter
1762 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001764_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001765{
1766 self->write_pos = 0;
1767 self->write_end = -1;
1768}
1769
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001770/*[clinic input]
1771_io.BufferedWriter.__init__
1772 raw: object
1773 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001775A buffer for a writeable sequential RawIO object.
1776
1777The constructor creates a BufferedWriter for the given writeable raw
1778stream. If the buffer_size is not given, it defaults to
1779DEFAULT_BUFFER_SIZE.
1780[clinic start generated code]*/
1781
1782static int
1783_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1784 Py_ssize_t buffer_size)
1785/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1786{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001788 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001790 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791 return -1;
1792
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001794 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001795 self->readable = 0;
1796 self->writable = 1;
1797
1798 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001799 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001801 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802 self->pos = 0;
1803
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001804 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1805 Py_TYPE(raw) == &PyFileIO_Type);
1806
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807 self->ok = 1;
1808 return 0;
1809}
1810
1811static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813{
1814 Py_buffer buf;
1815 PyObject *memobj, *res;
1816 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001817 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818 /* NOTE: the buffer needn't be released as its object is NULL. */
1819 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1820 return -1;
1821 memobj = PyMemoryView_FromBuffer(&buf);
1822 if (memobj == NULL)
1823 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001824 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1825 occurs so we needn't do it ourselves.
1826 We then retry writing, ignoring the signal if no handler has
1827 raised (see issue #10956).
1828 */
1829 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001830 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001831 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001832 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001833 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834 Py_DECREF(memobj);
1835 if (res == NULL)
1836 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001837 if (res == Py_None) {
1838 /* Non-blocking stream would have blocked. Special return code!
1839 Being paranoid we reset errno in case it is changed by code
1840 triggered by a decref. errno is used by _set_BlockingIOError(). */
1841 Py_DECREF(res);
1842 errno = errnum;
1843 return -2;
1844 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001845 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1846 Py_DECREF(res);
1847 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001848 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001849 "raw write() returned invalid length %zd "
1850 "(should have been between 0 and %zd)", n, len);
1851 return -1;
1852 }
1853 if (n > 0 && self->abs_pos != -1)
1854 self->abs_pos += n;
1855 return n;
1856}
1857
1858/* `restore_pos` is 1 if we need to restore the raw stream position at
1859 the end, 0 otherwise. */
1860static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001861_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862{
1863 Py_ssize_t written = 0;
1864 Py_off_t n, rewind;
1865
1866 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1867 goto end;
1868 /* First, rewind */
1869 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1870 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001871 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001872 if (n < 0) {
1873 goto error;
1874 }
1875 self->raw_pos -= rewind;
1876 }
1877 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001878 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001879 self->buffer + self->write_pos,
1880 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1881 Py_off_t, Py_ssize_t));
1882 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001883 goto error;
1884 }
1885 else if (n == -2) {
1886 _set_BlockingIOError("write could not complete without blocking",
1887 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001888 goto error;
1889 }
1890 self->write_pos += n;
1891 self->raw_pos = self->write_pos;
1892 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001893 /* Partial writes can return successfully when interrupted by a
1894 signal (see write(2)). We must run signal handlers before
1895 blocking another time, possibly indefinitely. */
1896 if (PyErr_CheckSignals() < 0)
1897 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898 }
1899
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001900 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001901
1902end:
1903 Py_RETURN_NONE;
1904
1905error:
1906 return NULL;
1907}
1908
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001909/*[clinic input]
1910_io.BufferedWriter.write
1911 buffer: Py_buffer
1912 /
1913[clinic start generated code]*/
1914
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001915static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001916_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1917/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918{
1919 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001920 Py_ssize_t written, avail, remaining;
1921 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001922
1923 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001924 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001925 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926 return NULL;
1927 }
1928
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001929 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001930 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001931
1932 /* Fast path: the data to write can be fully buffered. */
1933 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1934 self->pos = 0;
1935 self->raw_pos = 0;
1936 }
1937 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001938 if (buffer->len <= avail) {
1939 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001940 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941 self->write_pos = self->pos;
1942 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001943 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001944 if (self->pos > self->write_end)
1945 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001946 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001947 goto end;
1948 }
1949
1950 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001951 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001953 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954 if (w == NULL)
1955 goto error;
1956 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001957 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 /* Make some place by shifting the buffer. */
1959 assert(VALID_WRITE_BUFFER(self));
1960 memmove(self->buffer, self->buffer + self->write_pos,
1961 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1962 Py_off_t, Py_ssize_t));
1963 self->write_end -= self->write_pos;
1964 self->raw_pos -= self->write_pos;
1965 self->pos -= self->write_pos;
1966 self->write_pos = 0;
1967 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1968 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001969 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 /* Everything can be buffered */
1971 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001972 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1973 self->write_end += buffer->len;
1974 self->pos += buffer->len;
1975 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976 goto end;
1977 }
1978 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001979 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001980 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001981 self->pos += avail;
1982 /* XXX Modifying the existing exception e using the pointer w
1983 will change e.characters_written but not e.args[2].
1984 Therefore we just replace with a new error. */
1985 _set_BlockingIOError("write could not complete without blocking",
1986 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001987 goto error;
1988 }
1989 Py_CLEAR(res);
1990
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001991 /* Adjust the raw stream position if it is away from the logical stream
1992 position. This happens if the read buffer has been filled but not
1993 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1994 the raw stream by itself).
1995 Fixes issue #6629.
1996 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001997 offset = RAW_OFFSET(self);
1998 if (offset != 0) {
1999 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002000 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002001 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002002 }
2003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002005 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002006 written = 0;
2007 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002008 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002009 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002011 goto error;
2012 } else if (n == -2) {
2013 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002014 if (remaining > self->buffer_size) {
2015 /* Can't buffer everything, still buffer as much as possible */
2016 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002017 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 self->raw_pos = 0;
2019 ADJUST_POSITION(self, self->buffer_size);
2020 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002021 written += self->buffer_size;
2022 _set_BlockingIOError("write could not complete without "
2023 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 goto error;
2025 }
2026 PyErr_Clear();
2027 break;
2028 }
2029 written += n;
2030 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002031 /* Partial writes can return successfully when interrupted by a
2032 signal (see write(2)). We must run signal handlers before
2033 blocking another time, possibly indefinitely. */
2034 if (PyErr_CheckSignals() < 0)
2035 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002036 }
2037 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002038 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002039 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002040 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 written += remaining;
2042 }
2043 self->write_pos = 0;
2044 /* TODO: sanity check (remaining >= 0) */
2045 self->write_end = remaining;
2046 ADJUST_POSITION(self, remaining);
2047 self->raw_pos = 0;
2048
2049end:
2050 res = PyLong_FromSsize_t(written);
2051
2052error:
2053 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 return res;
2055}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056
2057
2058
2059/*
2060 * BufferedRWPair
2061 */
2062
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002063/* XXX The usefulness of this (compared to having two separate IO objects) is
2064 * questionable.
2065 */
2066
2067typedef struct {
2068 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002069 buffered *reader;
2070 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002071 PyObject *dict;
2072 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002073} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002075/*[clinic input]
2076_io.BufferedRWPair.__init__
2077 reader: object
2078 writer: object
2079 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2080 /
2081
2082A buffered reader and writer object together.
2083
2084A buffered reader object and buffered writer object put together to
2085form a sequential IO object that can read and write. This is typically
2086used with a socket or two-way pipe.
2087
2088reader and writer are RawIOBase objects that are readable and
2089writeable respectively. If the buffer_size is omitted it defaults to
2090DEFAULT_BUFFER_SIZE.
2091[clinic start generated code]*/
2092
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002093static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002094_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2095 PyObject *writer, Py_ssize_t buffer_size)
2096/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002098 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002099 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002100 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002101 return -1;
2102
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002103 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002104 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002105 if (self->reader == NULL)
2106 return -1;
2107
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002108 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002109 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110 if (self->writer == NULL) {
2111 Py_CLEAR(self->reader);
2112 return -1;
2113 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002114
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002115 return 0;
2116}
2117
2118static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002119bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002120{
2121 Py_VISIT(self->dict);
2122 return 0;
2123}
2124
2125static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002127{
2128 Py_CLEAR(self->reader);
2129 Py_CLEAR(self->writer);
2130 Py_CLEAR(self->dict);
2131 return 0;
2132}
2133
2134static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002135bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002136{
2137 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002138 if (self->weakreflist != NULL)
2139 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140 Py_CLEAR(self->reader);
2141 Py_CLEAR(self->writer);
2142 Py_CLEAR(self->dict);
2143 Py_TYPE(self)->tp_free((PyObject *) self);
2144}
2145
2146static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002147_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002149 PyObject *func, *ret;
2150 if (self == NULL) {
2151 PyErr_SetString(PyExc_ValueError,
2152 "I/O operation on uninitialized object");
2153 return NULL;
2154 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002156 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002157 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002158 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 return NULL;
2160 }
2161
2162 ret = PyObject_CallObject(func, args);
2163 Py_DECREF(func);
2164 return ret;
2165}
2166
2167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002170 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171}
2172
2173static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002174bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002176 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177}
2178
2179static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002182 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183}
2184
2185static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002186bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002187{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002188 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002189}
2190
2191static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002192bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2193{
2194 return _forward_call(self->reader, &PyId_readinto1, args);
2195}
2196
2197static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002198bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002199{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002200 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201}
2202
2203static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002204bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002206 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207}
2208
2209static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002210bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002212 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213}
2214
2215static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002216bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002217{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002218 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219}
2220
2221static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002224 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002225 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002226 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002227 PyErr_Fetch(&exc, &val, &tb);
2228 else
2229 Py_DECREF(ret);
2230 ret = _forward_call(self->reader, &PyId_close, args);
2231 if (exc != NULL) {
2232 _PyErr_ChainExceptions(exc, val, tb);
2233 Py_CLEAR(ret);
2234 }
2235 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236}
2237
2238static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002239bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002241 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242
2243 if (ret != Py_False) {
2244 /* either True or exception */
2245 return ret;
2246 }
2247 Py_DECREF(ret);
2248
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002249 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002250}
2251
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002252static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002253bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002254{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002255 if (self->writer == NULL) {
2256 PyErr_SetString(PyExc_RuntimeError,
2257 "the BufferedRWPair object is being garbage-collected");
2258 return NULL;
2259 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002260 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2261}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002262
2263
2264
2265/*
2266 * BufferedRandom
2267 */
2268
2269/*[clinic input]
2270_io.BufferedRandom.__init__
2271 raw: object
2272 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2273
2274A buffered interface to random access streams.
2275
2276The constructor creates a reader and writer for a seekable stream,
2277raw, given in the first argument. If the buffer_size is omitted it
2278defaults to DEFAULT_BUFFER_SIZE.
2279[clinic start generated code]*/
2280
2281static int
2282_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2283 Py_ssize_t buffer_size)
2284/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2285{
2286 self->ok = 0;
2287 self->detached = 0;
2288
2289 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2290 return -1;
2291 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2292 return -1;
2293 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2294 return -1;
2295
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002296 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002297 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002298 self->buffer_size = buffer_size;
2299 self->readable = 1;
2300 self->writable = 1;
2301
2302 if (_buffered_init(self) < 0)
2303 return -1;
2304 _bufferedreader_reset_buf(self);
2305 _bufferedwriter_reset_buf(self);
2306 self->pos = 0;
2307
2308 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2309 Py_TYPE(raw) == &PyFileIO_Type);
2310
2311 self->ok = 1;
2312 return 0;
2313}
2314
2315#include "clinic/bufferedio.c.h"
2316
2317
2318static PyMethodDef bufferediobase_methods[] = {
2319 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2320 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2321 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2322 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2323 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2324 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2325 {NULL, NULL}
2326};
2327
2328PyTypeObject PyBufferedIOBase_Type = {
2329 PyVarObject_HEAD_INIT(NULL, 0)
2330 "_io._BufferedIOBase", /*tp_name*/
2331 0, /*tp_basicsize*/
2332 0, /*tp_itemsize*/
2333 0, /*tp_dealloc*/
2334 0, /*tp_print*/
2335 0, /*tp_getattr*/
2336 0, /*tp_setattr*/
2337 0, /*tp_compare */
2338 0, /*tp_repr*/
2339 0, /*tp_as_number*/
2340 0, /*tp_as_sequence*/
2341 0, /*tp_as_mapping*/
2342 0, /*tp_hash */
2343 0, /*tp_call*/
2344 0, /*tp_str*/
2345 0, /*tp_getattro*/
2346 0, /*tp_setattro*/
2347 0, /*tp_as_buffer*/
2348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2349 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2350 bufferediobase_doc, /* tp_doc */
2351 0, /* tp_traverse */
2352 0, /* tp_clear */
2353 0, /* tp_richcompare */
2354 0, /* tp_weaklistoffset */
2355 0, /* tp_iter */
2356 0, /* tp_iternext */
2357 bufferediobase_methods, /* tp_methods */
2358 0, /* tp_members */
2359 0, /* tp_getset */
2360 &PyIOBase_Type, /* tp_base */
2361 0, /* tp_dict */
2362 0, /* tp_descr_get */
2363 0, /* tp_descr_set */
2364 0, /* tp_dictoffset */
2365 0, /* tp_init */
2366 0, /* tp_alloc */
2367 0, /* tp_new */
2368 0, /* tp_free */
2369 0, /* tp_is_gc */
2370 0, /* tp_bases */
2371 0, /* tp_mro */
2372 0, /* tp_cache */
2373 0, /* tp_subclasses */
2374 0, /* tp_weaklist */
2375 0, /* tp_del */
2376 0, /* tp_version_tag */
2377 0, /* tp_finalize */
2378};
2379
2380
2381static PyMethodDef bufferedreader_methods[] = {
2382 /* BufferedIOMixin methods */
2383 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2384 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2385 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2386 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2387 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002388 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2389 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2390 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2391 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2392
2393 _IO__BUFFERED_READ_METHODDEF
2394 _IO__BUFFERED_PEEK_METHODDEF
2395 _IO__BUFFERED_READ1_METHODDEF
2396 _IO__BUFFERED_READINTO_METHODDEF
2397 _IO__BUFFERED_READINTO1_METHODDEF
2398 _IO__BUFFERED_READLINE_METHODDEF
2399 _IO__BUFFERED_SEEK_METHODDEF
2400 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2401 _IO__BUFFERED_TRUNCATE_METHODDEF
2402 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2403 {NULL, NULL}
2404};
2405
2406static PyMemberDef bufferedreader_members[] = {
2407 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2408 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2409 {NULL}
2410};
2411
2412static PyGetSetDef bufferedreader_getset[] = {
2413 {"closed", (getter)buffered_closed_get, NULL, NULL},
2414 {"name", (getter)buffered_name_get, NULL, NULL},
2415 {"mode", (getter)buffered_mode_get, NULL, NULL},
2416 {NULL}
2417};
2418
2419
2420PyTypeObject PyBufferedReader_Type = {
2421 PyVarObject_HEAD_INIT(NULL, 0)
2422 "_io.BufferedReader", /*tp_name*/
2423 sizeof(buffered), /*tp_basicsize*/
2424 0, /*tp_itemsize*/
2425 (destructor)buffered_dealloc, /*tp_dealloc*/
2426 0, /*tp_print*/
2427 0, /*tp_getattr*/
2428 0, /*tp_setattr*/
2429 0, /*tp_compare */
2430 (reprfunc)buffered_repr, /*tp_repr*/
2431 0, /*tp_as_number*/
2432 0, /*tp_as_sequence*/
2433 0, /*tp_as_mapping*/
2434 0, /*tp_hash */
2435 0, /*tp_call*/
2436 0, /*tp_str*/
2437 0, /*tp_getattro*/
2438 0, /*tp_setattro*/
2439 0, /*tp_as_buffer*/
2440 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2441 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2442 _io_BufferedReader___init____doc__, /* tp_doc */
2443 (traverseproc)buffered_traverse, /* tp_traverse */
2444 (inquiry)buffered_clear, /* tp_clear */
2445 0, /* tp_richcompare */
2446 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2447 0, /* tp_iter */
2448 (iternextfunc)buffered_iternext, /* tp_iternext */
2449 bufferedreader_methods, /* tp_methods */
2450 bufferedreader_members, /* tp_members */
2451 bufferedreader_getset, /* tp_getset */
2452 0, /* tp_base */
2453 0, /* tp_dict */
2454 0, /* tp_descr_get */
2455 0, /* tp_descr_set */
2456 offsetof(buffered, dict), /* tp_dictoffset */
2457 _io_BufferedReader___init__, /* tp_init */
2458 0, /* tp_alloc */
2459 PyType_GenericNew, /* tp_new */
2460 0, /* tp_free */
2461 0, /* tp_is_gc */
2462 0, /* tp_bases */
2463 0, /* tp_mro */
2464 0, /* tp_cache */
2465 0, /* tp_subclasses */
2466 0, /* tp_weaklist */
2467 0, /* tp_del */
2468 0, /* tp_version_tag */
2469 0, /* tp_finalize */
2470};
2471
2472
2473static PyMethodDef bufferedwriter_methods[] = {
2474 /* BufferedIOMixin methods */
2475 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2476 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2477 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002478 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2479 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2480 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2481 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2482 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2483
2484 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2485 _IO__BUFFERED_TRUNCATE_METHODDEF
2486 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2487 _IO__BUFFERED_SEEK_METHODDEF
2488 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2489 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2490 {NULL, NULL}
2491};
2492
2493static PyMemberDef bufferedwriter_members[] = {
2494 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2495 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2496 {NULL}
2497};
2498
2499static PyGetSetDef bufferedwriter_getset[] = {
2500 {"closed", (getter)buffered_closed_get, NULL, NULL},
2501 {"name", (getter)buffered_name_get, NULL, NULL},
2502 {"mode", (getter)buffered_mode_get, NULL, NULL},
2503 {NULL}
2504};
2505
2506
2507PyTypeObject PyBufferedWriter_Type = {
2508 PyVarObject_HEAD_INIT(NULL, 0)
2509 "_io.BufferedWriter", /*tp_name*/
2510 sizeof(buffered), /*tp_basicsize*/
2511 0, /*tp_itemsize*/
2512 (destructor)buffered_dealloc, /*tp_dealloc*/
2513 0, /*tp_print*/
2514 0, /*tp_getattr*/
2515 0, /*tp_setattr*/
2516 0, /*tp_compare */
2517 (reprfunc)buffered_repr, /*tp_repr*/
2518 0, /*tp_as_number*/
2519 0, /*tp_as_sequence*/
2520 0, /*tp_as_mapping*/
2521 0, /*tp_hash */
2522 0, /*tp_call*/
2523 0, /*tp_str*/
2524 0, /*tp_getattro*/
2525 0, /*tp_setattro*/
2526 0, /*tp_as_buffer*/
2527 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2528 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2529 _io_BufferedWriter___init____doc__, /* tp_doc */
2530 (traverseproc)buffered_traverse, /* tp_traverse */
2531 (inquiry)buffered_clear, /* tp_clear */
2532 0, /* tp_richcompare */
2533 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2534 0, /* tp_iter */
2535 0, /* tp_iternext */
2536 bufferedwriter_methods, /* tp_methods */
2537 bufferedwriter_members, /* tp_members */
2538 bufferedwriter_getset, /* tp_getset */
2539 0, /* tp_base */
2540 0, /* tp_dict */
2541 0, /* tp_descr_get */
2542 0, /* tp_descr_set */
2543 offsetof(buffered, dict), /* tp_dictoffset */
2544 _io_BufferedWriter___init__, /* tp_init */
2545 0, /* tp_alloc */
2546 PyType_GenericNew, /* tp_new */
2547 0, /* tp_free */
2548 0, /* tp_is_gc */
2549 0, /* tp_bases */
2550 0, /* tp_mro */
2551 0, /* tp_cache */
2552 0, /* tp_subclasses */
2553 0, /* tp_weaklist */
2554 0, /* tp_del */
2555 0, /* tp_version_tag */
2556 0, /* tp_finalize */
2557};
2558
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002560static PyMethodDef bufferedrwpair_methods[] = {
2561 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2562 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2563 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2564 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002565 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002567 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2568 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002570 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2571 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002572
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2574 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575
Antoine Pitrou243757e2010-11-05 21:15:39 +00002576 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2577
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002578 {NULL, NULL}
2579};
2580
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002581static PyGetSetDef bufferedrwpair_getset[] = {
2582 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002583 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002584};
2585
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586PyTypeObject PyBufferedRWPair_Type = {
2587 PyVarObject_HEAD_INIT(NULL, 0)
2588 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002589 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002590 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002591 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002592 0, /*tp_print*/
2593 0, /*tp_getattr*/
2594 0, /*tp_setattr*/
2595 0, /*tp_compare */
2596 0, /*tp_repr*/
2597 0, /*tp_as_number*/
2598 0, /*tp_as_sequence*/
2599 0, /*tp_as_mapping*/
2600 0, /*tp_hash */
2601 0, /*tp_call*/
2602 0, /*tp_str*/
2603 0, /*tp_getattro*/
2604 0, /*tp_setattro*/
2605 0, /*tp_as_buffer*/
2606 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002607 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002608 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002609 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2610 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002611 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002612 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613 0, /* tp_iter */
2614 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002615 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002617 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002618 0, /* tp_base */
2619 0, /* tp_dict */
2620 0, /* tp_descr_get */
2621 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002623 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002624 0, /* tp_alloc */
2625 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002626 0, /* tp_free */
2627 0, /* tp_is_gc */
2628 0, /* tp_bases */
2629 0, /* tp_mro */
2630 0, /* tp_cache */
2631 0, /* tp_subclasses */
2632 0, /* tp_weaklist */
2633 0, /* tp_del */
2634 0, /* tp_version_tag */
2635 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002637
2638
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002639static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002640 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002641 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2642 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2643 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2644 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2645 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2646 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2647 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002648 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002649 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002651 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002652
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002653 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002654 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002655 _IO__BUFFERED_TRUNCATE_METHODDEF
2656 _IO__BUFFERED_READ_METHODDEF
2657 _IO__BUFFERED_READ1_METHODDEF
2658 _IO__BUFFERED_READINTO_METHODDEF
2659 _IO__BUFFERED_READINTO1_METHODDEF
2660 _IO__BUFFERED_READLINE_METHODDEF
2661 _IO__BUFFERED_PEEK_METHODDEF
2662 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002663 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002664 {NULL, NULL}
2665};
2666
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002667static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002668 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002669 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002670 {NULL}
2671};
2672
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002673static PyGetSetDef bufferedrandom_getset[] = {
2674 {"closed", (getter)buffered_closed_get, NULL, NULL},
2675 {"name", (getter)buffered_name_get, NULL, NULL},
2676 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002677 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002678};
2679
2680
2681PyTypeObject PyBufferedRandom_Type = {
2682 PyVarObject_HEAD_INIT(NULL, 0)
2683 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002684 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002685 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002686 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002687 0, /*tp_print*/
2688 0, /*tp_getattr*/
2689 0, /*tp_setattr*/
2690 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002691 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002692 0, /*tp_as_number*/
2693 0, /*tp_as_sequence*/
2694 0, /*tp_as_mapping*/
2695 0, /*tp_hash */
2696 0, /*tp_call*/
2697 0, /*tp_str*/
2698 0, /*tp_getattro*/
2699 0, /*tp_setattro*/
2700 0, /*tp_as_buffer*/
2701 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002702 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002703 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002704 (traverseproc)buffered_traverse, /* tp_traverse */
2705 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002706 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002707 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002708 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002709 (iternextfunc)buffered_iternext, /* tp_iternext */
2710 bufferedrandom_methods, /* tp_methods */
2711 bufferedrandom_members, /* tp_members */
2712 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002713 0, /* tp_base */
2714 0, /*tp_dict*/
2715 0, /* tp_descr_get */
2716 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002717 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002718 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719 0, /* tp_alloc */
2720 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002721 0, /* tp_free */
2722 0, /* tp_is_gc */
2723 0, /* tp_bases */
2724 0, /* tp_mro */
2725 0, /* tp_cache */
2726 0, /* tp_subclasses */
2727 0, /* tp_weaklist */
2728 0, /* tp_del */
2729 0, /* tp_version_tag */
2730 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002731};