blob: b2b9ade2c7c4333ae17fd0cdd29a2b3c95aa698c [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -060012#include "internal/pystate.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000013#include "structmember.h"
14#include "pythread.h"
15#include "_iomodule.h"
16
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030017/*[clinic input]
18module _io
19class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
20class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
21class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
22class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
23class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
24class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
25[clinic start generated code]*/
26/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
27
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020028_Py_IDENTIFIER(close);
29_Py_IDENTIFIER(_dealloc_warn);
30_Py_IDENTIFIER(flush);
31_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020032_Py_IDENTIFIER(mode);
33_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020034_Py_IDENTIFIER(peek);
35_Py_IDENTIFIER(read);
36_Py_IDENTIFIER(read1);
37_Py_IDENTIFIER(readable);
38_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070039_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020040_Py_IDENTIFIER(writable);
41_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020042
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000043/*
44 * BufferedIOBase class, inherits from IOBase.
45 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000046PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000047 "Base class for buffered IO objects.\n"
48 "\n"
49 "The main difference with RawIOBase is that the read() method\n"
50 "supports omitting the size argument, and does not have a default\n"
51 "implementation that defers to readinto().\n"
52 "\n"
53 "In addition, read(), readinto() and write() may raise\n"
54 "BlockingIOError if the underlying raw stream is in non-blocking\n"
55 "mode and not ready; unlike their raw counterparts, they will never\n"
56 "return None.\n"
57 "\n"
58 "A typical implementation should not inherit from a RawIOBase\n"
59 "implementation, but wrap one.\n"
60 );
61
62static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030063_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000065 Py_ssize_t len;
66 PyObject *data;
67
Benjamin Petersona96fea02014-06-22 14:17:44 -070068 data = _PyObject_CallMethodId(self,
69 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030070 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030072 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000073
74 if (!PyBytes_Check(data)) {
75 Py_DECREF(data);
76 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030077 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000078 }
79
Serhiy Storchakafff9a312017-03-21 08:53:25 +020080 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030081 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030082 PyErr_Format(PyExc_ValueError,
83 "read() returned too much data: "
84 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030085 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030086 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030087 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030088 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030089 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000091 Py_DECREF(data);
92
93 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094}
95
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030096/*[clinic input]
97_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070098 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030099 /
100[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700101
102static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300103_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700104/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700105{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300106 return _bufferediobase_readinto_generic(self, buffer, 0);
107}
108
109/*[clinic input]
110_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700111 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300112 /
113[clinic start generated code]*/
114
115static PyObject *
116_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700117/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300118{
119 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700120}
121
122static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000123bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000124{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100125 _PyIO_State *state = IO_STATE();
126 if (state != NULL)
127 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000128 return NULL;
129}
130
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300131/*[clinic input]
132_io._BufferedIOBase.detach
133
134Disconnect this buffer from its underlying raw stream and return it.
135
136After the raw stream has been detached, the buffer is in an unusable
137state.
138[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000139
140static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300141_io__BufferedIOBase_detach_impl(PyObject *self)
142/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000143{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000145}
146
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000147PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000148 "Read and return up to n bytes.\n"
149 "\n"
150 "If the argument is omitted, None, or negative, reads and\n"
151 "returns all data until EOF.\n"
152 "\n"
153 "If the argument is positive, and the underlying raw stream is\n"
154 "not 'interactive', multiple raw reads may be issued to satisfy\n"
155 "the byte count (unless EOF is reached first). But for\n"
156 "interactive raw streams (as well as sockets and pipes), at most\n"
157 "one raw read will be issued, and a short result does not imply\n"
158 "that EOF is imminent.\n"
159 "\n"
160 "Returns an empty bytes object on EOF.\n"
161 "\n"
162 "Returns None if the underlying raw stream was open in non-blocking\n"
163 "mode and no data is available at the moment.\n");
164
165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000166bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000167{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000168 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000169}
170
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000171PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000172 "Read and return up to n bytes, with at most one read() call\n"
173 "to the underlying raw stream. A short result does not imply\n"
174 "that EOF is imminent.\n"
175 "\n"
176 "Returns an empty bytes object on EOF.\n");
177
178static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000179bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000181 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000182}
183
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000184PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000185 "Write the given buffer to the IO stream.\n"
186 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000187 "Returns the number of bytes written, which is always the length of b\n"
188 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000189 "\n"
190 "Raises BlockingIOError if the buffer is full and the\n"
191 "underlying raw stream cannot accept more data at the moment.\n");
192
193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197}
198
199
Neil Schemenauerdb564232017-09-04 22:13:17 -0700200typedef struct {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000201 PyObject_HEAD
202
203 PyObject *raw;
204 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000205 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206 int readable;
207 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200208 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200209
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000210 /* True if this is a vanilla Buffered object (rather than a user derived
211 class) *and* the raw stream is a vanilla FileIO object. */
212 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213
214 /* Absolute position inside the raw stream (-1 if unknown). */
215 Py_off_t abs_pos;
216
217 /* A static buffer of size `buffer_size` */
218 char *buffer;
219 /* Current logical position in the buffer. */
220 Py_off_t pos;
221 /* Position of the raw stream in the buffer. */
222 Py_off_t raw_pos;
223
224 /* Just after the last buffered byte in the buffer, or -1 if the buffer
225 isn't ready for reading. */
226 Py_off_t read_end;
227
228 /* Just after the last byte actually written */
229 Py_off_t write_pos;
230 /* Just after the last byte waiting to be written, or -1 if the buffer
231 isn't ready for writing. */
232 Py_off_t write_end;
233
234 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200235 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000236
237 Py_ssize_t buffer_size;
238 Py_ssize_t buffer_mask;
239
240 PyObject *dict;
241 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000242} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000243
244/*
245 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200246
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000247 * BufferedReader, BufferedWriter and BufferedRandom try to share most
248 methods (this is helped by the members `readable` and `writable`, which
249 are initialized in the respective constructors)
250 * They also share a single buffer for reading and writing. This enables
251 interleaved reads and writes without flushing. It also makes the logic
252 a bit trickier to get right.
253 * The absolute position of the raw stream is cached, if possible, in the
254 `abs_pos` member. It must be updated every time an operation is done
255 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000256 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000257 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000258 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
259 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000260
261 NOTE: we should try to maintain block alignment of reads and writes to the
262 raw stream (according to the buffer size), but for now it is only done
263 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200264
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000265*/
266
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000267/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000269static int
270_enter_buffered_busy(buffered *self)
271{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200272 int relax_locking;
273 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000274 if (self->owner == PyThread_get_thread_ident()) {
275 PyErr_Format(PyExc_RuntimeError,
276 "reentrant call inside %R", self);
277 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000278 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600279 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000280 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200281 if (!relax_locking)
282 st = PyThread_acquire_lock(self->lock, 1);
283 else {
284 /* When finalizing, we don't want a deadlock to happen with daemon
285 * threads abruptly shut down while they owned the lock.
286 * Therefore, only wait for a grace period (1 s.).
287 * Note that non-daemon threads have already exited here, so this
288 * shouldn't affect carefully written threaded I/O code.
289 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700290 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200291 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000292 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200293 if (relax_locking && st != PY_LOCK_ACQUIRED) {
294 PyObject *msgobj = PyUnicode_FromFormat(
295 "could not acquire lock for %A at interpreter "
296 "shutdown, possibly due to daemon threads",
297 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200298 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200299 Py_FatalError(msg);
300 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000301 return 1;
302}
303
304#define ENTER_BUFFERED(self) \
305 ( (PyThread_acquire_lock(self->lock, 0) ? \
306 1 : _enter_buffered_busy(self)) \
307 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000308
309#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000310 do { \
311 self->owner = 0; \
312 PyThread_release_lock(self->lock); \
313 } while(0);
314
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000315#define CHECK_INITIALIZED(self) \
316 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000317 if (self->detached) { \
318 PyErr_SetString(PyExc_ValueError, \
319 "raw stream has been detached"); \
320 } else { \
321 PyErr_SetString(PyExc_ValueError, \
322 "I/O operation on uninitialized object"); \
323 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000324 return NULL; \
325 }
326
327#define CHECK_INITIALIZED_INT(self) \
328 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000329 if (self->detached) { \
330 PyErr_SetString(PyExc_ValueError, \
331 "raw stream has been detached"); \
332 } else { \
333 PyErr_SetString(PyExc_ValueError, \
334 "I/O operation on uninitialized object"); \
335 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336 return -1; \
337 }
338
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000339#define IS_CLOSED(self) \
340 (self->fast_closed_checks \
341 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000342 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000343
344#define CHECK_CLOSED(self, error_msg) \
345 if (IS_CLOSED(self)) { \
346 PyErr_SetString(PyExc_ValueError, error_msg); \
347 return NULL; \
348 }
349
350
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000351#define VALID_READ_BUFFER(self) \
352 (self->readable && self->read_end != -1)
353
354#define VALID_WRITE_BUFFER(self) \
355 (self->writable && self->write_end != -1)
356
357#define ADJUST_POSITION(self, _new_pos) \
358 do { \
359 self->pos = _new_pos; \
360 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
361 self->read_end = self->pos; \
362 } while(0)
363
364#define READAHEAD(self) \
365 ((self->readable && VALID_READ_BUFFER(self)) \
366 ? (self->read_end - self->pos) : 0)
367
368#define RAW_OFFSET(self) \
369 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
370 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
371
372#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000373 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000374
375#define MINUS_LAST_BLOCK(self, size) \
376 (self->buffer_mask ? \
377 (size & ~self->buffer_mask) : \
378 (self->buffer_size * (size / self->buffer_size)))
379
380
381static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000382buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000383{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200384 self->finalizing = 1;
385 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000386 return;
387 _PyObject_GC_UNTRACK(self);
388 self->ok = 0;
389 if (self->weakreflist != NULL)
390 PyObject_ClearWeakRefs((PyObject *)self);
391 Py_CLEAR(self->raw);
392 if (self->buffer) {
393 PyMem_Free(self->buffer);
394 self->buffer = NULL;
395 }
396 if (self->lock) {
397 PyThread_free_lock(self->lock);
398 self->lock = NULL;
399 }
400 Py_CLEAR(self->dict);
401 Py_TYPE(self)->tp_free((PyObject *)self);
402}
403
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200404static PyObject *
405buffered_sizeof(buffered *self, void *unused)
406{
407 Py_ssize_t res;
408
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200409 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200410 if (self->buffer)
411 res += self->buffer_size;
412 return PyLong_FromSsize_t(res);
413}
414
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000415static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000416buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000417{
418 Py_VISIT(self->raw);
419 Py_VISIT(self->dict);
420 return 0;
421}
422
423static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000424buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000426 self->ok = 0;
427 Py_CLEAR(self->raw);
428 Py_CLEAR(self->dict);
429 return 0;
430}
431
Antoine Pitroue033e062010-10-29 10:38:18 +0000432/* Because this can call arbitrary code, it shouldn't be called when
433 the refcount is 0 (that is, not directly from tp_dealloc unless
434 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000435static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000436buffered_dealloc_warn(buffered *self, PyObject *source)
437{
438 if (self->ok && self->raw) {
439 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100440 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
441 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000442 if (r)
443 Py_DECREF(r);
444 else
445 PyErr_Clear();
446 }
447 Py_RETURN_NONE;
448}
449
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000450/*
451 * _BufferedIOMixin methods
452 * This is not a class, just a collection of methods that will be reused
453 * by BufferedReader and BufferedWriter
454 */
455
456/* Flush and close */
457
458static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000459buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000460{
461 CHECK_INITIALIZED(self)
462 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
463}
464
465static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000466buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000467{
468 int closed;
469 PyObject *res;
470 CHECK_INITIALIZED_INT(self)
471 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
472 if (res == NULL)
473 return -1;
474 closed = PyObject_IsTrue(res);
475 Py_DECREF(res);
476 return closed;
477}
478
479static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000480buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481{
482 CHECK_INITIALIZED(self)
483 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
484}
485
486static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000487buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000488{
Benjamin Peterson68623612012-12-20 11:53:11 -0600489 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000490 int r;
491
492 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000493 if (!ENTER_BUFFERED(self))
494 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000495
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000496 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000497 if (r < 0)
498 goto end;
499 if (r > 0) {
500 res = Py_None;
501 Py_INCREF(res);
502 goto end;
503 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000504
Antoine Pitrou796564c2013-07-30 19:59:21 +0200505 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000506 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
507 if (r)
508 Py_DECREF(r);
509 else
510 PyErr_Clear();
511 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512 /* flush() will most probably re-take the lock, so drop it first */
513 LEAVE_BUFFERED(self)
514 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000515 if (!ENTER_BUFFERED(self))
516 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600517 if (res == NULL)
518 PyErr_Fetch(&exc, &val, &tb);
519 else
520 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000521
522 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
523
Jesus Ceadc469452012-10-04 12:37:56 +0200524 if (self->buffer) {
525 PyMem_Free(self->buffer);
526 self->buffer = NULL;
527 }
528
Benjamin Peterson68623612012-12-20 11:53:11 -0600529 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300530 _PyErr_ChainExceptions(exc, val, tb);
531 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600532 }
533
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000534end:
535 LEAVE_BUFFERED(self)
536 return res;
537}
538
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000539/* detach */
540
541static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000542buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000543{
544 PyObject *raw, *res;
545 CHECK_INITIALIZED(self)
546 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
547 if (res == NULL)
548 return NULL;
549 Py_DECREF(res);
550 raw = self->raw;
551 self->raw = NULL;
552 self->detached = 1;
553 self->ok = 0;
554 return raw;
555}
556
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000557/* Inquiries */
558
559static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000560buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000561{
562 CHECK_INITIALIZED(self)
563 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
564}
565
566static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000567buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000568{
569 CHECK_INITIALIZED(self)
570 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
571}
572
573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000574buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575{
576 CHECK_INITIALIZED(self)
577 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
578}
579
580static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000581buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582{
583 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200584 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585}
586
587static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589{
590 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200591 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592}
593
594/* Lower-level APIs */
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598{
599 CHECK_INITIALIZED(self)
600 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
601}
602
603static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000604buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000605{
606 CHECK_INITIALIZED(self)
607 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
608}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000609
Antoine Pitrou243757e2010-11-05 21:15:39 +0000610/* Serialization */
611
612static PyObject *
613buffered_getstate(buffered *self, PyObject *args)
614{
615 PyErr_Format(PyExc_TypeError,
616 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
617 return NULL;
618}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000619
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620/* Forward decls */
621static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100622_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000623static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000624_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000625static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000626_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000628_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200630_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000631static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000632_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000633static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000634_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000635static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000636_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200637static Py_ssize_t
638_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639
640/*
641 * Helpers
642 */
643
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100644/* Sets the current error to BlockingIOError */
645static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200646_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100647{
648 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200649 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100650 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
651 errno, msg, written);
652 if (err)
653 PyErr_SetObject(PyExc_BlockingIOError, err);
654 Py_XDECREF(err);
655}
656
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657/* Returns the address of the `written` member if a BlockingIOError was
658 raised, NULL otherwise. The error is always re-raised. */
659static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000660_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000661{
662 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200663 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664
665 PyErr_Fetch(&t, &v, &tb);
666 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
667 PyErr_Restore(t, v, tb);
668 return NULL;
669 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200670 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671 /* TODO: sanity check (err->written >= 0) */
672 PyErr_Restore(t, v, tb);
673 return &err->written;
674}
675
676static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000677_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000679 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000680 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
682 if (res == NULL)
683 return -1;
684 n = PyNumber_AsOff_t(res, PyExc_ValueError);
685 Py_DECREF(res);
686 if (n < 0) {
687 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300688 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000689 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200690 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691 return -1;
692 }
693 self->abs_pos = n;
694 return n;
695}
696
697static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000698_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000699{
700 PyObject *res, *posobj, *whenceobj;
701 Py_off_t n;
702
703 posobj = PyLong_FromOff_t(target);
704 if (posobj == NULL)
705 return -1;
706 whenceobj = PyLong_FromLong(whence);
707 if (whenceobj == NULL) {
708 Py_DECREF(posobj);
709 return -1;
710 }
711 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
712 posobj, whenceobj, NULL);
713 Py_DECREF(posobj);
714 Py_DECREF(whenceobj);
715 if (res == NULL)
716 return -1;
717 n = PyNumber_AsOff_t(res, PyExc_ValueError);
718 Py_DECREF(res);
719 if (n < 0) {
720 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300721 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000722 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200723 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000724 return -1;
725 }
726 self->abs_pos = n;
727 return n;
728}
729
730static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000731_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732{
733 Py_ssize_t n;
734 if (self->buffer_size <= 0) {
735 PyErr_SetString(PyExc_ValueError,
736 "buffer size must be strictly positive");
737 return -1;
738 }
739 if (self->buffer)
740 PyMem_Free(self->buffer);
741 self->buffer = PyMem_Malloc(self->buffer_size);
742 if (self->buffer == NULL) {
743 PyErr_NoMemory();
744 return -1;
745 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000746 if (self->lock)
747 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000748 self->lock = PyThread_allocate_lock();
749 if (self->lock == NULL) {
750 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
751 return -1;
752 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000753 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 /* Find out whether buffer_size is a power of 2 */
755 /* XXX is this optimization useful? */
756 for (n = self->buffer_size - 1; n & 1; n >>= 1)
757 ;
758 if (n == 0)
759 self->buffer_mask = self->buffer_size - 1;
760 else
761 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000762 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000763 PyErr_Clear();
764 return 0;
765}
766
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300767/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000768 clears the error indicator), 0 otherwise.
769 Should only be called when PyErr_Occurred() is true.
770*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700771int
772_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000773{
774 static PyObject *eintr_int = NULL;
775 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300776 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000777
778 if (eintr_int == NULL) {
779 eintr_int = PyLong_FromLong(EINTR);
780 assert(eintr_int != NULL);
781 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300782 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000783 return 0;
784 PyErr_Fetch(&typ, &val, &tb);
785 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300786 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000787 assert(env_err != NULL);
788 if (env_err->myerrno != NULL &&
789 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
790 Py_DECREF(typ);
791 Py_DECREF(val);
792 Py_XDECREF(tb);
793 return 1;
794 }
795 /* This silences any error set by PyObject_RichCompareBool() */
796 PyErr_Restore(typ, val, tb);
797 return 0;
798}
799
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000800/*
801 * Shared methods and wrappers
802 */
803
804static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200805buffered_flush_and_rewind_unlocked(buffered *self)
806{
807 PyObject *res;
808
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100809 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200810 if (res == NULL)
811 return NULL;
812 Py_DECREF(res);
813
814 if (self->readable) {
815 /* Rewind the raw stream so that its position corresponds to
816 the current logical position. */
817 Py_off_t n;
818 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
819 _bufferedreader_reset_buf(self);
820 if (n == -1)
821 return NULL;
822 }
823 Py_RETURN_NONE;
824}
825
826static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000827buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000828{
829 PyObject *res;
830
831 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000832 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000833
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000834 if (!ENTER_BUFFERED(self))
835 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200836 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000837 LEAVE_BUFFERED(self)
838
839 return res;
840}
841
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300842/*[clinic input]
843_io._Buffered.peek
844 size: Py_ssize_t = 0
845 /
846
847[clinic start generated code]*/
848
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300850_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
851/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000853 PyObject *res = NULL;
854
855 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300856 CHECK_CLOSED(self, "peek of closed file")
857
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000858 if (!ENTER_BUFFERED(self))
859 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000860
861 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200862 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000863 if (res == NULL)
864 goto end;
865 Py_CLEAR(res);
866 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200867 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868
869end:
870 LEAVE_BUFFERED(self)
871 return res;
872}
873
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300874/*[clinic input]
875_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300876 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300877 /
878[clinic start generated code]*/
879
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000880static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300881_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300882/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000883{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000884 PyObject *res;
885
886 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887 if (n < -1) {
888 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000889 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890 return NULL;
891 }
892
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000893 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000894
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000895 if (n == -1) {
896 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000897 if (!ENTER_BUFFERED(self))
898 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000899 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000900 }
901 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000902 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200903 if (res != Py_None)
904 return res;
905 Py_DECREF(res);
906 if (!ENTER_BUFFERED(self))
907 return NULL;
908 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000909 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000910
Antoine Pitroue05565e2011-08-20 14:39:23 +0200911 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912 return res;
913}
914
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300915/*[clinic input]
916_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000917 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300918 /
919[clinic start generated code]*/
920
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000921static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300922_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000923/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300925 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000926 PyObject *res = NULL;
927
928 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000930 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300932
933 CHECK_CLOSED(self, "read of closed file")
934
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000935 if (n == 0)
936 return PyBytes_FromStringAndSize(NULL, 0);
937
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000938 /* Return up to n bytes. If at least one byte is buffered, we
939 only return buffered bytes. Otherwise, we do one raw read. */
940
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000941 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
942 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100943 n = Py_MIN(have, n);
944 res = _bufferedreader_read_fast(self, n);
945 assert(res != Py_None);
946 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100948 res = PyBytes_FromStringAndSize(NULL, n);
949 if (res == NULL)
950 return NULL;
951 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200952 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100953 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200954 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000955 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100956 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
957 LEAVE_BUFFERED(self)
958 if (r == -1) {
959 Py_DECREF(res);
960 return NULL;
961 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 if (r == -2)
963 r = 0;
964 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100965 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000966 return res;
967}
968
969static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300970_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000971{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200972 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000973 PyObject *res = NULL;
974
975 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200976
Antoine Pitrou3486a982011-05-12 01:57:53 +0200977 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
978 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300979 if (n >= buffer->len) {
980 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
981 self->pos += buffer->len;
982 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200983 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300984 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200985 self->pos += n;
986 written = n;
987 }
988
989 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300990 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200991
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +0200993 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000994 if (res == NULL)
995 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997 }
Antoine Pitrou3486a982011-05-12 01:57:53 +0200998
999 _bufferedreader_reset_buf(self);
1000 self->pos = 0;
1001
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001002 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001003 remaining > 0;
1004 written += n, remaining -= n) {
1005 /* If remaining bytes is larger than internal buffer size, copy
1006 * directly into caller's buffer. */
1007 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001008 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001009 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001010 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001011
1012 /* In readinto1 mode, we do not want to fill the internal
1013 buffer if we already have some data to return */
1014 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001015 n = _bufferedreader_fill_buffer(self);
1016 if (n > 0) {
1017 if (n > remaining)
1018 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001019 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001020 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 self->pos += n;
1022 continue; /* short circuit */
1023 }
1024 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001025 else
1026 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001027
Antoine Pitrou3486a982011-05-12 01:57:53 +02001028 if (n == 0 || (n == -2 && written > 0))
1029 break;
1030 if (n < 0) {
1031 if (n == -2) {
1032 Py_INCREF(Py_None);
1033 res = Py_None;
1034 }
1035 goto end;
1036 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001037
Benjamin Petersona96fea02014-06-22 14:17:44 -07001038 /* At most one read in readinto1 mode */
1039 if (readinto1) {
1040 written += n;
1041 break;
1042 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001043 }
1044 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001045
1046end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001047 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001048 return res;
1049}
1050
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001051/*[clinic input]
1052_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001053 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001054 /
1055[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001056
1057static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001058_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001059/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001060{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001061 return _buffered_readinto_generic(self, buffer, 0);
1062}
1063
1064/*[clinic input]
1065_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001066 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001067 /
1068[clinic start generated code]*/
1069
1070static PyObject *
1071_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001072/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001073{
1074 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001075}
1076
1077
1078static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001079_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001080{
1081 PyObject *res = NULL;
1082 PyObject *chunks = NULL;
1083 Py_ssize_t n, written = 0;
1084 const char *start, *s, *end;
1085
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001086 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001087
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001088 /* First, try to find a line in the buffer. This can run unlocked because
1089 the calls to the C API are simple enough that they can't trigger
1090 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001091 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1092 if (limit >= 0 && n > limit)
1093 n = limit;
1094 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001095 s = memchr(start, '\n', n);
1096 if (s != NULL) {
1097 res = PyBytes_FromStringAndSize(start, s - start + 1);
1098 if (res != NULL)
1099 self->pos += s - start + 1;
1100 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 }
1102 if (n == limit) {
1103 res = PyBytes_FromStringAndSize(start, n);
1104 if (res != NULL)
1105 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001106 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001107 }
1108
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001109 if (!ENTER_BUFFERED(self))
1110 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001111
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001112 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113 chunks = PyList_New(0);
1114 if (chunks == NULL)
1115 goto end;
1116 if (n > 0) {
1117 res = PyBytes_FromStringAndSize(start, n);
1118 if (res == NULL)
1119 goto end;
1120 if (PyList_Append(chunks, res) < 0) {
1121 Py_CLEAR(res);
1122 goto end;
1123 }
1124 Py_CLEAR(res);
1125 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001126 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127 if (limit >= 0)
1128 limit -= n;
1129 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001130 if (self->writable) {
1131 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1132 if (r == NULL)
1133 goto end;
1134 Py_DECREF(r);
1135 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001136
1137 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001138 _bufferedreader_reset_buf(self);
1139 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001140 if (n == -1)
1141 goto end;
1142 if (n <= 0)
1143 break;
1144 if (limit >= 0 && n > limit)
1145 n = limit;
1146 start = self->buffer;
1147 end = start + n;
1148 s = start;
1149 while (s < end) {
1150 if (*s++ == '\n') {
1151 res = PyBytes_FromStringAndSize(start, s - start);
1152 if (res == NULL)
1153 goto end;
1154 self->pos = s - start;
1155 goto found;
1156 }
1157 }
1158 res = PyBytes_FromStringAndSize(start, n);
1159 if (res == NULL)
1160 goto end;
1161 if (n == limit) {
1162 self->pos = n;
1163 break;
1164 }
1165 if (PyList_Append(chunks, res) < 0) {
1166 Py_CLEAR(res);
1167 goto end;
1168 }
1169 Py_CLEAR(res);
1170 written += n;
1171 if (limit >= 0)
1172 limit -= n;
1173 }
1174found:
1175 if (res != NULL && PyList_Append(chunks, res) < 0) {
1176 Py_CLEAR(res);
1177 goto end;
1178 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001179 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001180
1181end:
1182 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001183end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001184 Py_XDECREF(chunks);
1185 return res;
1186}
1187
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001188/*[clinic input]
1189_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001190 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001191 /
1192[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001193
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001194static PyObject *
1195_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001196/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001197{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001198 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001199 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001200}
1201
1202
1203static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001204buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001205{
1206 Py_off_t pos;
1207
1208 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001209 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001210 if (pos == -1)
1211 return NULL;
1212 pos -= RAW_OFFSET(self);
1213 /* TODO: sanity check (pos >= 0) */
1214 return PyLong_FromOff_t(pos);
1215}
1216
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001217/*[clinic input]
1218_io._Buffered.seek
1219 target as targetobj: object
1220 whence: int = 0
1221 /
1222[clinic start generated code]*/
1223
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001224static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001225_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1226/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227{
1228 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001229 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230
1231 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001232
1233 /* Do some error checking instead of trusting OS 'seek()'
1234 ** error detection, just in case.
1235 */
1236 if ((whence < 0 || whence >2)
1237#ifdef SEEK_HOLE
1238 && (whence != SEEK_HOLE)
1239#endif
1240#ifdef SEEK_DATA
1241 && (whence != SEEK_DATA)
1242#endif
1243 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001245 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246 return NULL;
1247 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001248
1249 CHECK_CLOSED(self, "seek of closed file")
1250
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001251 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1252 return NULL;
1253
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1255 if (target == -1 && PyErr_Occurred())
1256 return NULL;
1257
Jesus Cea94363612012-06-22 18:32:07 +02001258 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1259 buffer. Other whence values must be managed without this optimization.
1260 Some Operating Systems can provide additional values, like
1261 SEEK_HOLE/SEEK_DATA. */
1262 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 Py_off_t current, avail;
1264 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001265 so as to return quickly if possible. Also, we needn't take the
1266 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001267 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001268 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1269 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001270 current = RAW_TELL(self);
1271 avail = READAHEAD(self);
1272 if (avail > 0) {
1273 Py_off_t offset;
1274 if (whence == 0)
1275 offset = target - (current - RAW_OFFSET(self));
1276 else
1277 offset = target;
1278 if (offset >= -self->pos && offset <= avail) {
1279 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001280 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001281 }
1282 }
1283 }
1284
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001285 if (!ENTER_BUFFERED(self))
1286 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001287
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 /* Fallback: invoke raw seek() method and clear buffer */
1289 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001290 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001291 if (res == NULL)
1292 goto end;
1293 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001294 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001295 }
1296
1297 /* TODO: align on block boundary and read buffer if needed? */
1298 if (whence == 1)
1299 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001300 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 if (n == -1)
1302 goto end;
1303 self->raw_pos = -1;
1304 res = PyLong_FromOff_t(n);
1305 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001306 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307
1308end:
1309 LEAVE_BUFFERED(self)
1310 return res;
1311}
1312
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001313/*[clinic input]
1314_io._Buffered.truncate
1315 pos: object = None
1316 /
1317[clinic start generated code]*/
1318
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001320_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1321/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001323 PyObject *res = NULL;
1324
1325 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001326 if (!ENTER_BUFFERED(self))
1327 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328
1329 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001330 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001331 if (res == NULL)
1332 goto end;
1333 Py_CLEAR(res);
1334 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1336 if (res == NULL)
1337 goto end;
1338 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001339 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340 PyErr_Clear();
1341
1342end:
1343 LEAVE_BUFFERED(self)
1344 return res;
1345}
1346
1347static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001348buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349{
1350 PyObject *line;
1351 PyTypeObject *tp;
1352
1353 CHECK_INITIALIZED(self);
1354
1355 tp = Py_TYPE(self);
1356 if (tp == &PyBufferedReader_Type ||
1357 tp == &PyBufferedRandom_Type) {
1358 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001359 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360 }
1361 else {
1362 line = PyObject_CallMethodObjArgs((PyObject *)self,
1363 _PyIO_str_readline, NULL);
1364 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001365 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001366 "readline() should have returned a bytes object, "
1367 "not '%.200s'", Py_TYPE(line)->tp_name);
1368 Py_DECREF(line);
1369 return NULL;
1370 }
1371 }
1372
1373 if (line == NULL)
1374 return NULL;
1375
1376 if (PyBytes_GET_SIZE(line) == 0) {
1377 /* Reached EOF or would have blocked */
1378 Py_DECREF(line);
1379 return NULL;
1380 }
1381
1382 return line;
1383}
1384
Antoine Pitrou716c4442009-05-23 19:04:03 +00001385static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001386buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001387{
1388 PyObject *nameobj, *res;
1389
Martin v. Löwis767046a2011-10-14 15:35:36 +02001390 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001391 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001392 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001393 PyErr_Clear();
1394 else
1395 return NULL;
1396 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1397 }
1398 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001399 int status = Py_ReprEnter((PyObject *)self);
1400 res = NULL;
1401 if (status == 0) {
1402 res = PyUnicode_FromFormat("<%s name=%R>",
1403 Py_TYPE(self)->tp_name, nameobj);
1404 Py_ReprLeave((PyObject *)self);
1405 }
1406 else if (status > 0) {
1407 PyErr_Format(PyExc_RuntimeError,
1408 "reentrant call inside %s.__repr__",
1409 Py_TYPE(self)->tp_name);
1410 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001411 Py_DECREF(nameobj);
1412 }
1413 return res;
1414}
1415
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001416/*
1417 * class BufferedReader
1418 */
1419
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001420static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001421{
1422 self->read_end = -1;
1423}
1424
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001425/*[clinic input]
1426_io.BufferedReader.__init__
1427 raw: object
1428 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001429
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001430Create a new buffered reader using the given readable raw IO object.
1431[clinic start generated code]*/
1432
1433static int
1434_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1435 Py_ssize_t buffer_size)
1436/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1437{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001439 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001441 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001442 return -1;
1443
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001444 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001445 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001446 self->buffer_size = buffer_size;
1447 self->readable = 1;
1448 self->writable = 0;
1449
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001450 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001451 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001452 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001453
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001454 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1455 Py_TYPE(raw) == &PyFileIO_Type);
1456
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001457 self->ok = 1;
1458 return 0;
1459}
1460
1461static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001462_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463{
1464 Py_buffer buf;
1465 PyObject *memobj, *res;
1466 Py_ssize_t n;
1467 /* NOTE: the buffer needn't be released as its object is NULL. */
1468 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1469 return -1;
1470 memobj = PyMemoryView_FromBuffer(&buf);
1471 if (memobj == NULL)
1472 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001473 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1474 occurs so we needn't do it ourselves.
1475 We then retry reading, ignoring the signal if no handler has
1476 raised (see issue #10956).
1477 */
1478 do {
1479 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001480 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001481 Py_DECREF(memobj);
1482 if (res == NULL)
1483 return -1;
1484 if (res == Py_None) {
1485 /* Non-blocking stream would have blocked. Special return code! */
1486 Py_DECREF(res);
1487 return -2;
1488 }
1489 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1490 Py_DECREF(res);
1491 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001492 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001493 "raw readinto() returned invalid length %zd "
1494 "(should have been between 0 and %zd)", n, len);
1495 return -1;
1496 }
1497 if (n > 0 && self->abs_pos != -1)
1498 self->abs_pos += n;
1499 return n;
1500}
1501
1502static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001503_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001504{
1505 Py_ssize_t start, len, n;
1506 if (VALID_READ_BUFFER(self))
1507 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1508 else
1509 start = 0;
1510 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001511 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001512 if (n <= 0)
1513 return n;
1514 self->read_end = start + n;
1515 self->raw_pos = start + n;
1516 return n;
1517}
1518
1519static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001520_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001521{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001522 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001523 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001524
1525 /* First copy what we have in the current buffer. */
1526 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1527 if (current_size) {
1528 data = PyBytes_FromStringAndSize(
1529 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001530 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001531 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001532 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001533 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001534 /* We're going past the buffer's bounds, flush it */
1535 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001536 tmp = buffered_flush_and_rewind_unlocked(self);
1537 if (tmp == NULL)
1538 goto cleanup;
1539 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001540 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001541 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001542
1543 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001544 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1545 if (tmp == NULL)
1546 goto cleanup;
1547 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001548 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001549 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001550 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001551 if (tmp == Py_None) {
1552 if (current_size == 0) {
1553 res = Py_None;
1554 goto cleanup;
1555 } else {
1556 res = data;
1557 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001558 }
1559 }
1560 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001561 PyBytes_Concat(&data, tmp);
1562 res = data;
1563 goto cleanup;
1564 }
1565 else {
1566 res = tmp;
1567 goto cleanup;
1568 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001569 }
1570
1571 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001572 if (chunks == NULL)
1573 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001574
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001575 while (1) {
1576 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001577 if (PyList_Append(chunks, data) < 0)
1578 goto cleanup;
1579 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001580 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001581
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001582 /* Read until EOF or until read() would block. */
1583 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001584 if (data == NULL)
1585 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001586 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001587 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001588 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001589 }
1590 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1591 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001592 res = data;
1593 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594 }
1595 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001596 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1597 res = tmp;
1598 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599 }
1600 }
1601 current_size += PyBytes_GET_SIZE(data);
1602 if (self->abs_pos != -1)
1603 self->abs_pos += PyBytes_GET_SIZE(data);
1604 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001605cleanup:
1606 /* res is either NULL or a borrowed ref */
1607 Py_XINCREF(res);
1608 Py_XDECREF(data);
1609 Py_XDECREF(tmp);
1610 Py_XDECREF(chunks);
1611 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001612}
1613
1614/* Read n bytes from the buffer if it can, otherwise return None.
1615 This function is simple enough that it can run unlocked. */
1616static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001617_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001618{
1619 Py_ssize_t current_size;
1620
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001621 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1622 if (n <= current_size) {
1623 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001624 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1625 if (res != NULL)
1626 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001627 return res;
1628 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001629 Py_RETURN_NONE;
1630}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001631
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001632/* Generic read function: read from the stream until enough bytes are read,
1633 * or until an EOF occurs or until read() would block.
1634 */
1635static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001636_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001637{
1638 PyObject *res = NULL;
1639 Py_ssize_t current_size, remaining, written;
1640 char *out;
1641
1642 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1643 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001644 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001645
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001646 res = PyBytes_FromStringAndSize(NULL, n);
1647 if (res == NULL)
1648 goto error;
1649 out = PyBytes_AS_STRING(res);
1650 remaining = n;
1651 written = 0;
1652 if (current_size > 0) {
1653 memcpy(out, self->buffer + self->pos, current_size);
1654 remaining -= current_size;
1655 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001656 self->pos += current_size;
1657 }
1658 /* Flush the write buffer if necessary */
1659 if (self->writable) {
1660 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1661 if (r == NULL)
1662 goto error;
1663 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001664 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001665 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001666 while (remaining > 0) {
1667 /* We want to read a whole block at the end into buffer.
1668 If we had readv() we could do this in one pass. */
1669 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1670 if (r == 0)
1671 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001672 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001673 if (r == -1)
1674 goto error;
1675 if (r == 0 || r == -2) {
1676 /* EOF occurred or read() would block. */
1677 if (r == 0 || written > 0) {
1678 if (_PyBytes_Resize(&res, written))
1679 goto error;
1680 return res;
1681 }
1682 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001683 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001684 }
1685 remaining -= r;
1686 written += r;
1687 }
1688 assert(remaining <= self->buffer_size);
1689 self->pos = 0;
1690 self->raw_pos = 0;
1691 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001692 /* NOTE: when the read is satisfied, we avoid issuing any additional
1693 reads, which could block indefinitely (e.g. on a socket).
1694 See issue #9550. */
1695 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001696 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001697 if (r == -1)
1698 goto error;
1699 if (r == 0 || r == -2) {
1700 /* EOF occurred or read() would block. */
1701 if (r == 0 || written > 0) {
1702 if (_PyBytes_Resize(&res, written))
1703 goto error;
1704 return res;
1705 }
1706 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001707 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001708 }
1709 if (remaining > r) {
1710 memcpy(out + written, self->buffer + self->pos, r);
1711 written += r;
1712 self->pos += r;
1713 remaining -= r;
1714 }
1715 else if (remaining > 0) {
1716 memcpy(out + written, self->buffer + self->pos, remaining);
1717 written += remaining;
1718 self->pos += remaining;
1719 remaining = 0;
1720 }
1721 if (remaining == 0)
1722 break;
1723 }
1724
1725 return res;
1726
1727error:
1728 Py_XDECREF(res);
1729 return NULL;
1730}
1731
1732static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001733_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001734{
1735 Py_ssize_t have, r;
1736
1737 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1738 /* Constraints:
1739 1. we don't want to advance the file position.
1740 2. we don't want to lose block alignment, so we can't shift the buffer
1741 to make some place.
1742 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1743 */
1744 if (have > 0) {
1745 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1746 }
1747
1748 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001749 _bufferedreader_reset_buf(self);
1750 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001751 if (r == -1)
1752 return NULL;
1753 if (r == -2)
1754 r = 0;
1755 self->pos = 0;
1756 return PyBytes_FromStringAndSize(self->buffer, r);
1757}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001758
1759
Benjamin Peterson59406a92009-03-26 17:10:29 +00001760
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761/*
1762 * class BufferedWriter
1763 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001764static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001765_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001766{
1767 self->write_pos = 0;
1768 self->write_end = -1;
1769}
1770
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001771/*[clinic input]
1772_io.BufferedWriter.__init__
1773 raw: object
1774 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001776A buffer for a writeable sequential RawIO object.
1777
1778The constructor creates a BufferedWriter for the given writeable raw
1779stream. If the buffer_size is not given, it defaults to
1780DEFAULT_BUFFER_SIZE.
1781[clinic start generated code]*/
1782
1783static int
1784_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1785 Py_ssize_t buffer_size)
1786/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1787{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001789 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001791 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001792 return -1;
1793
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001795 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001796 self->readable = 0;
1797 self->writable = 1;
1798
1799 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001800 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001801 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001802 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001803 self->pos = 0;
1804
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001805 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1806 Py_TYPE(raw) == &PyFileIO_Type);
1807
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001808 self->ok = 1;
1809 return 0;
1810}
1811
1812static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001813_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814{
1815 Py_buffer buf;
1816 PyObject *memobj, *res;
1817 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001818 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001819 /* NOTE: the buffer needn't be released as its object is NULL. */
1820 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1821 return -1;
1822 memobj = PyMemoryView_FromBuffer(&buf);
1823 if (memobj == NULL)
1824 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001825 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1826 occurs so we needn't do it ourselves.
1827 We then retry writing, ignoring the signal if no handler has
1828 raised (see issue #10956).
1829 */
1830 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001831 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001832 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001833 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001834 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 Py_DECREF(memobj);
1836 if (res == NULL)
1837 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001838 if (res == Py_None) {
1839 /* Non-blocking stream would have blocked. Special return code!
1840 Being paranoid we reset errno in case it is changed by code
1841 triggered by a decref. errno is used by _set_BlockingIOError(). */
1842 Py_DECREF(res);
1843 errno = errnum;
1844 return -2;
1845 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1847 Py_DECREF(res);
1848 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001849 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001850 "raw write() returned invalid length %zd "
1851 "(should have been between 0 and %zd)", n, len);
1852 return -1;
1853 }
1854 if (n > 0 && self->abs_pos != -1)
1855 self->abs_pos += n;
1856 return n;
1857}
1858
1859/* `restore_pos` is 1 if we need to restore the raw stream position at
1860 the end, 0 otherwise. */
1861static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001862_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863{
1864 Py_ssize_t written = 0;
1865 Py_off_t n, rewind;
1866
1867 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1868 goto end;
1869 /* First, rewind */
1870 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1871 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001872 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001873 if (n < 0) {
1874 goto error;
1875 }
1876 self->raw_pos -= rewind;
1877 }
1878 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001879 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880 self->buffer + self->write_pos,
1881 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1882 Py_off_t, Py_ssize_t));
1883 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001884 goto error;
1885 }
1886 else if (n == -2) {
1887 _set_BlockingIOError("write could not complete without blocking",
1888 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001889 goto error;
1890 }
1891 self->write_pos += n;
1892 self->raw_pos = self->write_pos;
1893 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001894 /* Partial writes can return successfully when interrupted by a
1895 signal (see write(2)). We must run signal handlers before
1896 blocking another time, possibly indefinitely. */
1897 if (PyErr_CheckSignals() < 0)
1898 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001899 }
1900
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001901 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001902
1903end:
1904 Py_RETURN_NONE;
1905
1906error:
1907 return NULL;
1908}
1909
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001910/*[clinic input]
1911_io.BufferedWriter.write
1912 buffer: Py_buffer
1913 /
1914[clinic start generated code]*/
1915
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001916static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001917_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1918/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001919{
1920 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001921 Py_ssize_t written, avail, remaining;
1922 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923
1924 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001925 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001927 return NULL;
1928 }
1929
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001930 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001931 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001932
1933 /* Fast path: the data to write can be fully buffered. */
1934 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1935 self->pos = 0;
1936 self->raw_pos = 0;
1937 }
1938 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001939 if (buffer->len <= avail) {
1940 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001941 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942 self->write_pos = self->pos;
1943 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001944 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945 if (self->pos > self->write_end)
1946 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001947 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 goto end;
1949 }
1950
1951 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001952 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001953 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001954 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955 if (w == NULL)
1956 goto error;
1957 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001958 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001959 /* Make some place by shifting the buffer. */
1960 assert(VALID_WRITE_BUFFER(self));
1961 memmove(self->buffer, self->buffer + self->write_pos,
1962 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1963 Py_off_t, Py_ssize_t));
1964 self->write_end -= self->write_pos;
1965 self->raw_pos -= self->write_pos;
1966 self->pos -= self->write_pos;
1967 self->write_pos = 0;
1968 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1969 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001970 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001971 /* Everything can be buffered */
1972 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001973 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1974 self->write_end += buffer->len;
1975 self->pos += buffer->len;
1976 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001977 goto end;
1978 }
1979 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001980 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001982 self->pos += avail;
1983 /* XXX Modifying the existing exception e using the pointer w
1984 will change e.characters_written but not e.args[2].
1985 Therefore we just replace with a new error. */
1986 _set_BlockingIOError("write could not complete without blocking",
1987 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001988 goto error;
1989 }
1990 Py_CLEAR(res);
1991
Antoine Pitroua0ceb732009-08-06 20:29:56 +00001992 /* Adjust the raw stream position if it is away from the logical stream
1993 position. This happens if the read buffer has been filled but not
1994 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1995 the raw stream by itself).
1996 Fixes issue #6629.
1997 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001998 offset = RAW_OFFSET(self);
1999 if (offset != 0) {
2000 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002001 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002002 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002003 }
2004
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002005 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002006 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 written = 0;
2008 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002009 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002010 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002011 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002012 goto error;
2013 } else if (n == -2) {
2014 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 if (remaining > self->buffer_size) {
2016 /* Can't buffer everything, still buffer as much as possible */
2017 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002018 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002019 self->raw_pos = 0;
2020 ADJUST_POSITION(self, self->buffer_size);
2021 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002022 written += self->buffer_size;
2023 _set_BlockingIOError("write could not complete without "
2024 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025 goto error;
2026 }
2027 PyErr_Clear();
2028 break;
2029 }
2030 written += n;
2031 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002032 /* Partial writes can return successfully when interrupted by a
2033 signal (see write(2)). We must run signal handlers before
2034 blocking another time, possibly indefinitely. */
2035 if (PyErr_CheckSignals() < 0)
2036 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 }
2038 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002039 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002040 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002041 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002042 written += remaining;
2043 }
2044 self->write_pos = 0;
2045 /* TODO: sanity check (remaining >= 0) */
2046 self->write_end = remaining;
2047 ADJUST_POSITION(self, remaining);
2048 self->raw_pos = 0;
2049
2050end:
2051 res = PyLong_FromSsize_t(written);
2052
2053error:
2054 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002055 return res;
2056}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002057
2058
2059
2060/*
2061 * BufferedRWPair
2062 */
2063
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064/* XXX The usefulness of this (compared to having two separate IO objects) is
2065 * questionable.
2066 */
2067
2068typedef struct {
2069 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002070 buffered *reader;
2071 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002072 PyObject *dict;
2073 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002074} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002075
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002076/*[clinic input]
2077_io.BufferedRWPair.__init__
2078 reader: object
2079 writer: object
2080 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2081 /
2082
2083A buffered reader and writer object together.
2084
2085A buffered reader object and buffered writer object put together to
2086form a sequential IO object that can read and write. This is typically
2087used with a socket or two-way pipe.
2088
2089reader and writer are RawIOBase objects that are readable and
2090writeable respectively. If the buffer_size is omitted it defaults to
2091DEFAULT_BUFFER_SIZE.
2092[clinic start generated code]*/
2093
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002094static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002095_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2096 PyObject *writer, Py_ssize_t buffer_size)
2097/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002099 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002100 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002101 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002102 return -1;
2103
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002104 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002105 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106 if (self->reader == NULL)
2107 return -1;
2108
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002109 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002110 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 if (self->writer == NULL) {
2112 Py_CLEAR(self->reader);
2113 return -1;
2114 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002115
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002116 return 0;
2117}
2118
2119static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121{
2122 Py_VISIT(self->dict);
2123 return 0;
2124}
2125
2126static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002127bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128{
2129 Py_CLEAR(self->reader);
2130 Py_CLEAR(self->writer);
2131 Py_CLEAR(self->dict);
2132 return 0;
2133}
2134
2135static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002136bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002137{
2138 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002139 if (self->weakreflist != NULL)
2140 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141 Py_CLEAR(self->reader);
2142 Py_CLEAR(self->writer);
2143 Py_CLEAR(self->dict);
2144 Py_TYPE(self)->tp_free((PyObject *) self);
2145}
2146
2147static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002148_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002150 PyObject *func, *ret;
2151 if (self == NULL) {
2152 PyErr_SetString(PyExc_ValueError,
2153 "I/O operation on uninitialized object");
2154 return NULL;
2155 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002157 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002158 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002159 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160 return NULL;
2161 }
2162
2163 ret = PyObject_CallObject(func, args);
2164 Py_DECREF(func);
2165 return ret;
2166}
2167
2168static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002169bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002171 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002172}
2173
2174static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002175bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002176{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002177 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178}
2179
2180static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002181bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002183 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184}
2185
2186static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002187bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002188{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002189 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002190}
2191
2192static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002193bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2194{
2195 return _forward_call(self->reader, &PyId_readinto1, args);
2196}
2197
2198static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002199bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002200{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002201 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202}
2203
2204static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002205bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002206{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002207 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002208}
2209
2210static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002211bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002212{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002213 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002214}
2215
2216static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002217bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002219 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002220}
2221
2222static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002225 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002226 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002228 PyErr_Fetch(&exc, &val, &tb);
2229 else
2230 Py_DECREF(ret);
2231 ret = _forward_call(self->reader, &PyId_close, args);
2232 if (exc != NULL) {
2233 _PyErr_ChainExceptions(exc, val, tb);
2234 Py_CLEAR(ret);
2235 }
2236 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237}
2238
2239static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002240bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002241{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002242 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002243
2244 if (ret != Py_False) {
2245 /* either True or exception */
2246 return ret;
2247 }
2248 Py_DECREF(ret);
2249
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002250 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251}
2252
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002253static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002254bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002255{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002256 if (self->writer == NULL) {
2257 PyErr_SetString(PyExc_RuntimeError,
2258 "the BufferedRWPair object is being garbage-collected");
2259 return NULL;
2260 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002261 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2262}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002263
2264
2265
2266/*
2267 * BufferedRandom
2268 */
2269
2270/*[clinic input]
2271_io.BufferedRandom.__init__
2272 raw: object
2273 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2274
2275A buffered interface to random access streams.
2276
2277The constructor creates a reader and writer for a seekable stream,
2278raw, given in the first argument. If the buffer_size is omitted it
2279defaults to DEFAULT_BUFFER_SIZE.
2280[clinic start generated code]*/
2281
2282static int
2283_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2284 Py_ssize_t buffer_size)
2285/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2286{
2287 self->ok = 0;
2288 self->detached = 0;
2289
2290 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2291 return -1;
2292 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2293 return -1;
2294 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2295 return -1;
2296
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002297 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002298 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002299 self->buffer_size = buffer_size;
2300 self->readable = 1;
2301 self->writable = 1;
2302
2303 if (_buffered_init(self) < 0)
2304 return -1;
2305 _bufferedreader_reset_buf(self);
2306 _bufferedwriter_reset_buf(self);
2307 self->pos = 0;
2308
2309 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2310 Py_TYPE(raw) == &PyFileIO_Type);
2311
2312 self->ok = 1;
2313 return 0;
2314}
2315
2316#include "clinic/bufferedio.c.h"
2317
2318
2319static PyMethodDef bufferediobase_methods[] = {
2320 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2321 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2322 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2323 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2324 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2325 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2326 {NULL, NULL}
2327};
2328
2329PyTypeObject PyBufferedIOBase_Type = {
2330 PyVarObject_HEAD_INIT(NULL, 0)
2331 "_io._BufferedIOBase", /*tp_name*/
2332 0, /*tp_basicsize*/
2333 0, /*tp_itemsize*/
2334 0, /*tp_dealloc*/
2335 0, /*tp_print*/
2336 0, /*tp_getattr*/
2337 0, /*tp_setattr*/
2338 0, /*tp_compare */
2339 0, /*tp_repr*/
2340 0, /*tp_as_number*/
2341 0, /*tp_as_sequence*/
2342 0, /*tp_as_mapping*/
2343 0, /*tp_hash */
2344 0, /*tp_call*/
2345 0, /*tp_str*/
2346 0, /*tp_getattro*/
2347 0, /*tp_setattro*/
2348 0, /*tp_as_buffer*/
2349 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2350 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2351 bufferediobase_doc, /* tp_doc */
2352 0, /* tp_traverse */
2353 0, /* tp_clear */
2354 0, /* tp_richcompare */
2355 0, /* tp_weaklistoffset */
2356 0, /* tp_iter */
2357 0, /* tp_iternext */
2358 bufferediobase_methods, /* tp_methods */
2359 0, /* tp_members */
2360 0, /* tp_getset */
2361 &PyIOBase_Type, /* tp_base */
2362 0, /* tp_dict */
2363 0, /* tp_descr_get */
2364 0, /* tp_descr_set */
2365 0, /* tp_dictoffset */
2366 0, /* tp_init */
2367 0, /* tp_alloc */
2368 0, /* tp_new */
2369 0, /* tp_free */
2370 0, /* tp_is_gc */
2371 0, /* tp_bases */
2372 0, /* tp_mro */
2373 0, /* tp_cache */
2374 0, /* tp_subclasses */
2375 0, /* tp_weaklist */
2376 0, /* tp_del */
2377 0, /* tp_version_tag */
2378 0, /* tp_finalize */
2379};
2380
2381
2382static PyMethodDef bufferedreader_methods[] = {
2383 /* BufferedIOMixin methods */
2384 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2385 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2386 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2387 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2388 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002389 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2390 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2391 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2392 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2393
2394 _IO__BUFFERED_READ_METHODDEF
2395 _IO__BUFFERED_PEEK_METHODDEF
2396 _IO__BUFFERED_READ1_METHODDEF
2397 _IO__BUFFERED_READINTO_METHODDEF
2398 _IO__BUFFERED_READINTO1_METHODDEF
2399 _IO__BUFFERED_READLINE_METHODDEF
2400 _IO__BUFFERED_SEEK_METHODDEF
2401 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2402 _IO__BUFFERED_TRUNCATE_METHODDEF
2403 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2404 {NULL, NULL}
2405};
2406
2407static PyMemberDef bufferedreader_members[] = {
2408 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2409 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2410 {NULL}
2411};
2412
2413static PyGetSetDef bufferedreader_getset[] = {
2414 {"closed", (getter)buffered_closed_get, NULL, NULL},
2415 {"name", (getter)buffered_name_get, NULL, NULL},
2416 {"mode", (getter)buffered_mode_get, NULL, NULL},
2417 {NULL}
2418};
2419
2420
2421PyTypeObject PyBufferedReader_Type = {
2422 PyVarObject_HEAD_INIT(NULL, 0)
2423 "_io.BufferedReader", /*tp_name*/
2424 sizeof(buffered), /*tp_basicsize*/
2425 0, /*tp_itemsize*/
2426 (destructor)buffered_dealloc, /*tp_dealloc*/
2427 0, /*tp_print*/
2428 0, /*tp_getattr*/
2429 0, /*tp_setattr*/
2430 0, /*tp_compare */
2431 (reprfunc)buffered_repr, /*tp_repr*/
2432 0, /*tp_as_number*/
2433 0, /*tp_as_sequence*/
2434 0, /*tp_as_mapping*/
2435 0, /*tp_hash */
2436 0, /*tp_call*/
2437 0, /*tp_str*/
2438 0, /*tp_getattro*/
2439 0, /*tp_setattro*/
2440 0, /*tp_as_buffer*/
2441 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2442 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2443 _io_BufferedReader___init____doc__, /* tp_doc */
2444 (traverseproc)buffered_traverse, /* tp_traverse */
2445 (inquiry)buffered_clear, /* tp_clear */
2446 0, /* tp_richcompare */
2447 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2448 0, /* tp_iter */
2449 (iternextfunc)buffered_iternext, /* tp_iternext */
2450 bufferedreader_methods, /* tp_methods */
2451 bufferedreader_members, /* tp_members */
2452 bufferedreader_getset, /* tp_getset */
2453 0, /* tp_base */
2454 0, /* tp_dict */
2455 0, /* tp_descr_get */
2456 0, /* tp_descr_set */
2457 offsetof(buffered, dict), /* tp_dictoffset */
2458 _io_BufferedReader___init__, /* tp_init */
2459 0, /* tp_alloc */
2460 PyType_GenericNew, /* tp_new */
2461 0, /* tp_free */
2462 0, /* tp_is_gc */
2463 0, /* tp_bases */
2464 0, /* tp_mro */
2465 0, /* tp_cache */
2466 0, /* tp_subclasses */
2467 0, /* tp_weaklist */
2468 0, /* tp_del */
2469 0, /* tp_version_tag */
2470 0, /* tp_finalize */
2471};
2472
2473
2474static PyMethodDef bufferedwriter_methods[] = {
2475 /* BufferedIOMixin methods */
2476 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2477 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2478 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002479 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2480 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2481 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2482 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2483 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2484
2485 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2486 _IO__BUFFERED_TRUNCATE_METHODDEF
2487 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2488 _IO__BUFFERED_SEEK_METHODDEF
2489 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2490 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2491 {NULL, NULL}
2492};
2493
2494static PyMemberDef bufferedwriter_members[] = {
2495 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2496 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2497 {NULL}
2498};
2499
2500static PyGetSetDef bufferedwriter_getset[] = {
2501 {"closed", (getter)buffered_closed_get, NULL, NULL},
2502 {"name", (getter)buffered_name_get, NULL, NULL},
2503 {"mode", (getter)buffered_mode_get, NULL, NULL},
2504 {NULL}
2505};
2506
2507
2508PyTypeObject PyBufferedWriter_Type = {
2509 PyVarObject_HEAD_INIT(NULL, 0)
2510 "_io.BufferedWriter", /*tp_name*/
2511 sizeof(buffered), /*tp_basicsize*/
2512 0, /*tp_itemsize*/
2513 (destructor)buffered_dealloc, /*tp_dealloc*/
2514 0, /*tp_print*/
2515 0, /*tp_getattr*/
2516 0, /*tp_setattr*/
2517 0, /*tp_compare */
2518 (reprfunc)buffered_repr, /*tp_repr*/
2519 0, /*tp_as_number*/
2520 0, /*tp_as_sequence*/
2521 0, /*tp_as_mapping*/
2522 0, /*tp_hash */
2523 0, /*tp_call*/
2524 0, /*tp_str*/
2525 0, /*tp_getattro*/
2526 0, /*tp_setattro*/
2527 0, /*tp_as_buffer*/
2528 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2529 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2530 _io_BufferedWriter___init____doc__, /* tp_doc */
2531 (traverseproc)buffered_traverse, /* tp_traverse */
2532 (inquiry)buffered_clear, /* tp_clear */
2533 0, /* tp_richcompare */
2534 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2535 0, /* tp_iter */
2536 0, /* tp_iternext */
2537 bufferedwriter_methods, /* tp_methods */
2538 bufferedwriter_members, /* tp_members */
2539 bufferedwriter_getset, /* tp_getset */
2540 0, /* tp_base */
2541 0, /* tp_dict */
2542 0, /* tp_descr_get */
2543 0, /* tp_descr_set */
2544 offsetof(buffered, dict), /* tp_dictoffset */
2545 _io_BufferedWriter___init__, /* tp_init */
2546 0, /* tp_alloc */
2547 PyType_GenericNew, /* tp_new */
2548 0, /* tp_free */
2549 0, /* tp_is_gc */
2550 0, /* tp_bases */
2551 0, /* tp_mro */
2552 0, /* tp_cache */
2553 0, /* tp_subclasses */
2554 0, /* tp_weaklist */
2555 0, /* tp_del */
2556 0, /* tp_version_tag */
2557 0, /* tp_finalize */
2558};
2559
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002561static PyMethodDef bufferedrwpair_methods[] = {
2562 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2563 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2564 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2565 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002566 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002567
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002568 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2569 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002570
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002571 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2572 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002573
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002574 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2575 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002576
Antoine Pitrou243757e2010-11-05 21:15:39 +00002577 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2578
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579 {NULL, NULL}
2580};
2581
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002582static PyGetSetDef bufferedrwpair_getset[] = {
2583 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002584 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002585};
2586
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002587PyTypeObject PyBufferedRWPair_Type = {
2588 PyVarObject_HEAD_INIT(NULL, 0)
2589 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002590 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002591 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002592 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002593 0, /*tp_print*/
2594 0, /*tp_getattr*/
2595 0, /*tp_setattr*/
2596 0, /*tp_compare */
2597 0, /*tp_repr*/
2598 0, /*tp_as_number*/
2599 0, /*tp_as_sequence*/
2600 0, /*tp_as_mapping*/
2601 0, /*tp_hash */
2602 0, /*tp_call*/
2603 0, /*tp_str*/
2604 0, /*tp_getattro*/
2605 0, /*tp_setattro*/
2606 0, /*tp_as_buffer*/
2607 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002608 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002609 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002610 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2611 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002612 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002613 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002614 0, /* tp_iter */
2615 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002616 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002617 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002618 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002619 0, /* tp_base */
2620 0, /* tp_dict */
2621 0, /* tp_descr_get */
2622 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002623 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002624 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002625 0, /* tp_alloc */
2626 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002627 0, /* tp_free */
2628 0, /* tp_is_gc */
2629 0, /* tp_bases */
2630 0, /* tp_mro */
2631 0, /* tp_cache */
2632 0, /* tp_subclasses */
2633 0, /* tp_weaklist */
2634 0, /* tp_del */
2635 0, /* tp_version_tag */
2636 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002637};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002638
2639
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002640static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002641 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002642 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2643 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2644 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2645 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2646 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2647 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2648 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002649 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002650 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002651
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002652 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002653
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002654 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002655 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002656 _IO__BUFFERED_TRUNCATE_METHODDEF
2657 _IO__BUFFERED_READ_METHODDEF
2658 _IO__BUFFERED_READ1_METHODDEF
2659 _IO__BUFFERED_READINTO_METHODDEF
2660 _IO__BUFFERED_READINTO1_METHODDEF
2661 _IO__BUFFERED_READLINE_METHODDEF
2662 _IO__BUFFERED_PEEK_METHODDEF
2663 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002664 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002665 {NULL, NULL}
2666};
2667
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002668static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002669 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002670 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002671 {NULL}
2672};
2673
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002674static PyGetSetDef bufferedrandom_getset[] = {
2675 {"closed", (getter)buffered_closed_get, NULL, NULL},
2676 {"name", (getter)buffered_name_get, NULL, NULL},
2677 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002678 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002679};
2680
2681
2682PyTypeObject PyBufferedRandom_Type = {
2683 PyVarObject_HEAD_INIT(NULL, 0)
2684 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002685 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002686 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002687 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002688 0, /*tp_print*/
2689 0, /*tp_getattr*/
2690 0, /*tp_setattr*/
2691 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002692 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002693 0, /*tp_as_number*/
2694 0, /*tp_as_sequence*/
2695 0, /*tp_as_mapping*/
2696 0, /*tp_hash */
2697 0, /*tp_call*/
2698 0, /*tp_str*/
2699 0, /*tp_getattro*/
2700 0, /*tp_setattro*/
2701 0, /*tp_as_buffer*/
2702 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002703 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002704 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002705 (traverseproc)buffered_traverse, /* tp_traverse */
2706 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002707 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002708 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002709 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002710 (iternextfunc)buffered_iternext, /* tp_iternext */
2711 bufferedrandom_methods, /* tp_methods */
2712 bufferedrandom_members, /* tp_members */
2713 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002714 0, /* tp_base */
2715 0, /*tp_dict*/
2716 0, /* tp_descr_get */
2717 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002718 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002719 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002720 0, /* tp_alloc */
2721 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002722 0, /* tp_free */
2723 0, /* tp_is_gc */
2724 0, /* tp_bases */
2725 0, /* tp_mro */
2726 0, /* tp_cache */
2727 0, /* tp_subclasses */
2728 0, /* tp_weaklist */
2729 0, /* tp_del */
2730 0, /* tp_version_tag */
2731 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002732};