blob: 59e9beb47cf47d286286f3653d0eb9a23d93a246 [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
12#include "structmember.h"
13#include "pythread.h"
14#include "_iomodule.h"
15
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030016/*[clinic input]
17module _io
18class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24[clinic start generated code]*/
25/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26
27/*[python input]
28class io_ssize_t_converter(CConverter):
29 type = 'Py_ssize_t'
30 converter = '_PyIO_ConvertSsize_t'
31[python start generated code]*/
32/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
33
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020034_Py_IDENTIFIER(close);
35_Py_IDENTIFIER(_dealloc_warn);
36_Py_IDENTIFIER(flush);
37_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020038_Py_IDENTIFIER(mode);
39_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020040_Py_IDENTIFIER(peek);
41_Py_IDENTIFIER(read);
42_Py_IDENTIFIER(read1);
43_Py_IDENTIFIER(readable);
44_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070045_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020046_Py_IDENTIFIER(writable);
47_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020048
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000049/*
50 * BufferedIOBase class, inherits from IOBase.
51 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000052PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000053 "Base class for buffered IO objects.\n"
54 "\n"
55 "The main difference with RawIOBase is that the read() method\n"
56 "supports omitting the size argument, and does not have a default\n"
57 "implementation that defers to readinto().\n"
58 "\n"
59 "In addition, read(), readinto() and write() may raise\n"
60 "BlockingIOError if the underlying raw stream is in non-blocking\n"
61 "mode and not ready; unlike their raw counterparts, they will never\n"
62 "return None.\n"
63 "\n"
64 "A typical implementation should not inherit from a RawIOBase\n"
65 "implementation, but wrap one.\n"
66 );
67
68static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030069_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071 Py_ssize_t len;
72 PyObject *data;
73
Benjamin Petersona96fea02014-06-22 14:17:44 -070074 data = _PyObject_CallMethodId(self,
75 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030076 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030078 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000079
80 if (!PyBytes_Check(data)) {
81 Py_DECREF(data);
82 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030083 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000084 }
85
86 len = Py_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030087 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030088 PyErr_Format(PyExc_ValueError,
89 "read() returned too much data: "
90 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030091 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030092 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030093 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030094 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030095 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000096
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000097 Py_DECREF(data);
98
99 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000100}
101
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300102/*[clinic input]
103_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700104 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300105 /
106[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700107
108static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300109_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700110/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700111{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300112 return _bufferediobase_readinto_generic(self, buffer, 0);
113}
114
115/*[clinic input]
116_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700117 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300118 /
119[clinic start generated code]*/
120
121static PyObject *
122_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700123/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300124{
125 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700126}
127
128static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000129bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000130{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100131 _PyIO_State *state = IO_STATE();
132 if (state != NULL)
133 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000134 return NULL;
135}
136
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300137/*[clinic input]
138_io._BufferedIOBase.detach
139
140Disconnect this buffer from its underlying raw stream and return it.
141
142After the raw stream has been detached, the buffer is in an unusable
143state.
144[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000145
146static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300147_io__BufferedIOBase_detach_impl(PyObject *self)
148/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000149{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000151}
152
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000153PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000154 "Read and return up to n bytes.\n"
155 "\n"
156 "If the argument is omitted, None, or negative, reads and\n"
157 "returns all data until EOF.\n"
158 "\n"
159 "If the argument is positive, and the underlying raw stream is\n"
160 "not 'interactive', multiple raw reads may be issued to satisfy\n"
161 "the byte count (unless EOF is reached first). But for\n"
162 "interactive raw streams (as well as sockets and pipes), at most\n"
163 "one raw read will be issued, and a short result does not imply\n"
164 "that EOF is imminent.\n"
165 "\n"
166 "Returns an empty bytes object on EOF.\n"
167 "\n"
168 "Returns None if the underlying raw stream was open in non-blocking\n"
169 "mode and no data is available at the moment.\n");
170
171static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000172bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000173{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000174 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000175}
176
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000177PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000178 "Read and return up to n bytes, with at most one read() call\n"
179 "to the underlying raw stream. A short result does not imply\n"
180 "that EOF is imminent.\n"
181 "\n"
182 "Returns an empty bytes object on EOF.\n");
183
184static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000185bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000186{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000187 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188}
189
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000190PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000191 "Write the given buffer to the IO stream.\n"
192 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000193 "Returns the number of bytes written, which is always the length of b\n"
194 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 "\n"
196 "Raises BlockingIOError if the buffer is full and the\n"
197 "underlying raw stream cannot accept more data at the moment.\n");
198
199static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000200bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000201{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000202 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000203}
204
205
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206typedef struct {
207 PyObject_HEAD
208
209 PyObject *raw;
210 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000211 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212 int readable;
213 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200214 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200215
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000216 /* True if this is a vanilla Buffered object (rather than a user derived
217 class) *and* the raw stream is a vanilla FileIO object. */
218 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000219
220 /* Absolute position inside the raw stream (-1 if unknown). */
221 Py_off_t abs_pos;
222
223 /* A static buffer of size `buffer_size` */
224 char *buffer;
225 /* Current logical position in the buffer. */
226 Py_off_t pos;
227 /* Position of the raw stream in the buffer. */
228 Py_off_t raw_pos;
229
230 /* Just after the last buffered byte in the buffer, or -1 if the buffer
231 isn't ready for reading. */
232 Py_off_t read_end;
233
234 /* Just after the last byte actually written */
235 Py_off_t write_pos;
236 /* Just after the last byte waiting to be written, or -1 if the buffer
237 isn't ready for writing. */
238 Py_off_t write_end;
239
Georg Brandldfd73442009-04-05 11:47:34 +0000240#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000241 PyThread_type_lock lock;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000242 volatile long owner;
Georg Brandldfd73442009-04-05 11:47:34 +0000243#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000244
245 Py_ssize_t buffer_size;
246 Py_ssize_t buffer_mask;
247
248 PyObject *dict;
249 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000250} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251
252/*
253 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200254
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000255 * BufferedReader, BufferedWriter and BufferedRandom try to share most
256 methods (this is helped by the members `readable` and `writable`, which
257 are initialized in the respective constructors)
258 * They also share a single buffer for reading and writing. This enables
259 interleaved reads and writes without flushing. It also makes the logic
260 a bit trickier to get right.
261 * The absolute position of the raw stream is cached, if possible, in the
262 `abs_pos` member. It must be updated every time an operation is done
263 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000264 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000265 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000266 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
267 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268
269 NOTE: we should try to maintain block alignment of reads and writes to the
270 raw stream (according to the buffer size), but for now it is only done
271 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200272
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000273*/
274
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000275/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000276
Georg Brandldfd73442009-04-05 11:47:34 +0000277#ifdef WITH_THREAD
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000278
279static int
280_enter_buffered_busy(buffered *self)
281{
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200282 int relax_locking;
283 PyLockStatus st;
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000284 if (self->owner == PyThread_get_thread_ident()) {
285 PyErr_Format(PyExc_RuntimeError,
286 "reentrant call inside %R", self);
287 return 0;
Antoine Pitrou5800b272009-11-01 12:05:48 +0000288 }
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200289 relax_locking = (_Py_Finalizing != NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000290 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200291 if (!relax_locking)
292 st = PyThread_acquire_lock(self->lock, 1);
293 else {
294 /* When finalizing, we don't want a deadlock to happen with daemon
295 * threads abruptly shut down while they owned the lock.
296 * Therefore, only wait for a grace period (1 s.).
297 * Note that non-daemon threads have already exited here, so this
298 * shouldn't affect carefully written threaded I/O code.
299 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700300 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200301 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000302 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200303 if (relax_locking && st != PY_LOCK_ACQUIRED) {
304 PyObject *msgobj = PyUnicode_FromFormat(
305 "could not acquire lock for %A at interpreter "
306 "shutdown, possibly due to daemon threads",
307 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200308 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200309 Py_FatalError(msg);
310 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000311 return 1;
312}
313
314#define ENTER_BUFFERED(self) \
315 ( (PyThread_acquire_lock(self->lock, 0) ? \
316 1 : _enter_buffered_busy(self)) \
317 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000318
319#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000320 do { \
321 self->owner = 0; \
322 PyThread_release_lock(self->lock); \
323 } while(0);
324
Georg Brandldfd73442009-04-05 11:47:34 +0000325#else
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000326#define ENTER_BUFFERED(self) 1
Georg Brandldfd73442009-04-05 11:47:34 +0000327#define LEAVE_BUFFERED(self)
328#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000329
330#define CHECK_INITIALIZED(self) \
331 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000332 if (self->detached) { \
333 PyErr_SetString(PyExc_ValueError, \
334 "raw stream has been detached"); \
335 } else { \
336 PyErr_SetString(PyExc_ValueError, \
337 "I/O operation on uninitialized object"); \
338 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 return NULL; \
340 }
341
342#define CHECK_INITIALIZED_INT(self) \
343 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000344 if (self->detached) { \
345 PyErr_SetString(PyExc_ValueError, \
346 "raw stream has been detached"); \
347 } else { \
348 PyErr_SetString(PyExc_ValueError, \
349 "I/O operation on uninitialized object"); \
350 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000351 return -1; \
352 }
353
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000354#define IS_CLOSED(self) \
355 (self->fast_closed_checks \
356 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000357 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000358
359#define CHECK_CLOSED(self, error_msg) \
360 if (IS_CLOSED(self)) { \
361 PyErr_SetString(PyExc_ValueError, error_msg); \
362 return NULL; \
363 }
364
365
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000366#define VALID_READ_BUFFER(self) \
367 (self->readable && self->read_end != -1)
368
369#define VALID_WRITE_BUFFER(self) \
370 (self->writable && self->write_end != -1)
371
372#define ADJUST_POSITION(self, _new_pos) \
373 do { \
374 self->pos = _new_pos; \
375 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
376 self->read_end = self->pos; \
377 } while(0)
378
379#define READAHEAD(self) \
380 ((self->readable && VALID_READ_BUFFER(self)) \
381 ? (self->read_end - self->pos) : 0)
382
383#define RAW_OFFSET(self) \
384 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
385 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
386
387#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000388 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000389
390#define MINUS_LAST_BLOCK(self, size) \
391 (self->buffer_mask ? \
392 (size & ~self->buffer_mask) : \
393 (self->buffer_size * (size / self->buffer_size)))
394
395
396static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000397buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000398{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200399 self->finalizing = 1;
400 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000401 return;
402 _PyObject_GC_UNTRACK(self);
403 self->ok = 0;
404 if (self->weakreflist != NULL)
405 PyObject_ClearWeakRefs((PyObject *)self);
406 Py_CLEAR(self->raw);
407 if (self->buffer) {
408 PyMem_Free(self->buffer);
409 self->buffer = NULL;
410 }
Georg Brandldfd73442009-04-05 11:47:34 +0000411#ifdef WITH_THREAD
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000412 if (self->lock) {
413 PyThread_free_lock(self->lock);
414 self->lock = NULL;
415 }
Georg Brandldfd73442009-04-05 11:47:34 +0000416#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000417 Py_CLEAR(self->dict);
418 Py_TYPE(self)->tp_free((PyObject *)self);
419}
420
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200421static PyObject *
422buffered_sizeof(buffered *self, void *unused)
423{
424 Py_ssize_t res;
425
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200426 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200427 if (self->buffer)
428 res += self->buffer_size;
429 return PyLong_FromSsize_t(res);
430}
431
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000432static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000433buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000434{
435 Py_VISIT(self->raw);
436 Py_VISIT(self->dict);
437 return 0;
438}
439
440static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000441buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000442{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000443 self->ok = 0;
444 Py_CLEAR(self->raw);
445 Py_CLEAR(self->dict);
446 return 0;
447}
448
Antoine Pitroue033e062010-10-29 10:38:18 +0000449/* Because this can call arbitrary code, it shouldn't be called when
450 the refcount is 0 (that is, not directly from tp_dealloc unless
451 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000452static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000453buffered_dealloc_warn(buffered *self, PyObject *source)
454{
455 if (self->ok && self->raw) {
456 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100457 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
458 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000459 if (r)
460 Py_DECREF(r);
461 else
462 PyErr_Clear();
463 }
464 Py_RETURN_NONE;
465}
466
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000467/*
468 * _BufferedIOMixin methods
469 * This is not a class, just a collection of methods that will be reused
470 * by BufferedReader and BufferedWriter
471 */
472
473/* Flush and close */
474
475static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000476buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000477{
478 CHECK_INITIALIZED(self)
479 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
480}
481
482static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000483buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000484{
485 int closed;
486 PyObject *res;
487 CHECK_INITIALIZED_INT(self)
488 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
489 if (res == NULL)
490 return -1;
491 closed = PyObject_IsTrue(res);
492 Py_DECREF(res);
493 return closed;
494}
495
496static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000497buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000498{
499 CHECK_INITIALIZED(self)
500 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
501}
502
503static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000504buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000505{
Benjamin Peterson68623612012-12-20 11:53:11 -0600506 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507 int r;
508
509 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000510 if (!ENTER_BUFFERED(self))
511 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000513 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000514 if (r < 0)
515 goto end;
516 if (r > 0) {
517 res = Py_None;
518 Py_INCREF(res);
519 goto end;
520 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000521
Antoine Pitrou796564c2013-07-30 19:59:21 +0200522 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000523 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
524 if (r)
525 Py_DECREF(r);
526 else
527 PyErr_Clear();
528 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000529 /* flush() will most probably re-take the lock, so drop it first */
530 LEAVE_BUFFERED(self)
531 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000532 if (!ENTER_BUFFERED(self))
533 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600534 if (res == NULL)
535 PyErr_Fetch(&exc, &val, &tb);
536 else
537 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000538
539 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
540
Jesus Ceadc469452012-10-04 12:37:56 +0200541 if (self->buffer) {
542 PyMem_Free(self->buffer);
543 self->buffer = NULL;
544 }
545
Benjamin Peterson68623612012-12-20 11:53:11 -0600546 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300547 _PyErr_ChainExceptions(exc, val, tb);
548 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600549 }
550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000551end:
552 LEAVE_BUFFERED(self)
553 return res;
554}
555
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000556/* detach */
557
558static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000560{
561 PyObject *raw, *res;
562 CHECK_INITIALIZED(self)
563 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
564 if (res == NULL)
565 return NULL;
566 Py_DECREF(res);
567 raw = self->raw;
568 self->raw = NULL;
569 self->detached = 1;
570 self->ok = 0;
571 return raw;
572}
573
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574/* Inquiries */
575
576static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000577buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578{
579 CHECK_INITIALIZED(self)
580 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
581}
582
583static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000584buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 CHECK_INITIALIZED(self)
587 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
588}
589
590static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000591buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000592{
593 CHECK_INITIALIZED(self)
594 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
595}
596
597static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000598buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599{
600 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200601 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000602}
603
604static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000605buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606{
607 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200608 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609}
610
611/* Lower-level APIs */
612
613static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000614buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615{
616 CHECK_INITIALIZED(self)
617 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
618}
619
620static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000621buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622{
623 CHECK_INITIALIZED(self)
624 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
625}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000626
Antoine Pitrou243757e2010-11-05 21:15:39 +0000627/* Serialization */
628
629static PyObject *
630buffered_getstate(buffered *self, PyObject *args)
631{
632 PyErr_Format(PyExc_TypeError,
633 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
634 return NULL;
635}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000636
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000637/* Forward decls */
638static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100639_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000640static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000645_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200647_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000650static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000651_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000652static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200654static Py_ssize_t
655_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000656
657/*
658 * Helpers
659 */
660
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100661/* Sets the current error to BlockingIOError */
662static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200663_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100664{
665 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200666 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100667 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
668 errno, msg, written);
669 if (err)
670 PyErr_SetObject(PyExc_BlockingIOError, err);
671 Py_XDECREF(err);
672}
673
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674/* Returns the address of the `written` member if a BlockingIOError was
675 raised, NULL otherwise. The error is always re-raised. */
676static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000677_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678{
679 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200680 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681
682 PyErr_Fetch(&t, &v, &tb);
683 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
684 PyErr_Restore(t, v, tb);
685 return NULL;
686 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200687 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688 /* TODO: sanity check (err->written >= 0) */
689 PyErr_Restore(t, v, tb);
690 return &err->written;
691}
692
693static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000694_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000697 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
699 if (res == NULL)
700 return -1;
701 n = PyNumber_AsOff_t(res, PyExc_ValueError);
702 Py_DECREF(res);
703 if (n < 0) {
704 if (!PyErr_Occurred())
705 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000706 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200707 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708 return -1;
709 }
710 self->abs_pos = n;
711 return n;
712}
713
714static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000715_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716{
717 PyObject *res, *posobj, *whenceobj;
718 Py_off_t n;
719
720 posobj = PyLong_FromOff_t(target);
721 if (posobj == NULL)
722 return -1;
723 whenceobj = PyLong_FromLong(whence);
724 if (whenceobj == NULL) {
725 Py_DECREF(posobj);
726 return -1;
727 }
728 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
729 posobj, whenceobj, NULL);
730 Py_DECREF(posobj);
731 Py_DECREF(whenceobj);
732 if (res == NULL)
733 return -1;
734 n = PyNumber_AsOff_t(res, PyExc_ValueError);
735 Py_DECREF(res);
736 if (n < 0) {
737 if (!PyErr_Occurred())
738 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000739 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200740 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 return -1;
742 }
743 self->abs_pos = n;
744 return n;
745}
746
747static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000748_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000749{
750 Py_ssize_t n;
751 if (self->buffer_size <= 0) {
752 PyErr_SetString(PyExc_ValueError,
753 "buffer size must be strictly positive");
754 return -1;
755 }
756 if (self->buffer)
757 PyMem_Free(self->buffer);
758 self->buffer = PyMem_Malloc(self->buffer_size);
759 if (self->buffer == NULL) {
760 PyErr_NoMemory();
761 return -1;
762 }
Georg Brandldfd73442009-04-05 11:47:34 +0000763#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000764 if (self->lock)
765 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766 self->lock = PyThread_allocate_lock();
767 if (self->lock == NULL) {
768 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
769 return -1;
770 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000771 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000772#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773 /* Find out whether buffer_size is a power of 2 */
774 /* XXX is this optimization useful? */
775 for (n = self->buffer_size - 1; n & 1; n >>= 1)
776 ;
777 if (n == 0)
778 self->buffer_mask = self->buffer_size - 1;
779 else
780 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000781 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000782 PyErr_Clear();
783 return 0;
784}
785
Antoine Pitrou707ce822011-02-25 21:24:11 +0000786/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
787 clears the error indicator), 0 otherwise.
788 Should only be called when PyErr_Occurred() is true.
789*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700790int
791_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000792{
793 static PyObject *eintr_int = NULL;
794 PyObject *typ, *val, *tb;
795 PyEnvironmentErrorObject *env_err;
796
797 if (eintr_int == NULL) {
798 eintr_int = PyLong_FromLong(EINTR);
799 assert(eintr_int != NULL);
800 }
801 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
802 return 0;
803 PyErr_Fetch(&typ, &val, &tb);
804 PyErr_NormalizeException(&typ, &val, &tb);
805 env_err = (PyEnvironmentErrorObject *) val;
806 assert(env_err != NULL);
807 if (env_err->myerrno != NULL &&
808 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
809 Py_DECREF(typ);
810 Py_DECREF(val);
811 Py_XDECREF(tb);
812 return 1;
813 }
814 /* This silences any error set by PyObject_RichCompareBool() */
815 PyErr_Restore(typ, val, tb);
816 return 0;
817}
818
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819/*
820 * Shared methods and wrappers
821 */
822
823static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200824buffered_flush_and_rewind_unlocked(buffered *self)
825{
826 PyObject *res;
827
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100828 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200829 if (res == NULL)
830 return NULL;
831 Py_DECREF(res);
832
833 if (self->readable) {
834 /* Rewind the raw stream so that its position corresponds to
835 the current logical position. */
836 Py_off_t n;
837 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
838 _bufferedreader_reset_buf(self);
839 if (n == -1)
840 return NULL;
841 }
842 Py_RETURN_NONE;
843}
844
845static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000846buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000847{
848 PyObject *res;
849
850 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000851 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000852
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000853 if (!ENTER_BUFFERED(self))
854 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200855 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000856 LEAVE_BUFFERED(self)
857
858 return res;
859}
860
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300861/*[clinic input]
862_io._Buffered.peek
863 size: Py_ssize_t = 0
864 /
865
866[clinic start generated code]*/
867
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000868static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300869_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
870/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000872 PyObject *res = NULL;
873
874 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300875 CHECK_CLOSED(self, "peek of closed file")
876
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000877 if (!ENTER_BUFFERED(self))
878 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000879
880 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200881 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882 if (res == NULL)
883 goto end;
884 Py_CLEAR(res);
885 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200886 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000887
888end:
889 LEAVE_BUFFERED(self)
890 return res;
891}
892
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300893/*[clinic input]
894_io._Buffered.read
895 size as n: io_ssize_t = -1
896 /
897[clinic start generated code]*/
898
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000899static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300900_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
901/*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000903 PyObject *res;
904
905 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000906 if (n < -1) {
907 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000908 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909 return NULL;
910 }
911
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000912 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000913
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000914 if (n == -1) {
915 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000916 if (!ENTER_BUFFERED(self))
917 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000918 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000919 }
920 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000921 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200922 if (res != Py_None)
923 return res;
924 Py_DECREF(res);
925 if (!ENTER_BUFFERED(self))
926 return NULL;
927 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000928 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000929
Antoine Pitroue05565e2011-08-20 14:39:23 +0200930 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931 return res;
932}
933
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300934/*[clinic input]
935_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000936 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300937 /
938[clinic start generated code]*/
939
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300941_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000942/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300944 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945 PyObject *res = NULL;
946
947 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000949 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300951
952 CHECK_CLOSED(self, "read of closed file")
953
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954 if (n == 0)
955 return PyBytes_FromStringAndSize(NULL, 0);
956
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 /* Return up to n bytes. If at least one byte is buffered, we
958 only return buffered bytes. Otherwise, we do one raw read. */
959
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
961 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100962 n = Py_MIN(have, n);
963 res = _bufferedreader_read_fast(self, n);
964 assert(res != Py_None);
965 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000966 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100967 res = PyBytes_FromStringAndSize(NULL, n);
968 if (res == NULL)
969 return NULL;
970 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200971 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100972 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200973 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000974 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100975 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
976 LEAVE_BUFFERED(self)
977 if (r == -1) {
978 Py_DECREF(res);
979 return NULL;
980 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981 if (r == -2)
982 r = 0;
983 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100984 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985 return res;
986}
987
988static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300989_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200991 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 PyObject *res = NULL;
993
994 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
997 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300998 if (n >= buffer->len) {
999 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1000 self->pos += buffer->len;
1001 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001002 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001003 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001004 self->pos += n;
1005 written = n;
1006 }
1007
1008 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001009 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001010
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001011 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001012 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001013 if (res == NULL)
1014 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001015 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001016 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001017
1018 _bufferedreader_reset_buf(self);
1019 self->pos = 0;
1020
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001021 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001022 remaining > 0;
1023 written += n, remaining -= n) {
1024 /* If remaining bytes is larger than internal buffer size, copy
1025 * directly into caller's buffer. */
1026 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001027 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001028 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001029 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001030
1031 /* In readinto1 mode, we do not want to fill the internal
1032 buffer if we already have some data to return */
1033 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001034 n = _bufferedreader_fill_buffer(self);
1035 if (n > 0) {
1036 if (n > remaining)
1037 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001038 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001039 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001040 self->pos += n;
1041 continue; /* short circuit */
1042 }
1043 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001044 else
1045 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001046
Antoine Pitrou3486a982011-05-12 01:57:53 +02001047 if (n == 0 || (n == -2 && written > 0))
1048 break;
1049 if (n < 0) {
1050 if (n == -2) {
1051 Py_INCREF(Py_None);
1052 res = Py_None;
1053 }
1054 goto end;
1055 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001056
Benjamin Petersona96fea02014-06-22 14:17:44 -07001057 /* At most one read in readinto1 mode */
1058 if (readinto1) {
1059 written += n;
1060 break;
1061 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001062 }
1063 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001064
1065end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001066 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067 return res;
1068}
1069
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001070/*[clinic input]
1071_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001072 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001073 /
1074[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001075
1076static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001077_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001078/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001079{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001080 return _buffered_readinto_generic(self, buffer, 0);
1081}
1082
1083/*[clinic input]
1084_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001085 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001086 /
1087[clinic start generated code]*/
1088
1089static PyObject *
1090_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001091/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001092{
1093 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001094}
1095
1096
1097static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001098_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001099{
1100 PyObject *res = NULL;
1101 PyObject *chunks = NULL;
1102 Py_ssize_t n, written = 0;
1103 const char *start, *s, *end;
1104
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001105 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001106
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001107 /* First, try to find a line in the buffer. This can run unlocked because
1108 the calls to the C API are simple enough that they can't trigger
1109 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001110 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1111 if (limit >= 0 && n > limit)
1112 n = limit;
1113 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001114 s = memchr(start, '\n', n);
1115 if (s != NULL) {
1116 res = PyBytes_FromStringAndSize(start, s - start + 1);
1117 if (res != NULL)
1118 self->pos += s - start + 1;
1119 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001120 }
1121 if (n == limit) {
1122 res = PyBytes_FromStringAndSize(start, n);
1123 if (res != NULL)
1124 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001125 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001126 }
1127
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001128 if (!ENTER_BUFFERED(self))
1129 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001130
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001131 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132 chunks = PyList_New(0);
1133 if (chunks == NULL)
1134 goto end;
1135 if (n > 0) {
1136 res = PyBytes_FromStringAndSize(start, n);
1137 if (res == NULL)
1138 goto end;
1139 if (PyList_Append(chunks, res) < 0) {
1140 Py_CLEAR(res);
1141 goto end;
1142 }
1143 Py_CLEAR(res);
1144 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001145 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001146 if (limit >= 0)
1147 limit -= n;
1148 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001149 if (self->writable) {
1150 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1151 if (r == NULL)
1152 goto end;
1153 Py_DECREF(r);
1154 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001155
1156 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001157 _bufferedreader_reset_buf(self);
1158 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001159 if (n == -1)
1160 goto end;
1161 if (n <= 0)
1162 break;
1163 if (limit >= 0 && n > limit)
1164 n = limit;
1165 start = self->buffer;
1166 end = start + n;
1167 s = start;
1168 while (s < end) {
1169 if (*s++ == '\n') {
1170 res = PyBytes_FromStringAndSize(start, s - start);
1171 if (res == NULL)
1172 goto end;
1173 self->pos = s - start;
1174 goto found;
1175 }
1176 }
1177 res = PyBytes_FromStringAndSize(start, n);
1178 if (res == NULL)
1179 goto end;
1180 if (n == limit) {
1181 self->pos = n;
1182 break;
1183 }
1184 if (PyList_Append(chunks, res) < 0) {
1185 Py_CLEAR(res);
1186 goto end;
1187 }
1188 Py_CLEAR(res);
1189 written += n;
1190 if (limit >= 0)
1191 limit -= n;
1192 }
1193found:
1194 if (res != NULL && PyList_Append(chunks, res) < 0) {
1195 Py_CLEAR(res);
1196 goto end;
1197 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001198 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001199
1200end:
1201 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001202end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001203 Py_XDECREF(chunks);
1204 return res;
1205}
1206
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001207/*[clinic input]
1208_io._Buffered.readline
1209 size: io_ssize_t = -1
1210 /
1211[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001212
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001213static PyObject *
1214_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
1215/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
1216{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001217 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001218 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219}
1220
1221
1222static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001223buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001224{
1225 Py_off_t pos;
1226
1227 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001228 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001229 if (pos == -1)
1230 return NULL;
1231 pos -= RAW_OFFSET(self);
1232 /* TODO: sanity check (pos >= 0) */
1233 return PyLong_FromOff_t(pos);
1234}
1235
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001236/*[clinic input]
1237_io._Buffered.seek
1238 target as targetobj: object
1239 whence: int = 0
1240 /
1241[clinic start generated code]*/
1242
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001244_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1245/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246{
1247 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001248 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249
1250 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001251
1252 /* Do some error checking instead of trusting OS 'seek()'
1253 ** error detection, just in case.
1254 */
1255 if ((whence < 0 || whence >2)
1256#ifdef SEEK_HOLE
1257 && (whence != SEEK_HOLE)
1258#endif
1259#ifdef SEEK_DATA
1260 && (whence != SEEK_DATA)
1261#endif
1262 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001264 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265 return NULL;
1266 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001267
1268 CHECK_CLOSED(self, "seek of closed file")
1269
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001270 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1271 return NULL;
1272
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001273 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1274 if (target == -1 && PyErr_Occurred())
1275 return NULL;
1276
Jesus Cea94363612012-06-22 18:32:07 +02001277 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1278 buffer. Other whence values must be managed without this optimization.
1279 Some Operating Systems can provide additional values, like
1280 SEEK_HOLE/SEEK_DATA. */
1281 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 Py_off_t current, avail;
1283 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001284 so as to return quickly if possible. Also, we needn't take the
1285 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001286 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001287 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1288 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 current = RAW_TELL(self);
1290 avail = READAHEAD(self);
1291 if (avail > 0) {
1292 Py_off_t offset;
1293 if (whence == 0)
1294 offset = target - (current - RAW_OFFSET(self));
1295 else
1296 offset = target;
1297 if (offset >= -self->pos && offset <= avail) {
1298 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001299 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300 }
1301 }
1302 }
1303
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001304 if (!ENTER_BUFFERED(self))
1305 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001306
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001307 /* Fallback: invoke raw seek() method and clear buffer */
1308 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001309 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 if (res == NULL)
1311 goto end;
1312 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001313 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001314 }
1315
1316 /* TODO: align on block boundary and read buffer if needed? */
1317 if (whence == 1)
1318 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001319 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001320 if (n == -1)
1321 goto end;
1322 self->raw_pos = -1;
1323 res = PyLong_FromOff_t(n);
1324 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001325 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001326
1327end:
1328 LEAVE_BUFFERED(self)
1329 return res;
1330}
1331
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001332/*[clinic input]
1333_io._Buffered.truncate
1334 pos: object = None
1335 /
1336[clinic start generated code]*/
1337
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001338static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001339_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1340/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001342 PyObject *res = NULL;
1343
1344 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001345 if (!ENTER_BUFFERED(self))
1346 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001347
1348 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001349 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350 if (res == NULL)
1351 goto end;
1352 Py_CLEAR(res);
1353 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001354 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1355 if (res == NULL)
1356 goto end;
1357 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001358 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001359 PyErr_Clear();
1360
1361end:
1362 LEAVE_BUFFERED(self)
1363 return res;
1364}
1365
1366static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001367buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001368{
1369 PyObject *line;
1370 PyTypeObject *tp;
1371
1372 CHECK_INITIALIZED(self);
1373
1374 tp = Py_TYPE(self);
1375 if (tp == &PyBufferedReader_Type ||
1376 tp == &PyBufferedRandom_Type) {
1377 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001378 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001379 }
1380 else {
1381 line = PyObject_CallMethodObjArgs((PyObject *)self,
1382 _PyIO_str_readline, NULL);
1383 if (line && !PyBytes_Check(line)) {
1384 PyErr_Format(PyExc_IOError,
1385 "readline() should have returned a bytes object, "
1386 "not '%.200s'", Py_TYPE(line)->tp_name);
1387 Py_DECREF(line);
1388 return NULL;
1389 }
1390 }
1391
1392 if (line == NULL)
1393 return NULL;
1394
1395 if (PyBytes_GET_SIZE(line) == 0) {
1396 /* Reached EOF or would have blocked */
1397 Py_DECREF(line);
1398 return NULL;
1399 }
1400
1401 return line;
1402}
1403
Antoine Pitrou716c4442009-05-23 19:04:03 +00001404static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001405buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001406{
1407 PyObject *nameobj, *res;
1408
Martin v. Löwis767046a2011-10-14 15:35:36 +02001409 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001410 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001411 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001412 PyErr_Clear();
1413 else
1414 return NULL;
1415 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1416 }
1417 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001418 int status = Py_ReprEnter((PyObject *)self);
1419 res = NULL;
1420 if (status == 0) {
1421 res = PyUnicode_FromFormat("<%s name=%R>",
1422 Py_TYPE(self)->tp_name, nameobj);
1423 Py_ReprLeave((PyObject *)self);
1424 }
1425 else if (status > 0) {
1426 PyErr_Format(PyExc_RuntimeError,
1427 "reentrant call inside %s.__repr__",
1428 Py_TYPE(self)->tp_name);
1429 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001430 Py_DECREF(nameobj);
1431 }
1432 return res;
1433}
1434
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435/*
1436 * class BufferedReader
1437 */
1438
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001439static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001440{
1441 self->read_end = -1;
1442}
1443
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001444/*[clinic input]
1445_io.BufferedReader.__init__
1446 raw: object
1447 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001449Create a new buffered reader using the given readable raw IO object.
1450[clinic start generated code]*/
1451
1452static int
1453_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1454 Py_ssize_t buffer_size)
1455/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1456{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001457 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001458 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001459
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001460 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001461 return -1;
1462
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001464 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465 self->buffer_size = buffer_size;
1466 self->readable = 1;
1467 self->writable = 0;
1468
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001469 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001470 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001471 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001472
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001473 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1474 Py_TYPE(raw) == &PyFileIO_Type);
1475
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001476 self->ok = 1;
1477 return 0;
1478}
1479
1480static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001481_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001482{
1483 Py_buffer buf;
1484 PyObject *memobj, *res;
1485 Py_ssize_t n;
1486 /* NOTE: the buffer needn't be released as its object is NULL. */
1487 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1488 return -1;
1489 memobj = PyMemoryView_FromBuffer(&buf);
1490 if (memobj == NULL)
1491 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001492 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1493 occurs so we needn't do it ourselves.
1494 We then retry reading, ignoring the signal if no handler has
1495 raised (see issue #10956).
1496 */
1497 do {
1498 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001499 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001500 Py_DECREF(memobj);
1501 if (res == NULL)
1502 return -1;
1503 if (res == Py_None) {
1504 /* Non-blocking stream would have blocked. Special return code! */
1505 Py_DECREF(res);
1506 return -2;
1507 }
1508 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1509 Py_DECREF(res);
1510 if (n < 0 || n > len) {
1511 PyErr_Format(PyExc_IOError,
1512 "raw readinto() returned invalid length %zd "
1513 "(should have been between 0 and %zd)", n, len);
1514 return -1;
1515 }
1516 if (n > 0 && self->abs_pos != -1)
1517 self->abs_pos += n;
1518 return n;
1519}
1520
1521static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001522_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001523{
1524 Py_ssize_t start, len, n;
1525 if (VALID_READ_BUFFER(self))
1526 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1527 else
1528 start = 0;
1529 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001530 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001531 if (n <= 0)
1532 return n;
1533 self->read_end = start + n;
1534 self->raw_pos = start + n;
1535 return n;
1536}
1537
1538static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001539_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001540{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001541 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001542 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001543
1544 /* First copy what we have in the current buffer. */
1545 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1546 if (current_size) {
1547 data = PyBytes_FromStringAndSize(
1548 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001549 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001550 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001551 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001552 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001553 /* We're going past the buffer's bounds, flush it */
1554 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001555 tmp = buffered_flush_and_rewind_unlocked(self);
1556 if (tmp == NULL)
1557 goto cleanup;
1558 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001559 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001560 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001561
1562 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001563 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1564 if (tmp == NULL)
1565 goto cleanup;
1566 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001567 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001568 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001569 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001570 if (tmp == Py_None) {
1571 if (current_size == 0) {
1572 res = Py_None;
1573 goto cleanup;
1574 } else {
1575 res = data;
1576 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001577 }
1578 }
1579 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001580 PyBytes_Concat(&data, tmp);
1581 res = data;
1582 goto cleanup;
1583 }
1584 else {
1585 res = tmp;
1586 goto cleanup;
1587 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001588 }
1589
1590 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001591 if (chunks == NULL)
1592 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001593
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594 while (1) {
1595 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001596 if (PyList_Append(chunks, data) < 0)
1597 goto cleanup;
1598 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001599 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001600
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001601 /* Read until EOF or until read() would block. */
1602 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001603 if (data == NULL)
1604 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001605 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001606 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001607 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608 }
1609 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1610 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001611 res = data;
1612 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001613 }
1614 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001615 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1616 res = tmp;
1617 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001618 }
1619 }
1620 current_size += PyBytes_GET_SIZE(data);
1621 if (self->abs_pos != -1)
1622 self->abs_pos += PyBytes_GET_SIZE(data);
1623 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001624cleanup:
1625 /* res is either NULL or a borrowed ref */
1626 Py_XINCREF(res);
1627 Py_XDECREF(data);
1628 Py_XDECREF(tmp);
1629 Py_XDECREF(chunks);
1630 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001631}
1632
1633/* Read n bytes from the buffer if it can, otherwise return None.
1634 This function is simple enough that it can run unlocked. */
1635static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001636_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001637{
1638 Py_ssize_t current_size;
1639
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001640 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1641 if (n <= current_size) {
1642 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001643 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1644 if (res != NULL)
1645 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001646 return res;
1647 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001648 Py_RETURN_NONE;
1649}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001650
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001651/* Generic read function: read from the stream until enough bytes are read,
1652 * or until an EOF occurs or until read() would block.
1653 */
1654static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001655_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001656{
1657 PyObject *res = NULL;
1658 Py_ssize_t current_size, remaining, written;
1659 char *out;
1660
1661 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1662 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001663 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001664
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001665 res = PyBytes_FromStringAndSize(NULL, n);
1666 if (res == NULL)
1667 goto error;
1668 out = PyBytes_AS_STRING(res);
1669 remaining = n;
1670 written = 0;
1671 if (current_size > 0) {
1672 memcpy(out, self->buffer + self->pos, current_size);
1673 remaining -= current_size;
1674 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001675 self->pos += current_size;
1676 }
1677 /* Flush the write buffer if necessary */
1678 if (self->writable) {
1679 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1680 if (r == NULL)
1681 goto error;
1682 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001684 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685 while (remaining > 0) {
1686 /* We want to read a whole block at the end into buffer.
1687 If we had readv() we could do this in one pass. */
1688 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1689 if (r == 0)
1690 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001691 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001692 if (r == -1)
1693 goto error;
1694 if (r == 0 || r == -2) {
1695 /* EOF occurred or read() would block. */
1696 if (r == 0 || written > 0) {
1697 if (_PyBytes_Resize(&res, written))
1698 goto error;
1699 return res;
1700 }
1701 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001702 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001703 }
1704 remaining -= r;
1705 written += r;
1706 }
1707 assert(remaining <= self->buffer_size);
1708 self->pos = 0;
1709 self->raw_pos = 0;
1710 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001711 /* NOTE: when the read is satisfied, we avoid issuing any additional
1712 reads, which could block indefinitely (e.g. on a socket).
1713 See issue #9550. */
1714 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001715 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001716 if (r == -1)
1717 goto error;
1718 if (r == 0 || r == -2) {
1719 /* EOF occurred or read() would block. */
1720 if (r == 0 || written > 0) {
1721 if (_PyBytes_Resize(&res, written))
1722 goto error;
1723 return res;
1724 }
1725 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001726 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001727 }
1728 if (remaining > r) {
1729 memcpy(out + written, self->buffer + self->pos, r);
1730 written += r;
1731 self->pos += r;
1732 remaining -= r;
1733 }
1734 else if (remaining > 0) {
1735 memcpy(out + written, self->buffer + self->pos, remaining);
1736 written += remaining;
1737 self->pos += remaining;
1738 remaining = 0;
1739 }
1740 if (remaining == 0)
1741 break;
1742 }
1743
1744 return res;
1745
1746error:
1747 Py_XDECREF(res);
1748 return NULL;
1749}
1750
1751static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001752_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001753{
1754 Py_ssize_t have, r;
1755
1756 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1757 /* Constraints:
1758 1. we don't want to advance the file position.
1759 2. we don't want to lose block alignment, so we can't shift the buffer
1760 to make some place.
1761 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1762 */
1763 if (have > 0) {
1764 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1765 }
1766
1767 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001768 _bufferedreader_reset_buf(self);
1769 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770 if (r == -1)
1771 return NULL;
1772 if (r == -2)
1773 r = 0;
1774 self->pos = 0;
1775 return PyBytes_FromStringAndSize(self->buffer, r);
1776}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001777
1778
Benjamin Peterson59406a92009-03-26 17:10:29 +00001779
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780/*
1781 * class BufferedWriter
1782 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001784_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785{
1786 self->write_pos = 0;
1787 self->write_end = -1;
1788}
1789
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001790/*[clinic input]
1791_io.BufferedWriter.__init__
1792 raw: object
1793 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001794
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001795A buffer for a writeable sequential RawIO object.
1796
1797The constructor creates a BufferedWriter for the given writeable raw
1798stream. If the buffer_size is not given, it defaults to
1799DEFAULT_BUFFER_SIZE.
1800[clinic start generated code]*/
1801
1802static int
1803_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1804 Py_ssize_t buffer_size)
1805/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1806{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001807 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001808 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001810 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 return -1;
1812
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001814 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 self->readable = 0;
1816 self->writable = 1;
1817
1818 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001819 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001821 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822 self->pos = 0;
1823
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001824 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1825 Py_TYPE(raw) == &PyFileIO_Type);
1826
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827 self->ok = 1;
1828 return 0;
1829}
1830
1831static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001832_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001833{
1834 Py_buffer buf;
1835 PyObject *memobj, *res;
1836 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001837 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001838 /* NOTE: the buffer needn't be released as its object is NULL. */
1839 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1840 return -1;
1841 memobj = PyMemoryView_FromBuffer(&buf);
1842 if (memobj == NULL)
1843 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001844 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1845 occurs so we needn't do it ourselves.
1846 We then retry writing, ignoring the signal if no handler has
1847 raised (see issue #10956).
1848 */
1849 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001850 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001851 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001852 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001853 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001854 Py_DECREF(memobj);
1855 if (res == NULL)
1856 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001857 if (res == Py_None) {
1858 /* Non-blocking stream would have blocked. Special return code!
1859 Being paranoid we reset errno in case it is changed by code
1860 triggered by a decref. errno is used by _set_BlockingIOError(). */
1861 Py_DECREF(res);
1862 errno = errnum;
1863 return -2;
1864 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001865 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1866 Py_DECREF(res);
1867 if (n < 0 || n > len) {
1868 PyErr_Format(PyExc_IOError,
1869 "raw write() returned invalid length %zd "
1870 "(should have been between 0 and %zd)", n, len);
1871 return -1;
1872 }
1873 if (n > 0 && self->abs_pos != -1)
1874 self->abs_pos += n;
1875 return n;
1876}
1877
1878/* `restore_pos` is 1 if we need to restore the raw stream position at
1879 the end, 0 otherwise. */
1880static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001882{
1883 Py_ssize_t written = 0;
1884 Py_off_t n, rewind;
1885
1886 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1887 goto end;
1888 /* First, rewind */
1889 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1890 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001891 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001892 if (n < 0) {
1893 goto error;
1894 }
1895 self->raw_pos -= rewind;
1896 }
1897 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001898 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001899 self->buffer + self->write_pos,
1900 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1901 Py_off_t, Py_ssize_t));
1902 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001903 goto error;
1904 }
1905 else if (n == -2) {
1906 _set_BlockingIOError("write could not complete without blocking",
1907 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001908 goto error;
1909 }
1910 self->write_pos += n;
1911 self->raw_pos = self->write_pos;
1912 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001913 /* Partial writes can return successfully when interrupted by a
1914 signal (see write(2)). We must run signal handlers before
1915 blocking another time, possibly indefinitely. */
1916 if (PyErr_CheckSignals() < 0)
1917 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918 }
1919
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001920 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921
1922end:
1923 Py_RETURN_NONE;
1924
1925error:
1926 return NULL;
1927}
1928
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001929/*[clinic input]
1930_io.BufferedWriter.write
1931 buffer: Py_buffer
1932 /
1933[clinic start generated code]*/
1934
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001935static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001936_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1937/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938{
1939 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001940 Py_ssize_t written, avail, remaining;
1941 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942
1943 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001944 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001946 return NULL;
1947 }
1948
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001949 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001950 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951
1952 /* Fast path: the data to write can be fully buffered. */
1953 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1954 self->pos = 0;
1955 self->raw_pos = 0;
1956 }
1957 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001958 if (buffer->len <= avail) {
1959 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001960 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001961 self->write_pos = self->pos;
1962 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001963 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 if (self->pos > self->write_end)
1965 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001966 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 goto end;
1968 }
1969
1970 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001971 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001973 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001974 if (w == NULL)
1975 goto error;
1976 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001977 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978 /* Make some place by shifting the buffer. */
1979 assert(VALID_WRITE_BUFFER(self));
1980 memmove(self->buffer, self->buffer + self->write_pos,
1981 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1982 Py_off_t, Py_ssize_t));
1983 self->write_end -= self->write_pos;
1984 self->raw_pos -= self->write_pos;
1985 self->pos -= self->write_pos;
1986 self->write_pos = 0;
1987 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1988 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001989 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001990 /* Everything can be buffered */
1991 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001992 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1993 self->write_end += buffer->len;
1994 self->pos += buffer->len;
1995 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996 goto end;
1997 }
1998 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001999 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002001 self->pos += avail;
2002 /* XXX Modifying the existing exception e using the pointer w
2003 will change e.characters_written but not e.args[2].
2004 Therefore we just replace with a new error. */
2005 _set_BlockingIOError("write could not complete without blocking",
2006 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 goto error;
2008 }
2009 Py_CLEAR(res);
2010
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002011 /* Adjust the raw stream position if it is away from the logical stream
2012 position. This happens if the read buffer has been filled but not
2013 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2014 the raw stream by itself).
2015 Fixes issue #6629.
2016 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002017 offset = RAW_OFFSET(self);
2018 if (offset != 0) {
2019 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002020 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002021 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002022 }
2023
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002025 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 written = 0;
2027 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002028 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002029 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002031 goto error;
2032 } else if (n == -2) {
2033 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002034 if (remaining > self->buffer_size) {
2035 /* Can't buffer everything, still buffer as much as possible */
2036 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002037 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002038 self->raw_pos = 0;
2039 ADJUST_POSITION(self, self->buffer_size);
2040 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002041 written += self->buffer_size;
2042 _set_BlockingIOError("write could not complete without "
2043 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002044 goto error;
2045 }
2046 PyErr_Clear();
2047 break;
2048 }
2049 written += n;
2050 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002051 /* Partial writes can return successfully when interrupted by a
2052 signal (see write(2)). We must run signal handlers before
2053 blocking another time, possibly indefinitely. */
2054 if (PyErr_CheckSignals() < 0)
2055 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 }
2057 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002058 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002060 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002061 written += remaining;
2062 }
2063 self->write_pos = 0;
2064 /* TODO: sanity check (remaining >= 0) */
2065 self->write_end = remaining;
2066 ADJUST_POSITION(self, remaining);
2067 self->raw_pos = 0;
2068
2069end:
2070 res = PyLong_FromSsize_t(written);
2071
2072error:
2073 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074 return res;
2075}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002076
2077
2078
2079/*
2080 * BufferedRWPair
2081 */
2082
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002083/* XXX The usefulness of this (compared to having two separate IO objects) is
2084 * questionable.
2085 */
2086
2087typedef struct {
2088 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002089 buffered *reader;
2090 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002091 PyObject *dict;
2092 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002093} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002094
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002095/*[clinic input]
2096_io.BufferedRWPair.__init__
2097 reader: object
2098 writer: object
2099 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2100 /
2101
2102A buffered reader and writer object together.
2103
2104A buffered reader object and buffered writer object put together to
2105form a sequential IO object that can read and write. This is typically
2106used with a socket or two-way pipe.
2107
2108reader and writer are RawIOBase objects that are readable and
2109writeable respectively. If the buffer_size is omitted it defaults to
2110DEFAULT_BUFFER_SIZE.
2111[clinic start generated code]*/
2112
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002114_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2115 PyObject *writer, Py_ssize_t buffer_size)
2116/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002117{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002118 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002119 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002120 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121 return -1;
2122
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002124 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002125 if (self->reader == NULL)
2126 return -1;
2127
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002128 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002129 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130 if (self->writer == NULL) {
2131 Py_CLEAR(self->reader);
2132 return -1;
2133 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002134
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002135 return 0;
2136}
2137
2138static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002139bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002140{
2141 Py_VISIT(self->dict);
2142 return 0;
2143}
2144
2145static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002146bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147{
2148 Py_CLEAR(self->reader);
2149 Py_CLEAR(self->writer);
2150 Py_CLEAR(self->dict);
2151 return 0;
2152}
2153
2154static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002155bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002156{
2157 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002158 if (self->weakreflist != NULL)
2159 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160 Py_CLEAR(self->reader);
2161 Py_CLEAR(self->writer);
2162 Py_CLEAR(self->dict);
2163 Py_TYPE(self)->tp_free((PyObject *) self);
2164}
2165
2166static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002167_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002169 PyObject *func, *ret;
2170 if (self == NULL) {
2171 PyErr_SetString(PyExc_ValueError,
2172 "I/O operation on uninitialized object");
2173 return NULL;
2174 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002175
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002176 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002178 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179 return NULL;
2180 }
2181
2182 ret = PyObject_CallObject(func, args);
2183 Py_DECREF(func);
2184 return ret;
2185}
2186
2187static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002188bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002190 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191}
2192
2193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002194bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002195{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002196 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002197}
2198
2199static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002200bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002201{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002202 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002203}
2204
2205static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002206bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002207{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002208 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002209}
2210
2211static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002212bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2213{
2214 return _forward_call(self->reader, &PyId_readinto1, args);
2215}
2216
2217static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002218bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002220 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221}
2222
2223static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002226 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227}
2228
2229static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002230bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002231{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002232 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233}
2234
2235static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002236bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002238 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239}
2240
2241static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002242bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002243{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002244 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002245 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002247 PyErr_Fetch(&exc, &val, &tb);
2248 else
2249 Py_DECREF(ret);
2250 ret = _forward_call(self->reader, &PyId_close, args);
2251 if (exc != NULL) {
2252 _PyErr_ChainExceptions(exc, val, tb);
2253 Py_CLEAR(ret);
2254 }
2255 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002256}
2257
2258static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002259bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002261 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002262
2263 if (ret != Py_False) {
2264 /* either True or exception */
2265 return ret;
2266 }
2267 Py_DECREF(ret);
2268
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002269 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002270}
2271
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002272static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002273bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002274{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002275 if (self->writer == NULL) {
2276 PyErr_SetString(PyExc_RuntimeError,
2277 "the BufferedRWPair object is being garbage-collected");
2278 return NULL;
2279 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002280 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2281}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002282
2283
2284
2285/*
2286 * BufferedRandom
2287 */
2288
2289/*[clinic input]
2290_io.BufferedRandom.__init__
2291 raw: object
2292 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2293
2294A buffered interface to random access streams.
2295
2296The constructor creates a reader and writer for a seekable stream,
2297raw, given in the first argument. If the buffer_size is omitted it
2298defaults to DEFAULT_BUFFER_SIZE.
2299[clinic start generated code]*/
2300
2301static int
2302_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2303 Py_ssize_t buffer_size)
2304/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2305{
2306 self->ok = 0;
2307 self->detached = 0;
2308
2309 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2310 return -1;
2311 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2312 return -1;
2313 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2314 return -1;
2315
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002316 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002317 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002318 self->buffer_size = buffer_size;
2319 self->readable = 1;
2320 self->writable = 1;
2321
2322 if (_buffered_init(self) < 0)
2323 return -1;
2324 _bufferedreader_reset_buf(self);
2325 _bufferedwriter_reset_buf(self);
2326 self->pos = 0;
2327
2328 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2329 Py_TYPE(raw) == &PyFileIO_Type);
2330
2331 self->ok = 1;
2332 return 0;
2333}
2334
2335#include "clinic/bufferedio.c.h"
2336
2337
2338static PyMethodDef bufferediobase_methods[] = {
2339 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2340 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2341 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2342 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2343 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2344 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2345 {NULL, NULL}
2346};
2347
2348PyTypeObject PyBufferedIOBase_Type = {
2349 PyVarObject_HEAD_INIT(NULL, 0)
2350 "_io._BufferedIOBase", /*tp_name*/
2351 0, /*tp_basicsize*/
2352 0, /*tp_itemsize*/
2353 0, /*tp_dealloc*/
2354 0, /*tp_print*/
2355 0, /*tp_getattr*/
2356 0, /*tp_setattr*/
2357 0, /*tp_compare */
2358 0, /*tp_repr*/
2359 0, /*tp_as_number*/
2360 0, /*tp_as_sequence*/
2361 0, /*tp_as_mapping*/
2362 0, /*tp_hash */
2363 0, /*tp_call*/
2364 0, /*tp_str*/
2365 0, /*tp_getattro*/
2366 0, /*tp_setattro*/
2367 0, /*tp_as_buffer*/
2368 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2369 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2370 bufferediobase_doc, /* tp_doc */
2371 0, /* tp_traverse */
2372 0, /* tp_clear */
2373 0, /* tp_richcompare */
2374 0, /* tp_weaklistoffset */
2375 0, /* tp_iter */
2376 0, /* tp_iternext */
2377 bufferediobase_methods, /* tp_methods */
2378 0, /* tp_members */
2379 0, /* tp_getset */
2380 &PyIOBase_Type, /* tp_base */
2381 0, /* tp_dict */
2382 0, /* tp_descr_get */
2383 0, /* tp_descr_set */
2384 0, /* tp_dictoffset */
2385 0, /* tp_init */
2386 0, /* tp_alloc */
2387 0, /* tp_new */
2388 0, /* tp_free */
2389 0, /* tp_is_gc */
2390 0, /* tp_bases */
2391 0, /* tp_mro */
2392 0, /* tp_cache */
2393 0, /* tp_subclasses */
2394 0, /* tp_weaklist */
2395 0, /* tp_del */
2396 0, /* tp_version_tag */
2397 0, /* tp_finalize */
2398};
2399
2400
2401static PyMethodDef bufferedreader_methods[] = {
2402 /* BufferedIOMixin methods */
2403 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2404 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2405 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2406 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2407 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002408 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2409 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2410 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2411 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2412
2413 _IO__BUFFERED_READ_METHODDEF
2414 _IO__BUFFERED_PEEK_METHODDEF
2415 _IO__BUFFERED_READ1_METHODDEF
2416 _IO__BUFFERED_READINTO_METHODDEF
2417 _IO__BUFFERED_READINTO1_METHODDEF
2418 _IO__BUFFERED_READLINE_METHODDEF
2419 _IO__BUFFERED_SEEK_METHODDEF
2420 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2421 _IO__BUFFERED_TRUNCATE_METHODDEF
2422 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2423 {NULL, NULL}
2424};
2425
2426static PyMemberDef bufferedreader_members[] = {
2427 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2428 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2429 {NULL}
2430};
2431
2432static PyGetSetDef bufferedreader_getset[] = {
2433 {"closed", (getter)buffered_closed_get, NULL, NULL},
2434 {"name", (getter)buffered_name_get, NULL, NULL},
2435 {"mode", (getter)buffered_mode_get, NULL, NULL},
2436 {NULL}
2437};
2438
2439
2440PyTypeObject PyBufferedReader_Type = {
2441 PyVarObject_HEAD_INIT(NULL, 0)
2442 "_io.BufferedReader", /*tp_name*/
2443 sizeof(buffered), /*tp_basicsize*/
2444 0, /*tp_itemsize*/
2445 (destructor)buffered_dealloc, /*tp_dealloc*/
2446 0, /*tp_print*/
2447 0, /*tp_getattr*/
2448 0, /*tp_setattr*/
2449 0, /*tp_compare */
2450 (reprfunc)buffered_repr, /*tp_repr*/
2451 0, /*tp_as_number*/
2452 0, /*tp_as_sequence*/
2453 0, /*tp_as_mapping*/
2454 0, /*tp_hash */
2455 0, /*tp_call*/
2456 0, /*tp_str*/
2457 0, /*tp_getattro*/
2458 0, /*tp_setattro*/
2459 0, /*tp_as_buffer*/
2460 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2461 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2462 _io_BufferedReader___init____doc__, /* tp_doc */
2463 (traverseproc)buffered_traverse, /* tp_traverse */
2464 (inquiry)buffered_clear, /* tp_clear */
2465 0, /* tp_richcompare */
2466 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2467 0, /* tp_iter */
2468 (iternextfunc)buffered_iternext, /* tp_iternext */
2469 bufferedreader_methods, /* tp_methods */
2470 bufferedreader_members, /* tp_members */
2471 bufferedreader_getset, /* tp_getset */
2472 0, /* tp_base */
2473 0, /* tp_dict */
2474 0, /* tp_descr_get */
2475 0, /* tp_descr_set */
2476 offsetof(buffered, dict), /* tp_dictoffset */
2477 _io_BufferedReader___init__, /* tp_init */
2478 0, /* tp_alloc */
2479 PyType_GenericNew, /* tp_new */
2480 0, /* tp_free */
2481 0, /* tp_is_gc */
2482 0, /* tp_bases */
2483 0, /* tp_mro */
2484 0, /* tp_cache */
2485 0, /* tp_subclasses */
2486 0, /* tp_weaklist */
2487 0, /* tp_del */
2488 0, /* tp_version_tag */
2489 0, /* tp_finalize */
2490};
2491
2492
2493static PyMethodDef bufferedwriter_methods[] = {
2494 /* BufferedIOMixin methods */
2495 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2496 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2497 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002498 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2499 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2500 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2501 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2502 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2503
2504 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2505 _IO__BUFFERED_TRUNCATE_METHODDEF
2506 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2507 _IO__BUFFERED_SEEK_METHODDEF
2508 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2509 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2510 {NULL, NULL}
2511};
2512
2513static PyMemberDef bufferedwriter_members[] = {
2514 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2515 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2516 {NULL}
2517};
2518
2519static PyGetSetDef bufferedwriter_getset[] = {
2520 {"closed", (getter)buffered_closed_get, NULL, NULL},
2521 {"name", (getter)buffered_name_get, NULL, NULL},
2522 {"mode", (getter)buffered_mode_get, NULL, NULL},
2523 {NULL}
2524};
2525
2526
2527PyTypeObject PyBufferedWriter_Type = {
2528 PyVarObject_HEAD_INIT(NULL, 0)
2529 "_io.BufferedWriter", /*tp_name*/
2530 sizeof(buffered), /*tp_basicsize*/
2531 0, /*tp_itemsize*/
2532 (destructor)buffered_dealloc, /*tp_dealloc*/
2533 0, /*tp_print*/
2534 0, /*tp_getattr*/
2535 0, /*tp_setattr*/
2536 0, /*tp_compare */
2537 (reprfunc)buffered_repr, /*tp_repr*/
2538 0, /*tp_as_number*/
2539 0, /*tp_as_sequence*/
2540 0, /*tp_as_mapping*/
2541 0, /*tp_hash */
2542 0, /*tp_call*/
2543 0, /*tp_str*/
2544 0, /*tp_getattro*/
2545 0, /*tp_setattro*/
2546 0, /*tp_as_buffer*/
2547 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2548 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2549 _io_BufferedWriter___init____doc__, /* tp_doc */
2550 (traverseproc)buffered_traverse, /* tp_traverse */
2551 (inquiry)buffered_clear, /* tp_clear */
2552 0, /* tp_richcompare */
2553 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2554 0, /* tp_iter */
2555 0, /* tp_iternext */
2556 bufferedwriter_methods, /* tp_methods */
2557 bufferedwriter_members, /* tp_members */
2558 bufferedwriter_getset, /* tp_getset */
2559 0, /* tp_base */
2560 0, /* tp_dict */
2561 0, /* tp_descr_get */
2562 0, /* tp_descr_set */
2563 offsetof(buffered, dict), /* tp_dictoffset */
2564 _io_BufferedWriter___init__, /* tp_init */
2565 0, /* tp_alloc */
2566 PyType_GenericNew, /* tp_new */
2567 0, /* tp_free */
2568 0, /* tp_is_gc */
2569 0, /* tp_bases */
2570 0, /* tp_mro */
2571 0, /* tp_cache */
2572 0, /* tp_subclasses */
2573 0, /* tp_weaklist */
2574 0, /* tp_del */
2575 0, /* tp_version_tag */
2576 0, /* tp_finalize */
2577};
2578
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002580static PyMethodDef bufferedrwpair_methods[] = {
2581 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2582 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2583 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2584 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002585 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002587 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2588 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002590 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2591 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002592
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002593 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2594 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002595
Antoine Pitrou243757e2010-11-05 21:15:39 +00002596 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2597
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002598 {NULL, NULL}
2599};
2600
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601static PyGetSetDef bufferedrwpair_getset[] = {
2602 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002603 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002604};
2605
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002606PyTypeObject PyBufferedRWPair_Type = {
2607 PyVarObject_HEAD_INIT(NULL, 0)
2608 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002609 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002610 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002611 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002612 0, /*tp_print*/
2613 0, /*tp_getattr*/
2614 0, /*tp_setattr*/
2615 0, /*tp_compare */
2616 0, /*tp_repr*/
2617 0, /*tp_as_number*/
2618 0, /*tp_as_sequence*/
2619 0, /*tp_as_mapping*/
2620 0, /*tp_hash */
2621 0, /*tp_call*/
2622 0, /*tp_str*/
2623 0, /*tp_getattro*/
2624 0, /*tp_setattro*/
2625 0, /*tp_as_buffer*/
2626 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002627 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002628 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002629 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2630 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002631 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002632 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002633 0, /* tp_iter */
2634 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002635 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002637 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002638 0, /* tp_base */
2639 0, /* tp_dict */
2640 0, /* tp_descr_get */
2641 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002642 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002643 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002644 0, /* tp_alloc */
2645 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002646 0, /* tp_free */
2647 0, /* tp_is_gc */
2648 0, /* tp_bases */
2649 0, /* tp_mro */
2650 0, /* tp_cache */
2651 0, /* tp_subclasses */
2652 0, /* tp_weaklist */
2653 0, /* tp_del */
2654 0, /* tp_version_tag */
2655 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002656};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002657
2658
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002659static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002660 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002661 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2662 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2663 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2664 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2665 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2666 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2667 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002668 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002669 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002670
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002671 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002672
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002673 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002674 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002675 _IO__BUFFERED_TRUNCATE_METHODDEF
2676 _IO__BUFFERED_READ_METHODDEF
2677 _IO__BUFFERED_READ1_METHODDEF
2678 _IO__BUFFERED_READINTO_METHODDEF
2679 _IO__BUFFERED_READINTO1_METHODDEF
2680 _IO__BUFFERED_READLINE_METHODDEF
2681 _IO__BUFFERED_PEEK_METHODDEF
2682 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002683 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002684 {NULL, NULL}
2685};
2686
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002687static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002688 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002689 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690 {NULL}
2691};
2692
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002693static PyGetSetDef bufferedrandom_getset[] = {
2694 {"closed", (getter)buffered_closed_get, NULL, NULL},
2695 {"name", (getter)buffered_name_get, NULL, NULL},
2696 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002697 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002698};
2699
2700
2701PyTypeObject PyBufferedRandom_Type = {
2702 PyVarObject_HEAD_INIT(NULL, 0)
2703 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002704 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002705 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002706 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002707 0, /*tp_print*/
2708 0, /*tp_getattr*/
2709 0, /*tp_setattr*/
2710 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002711 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002712 0, /*tp_as_number*/
2713 0, /*tp_as_sequence*/
2714 0, /*tp_as_mapping*/
2715 0, /*tp_hash */
2716 0, /*tp_call*/
2717 0, /*tp_str*/
2718 0, /*tp_getattro*/
2719 0, /*tp_setattro*/
2720 0, /*tp_as_buffer*/
2721 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002722 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002723 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002724 (traverseproc)buffered_traverse, /* tp_traverse */
2725 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002726 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002727 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002728 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002729 (iternextfunc)buffered_iternext, /* tp_iternext */
2730 bufferedrandom_methods, /* tp_methods */
2731 bufferedrandom_members, /* tp_members */
2732 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002733 0, /* tp_base */
2734 0, /*tp_dict*/
2735 0, /* tp_descr_get */
2736 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002737 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002738 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002739 0, /* tp_alloc */
2740 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002741 0, /* tp_free */
2742 0, /* tp_is_gc */
2743 0, /* tp_bases */
2744 0, /* tp_mro */
2745 0, /* tp_cache */
2746 0, /* tp_subclasses */
2747 0, /* tp_weaklist */
2748 0, /* tp_del */
2749 0, /* tp_version_tag */
2750 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002751};