blob: efc7d05b7d01b9ad192cb2c5f73a9f3ffece46da [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);
308 char *msg = PyUnicode_AsUTF8(msgobj);
309 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;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200457 r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
Antoine Pitroue033e062010-10-29 10:38:18 +0000458 if (r)
459 Py_DECREF(r);
460 else
461 PyErr_Clear();
462 }
463 Py_RETURN_NONE;
464}
465
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466/*
467 * _BufferedIOMixin methods
468 * This is not a class, just a collection of methods that will be reused
469 * by BufferedReader and BufferedWriter
470 */
471
472/* Flush and close */
473
474static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000475buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000476{
477 CHECK_INITIALIZED(self)
478 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
479}
480
481static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000482buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000483{
484 int closed;
485 PyObject *res;
486 CHECK_INITIALIZED_INT(self)
487 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
488 if (res == NULL)
489 return -1;
490 closed = PyObject_IsTrue(res);
491 Py_DECREF(res);
492 return closed;
493}
494
495static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000496buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000497{
498 CHECK_INITIALIZED(self)
499 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
500}
501
502static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000503buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000504{
Benjamin Peterson68623612012-12-20 11:53:11 -0600505 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506 int r;
507
508 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000509 if (!ENTER_BUFFERED(self))
510 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000512 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513 if (r < 0)
514 goto end;
515 if (r > 0) {
516 res = Py_None;
517 Py_INCREF(res);
518 goto end;
519 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000520
Antoine Pitrou796564c2013-07-30 19:59:21 +0200521 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000522 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
523 if (r)
524 Py_DECREF(r);
525 else
526 PyErr_Clear();
527 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000528 /* flush() will most probably re-take the lock, so drop it first */
529 LEAVE_BUFFERED(self)
530 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000531 if (!ENTER_BUFFERED(self))
532 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600533 if (res == NULL)
534 PyErr_Fetch(&exc, &val, &tb);
535 else
536 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000537
538 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
539
Jesus Ceadc469452012-10-04 12:37:56 +0200540 if (self->buffer) {
541 PyMem_Free(self->buffer);
542 self->buffer = NULL;
543 }
544
Benjamin Peterson68623612012-12-20 11:53:11 -0600545 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300546 _PyErr_ChainExceptions(exc, val, tb);
547 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600548 }
549
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000550end:
551 LEAVE_BUFFERED(self)
552 return res;
553}
554
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000555/* detach */
556
557static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000558buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000559{
560 PyObject *raw, *res;
561 CHECK_INITIALIZED(self)
562 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
563 if (res == NULL)
564 return NULL;
565 Py_DECREF(res);
566 raw = self->raw;
567 self->raw = NULL;
568 self->detached = 1;
569 self->ok = 0;
570 return raw;
571}
572
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573/* Inquiries */
574
575static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000576buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000577{
578 CHECK_INITIALIZED(self)
579 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
580}
581
582static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000583buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584{
585 CHECK_INITIALIZED(self)
586 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
587}
588
589static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000590buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591{
592 CHECK_INITIALIZED(self)
593 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
594}
595
596static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000597buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598{
599 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200600 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601}
602
603static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000604buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000605{
606 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200607 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608}
609
610/* Lower-level APIs */
611
612static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614{
615 CHECK_INITIALIZED(self)
616 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
617}
618
619static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000621{
622 CHECK_INITIALIZED(self)
623 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
624}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000625
Antoine Pitrou243757e2010-11-05 21:15:39 +0000626/* Serialization */
627
628static PyObject *
629buffered_getstate(buffered *self, PyObject *args)
630{
631 PyErr_Format(PyExc_TypeError,
632 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
633 return NULL;
634}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000635
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000636/* Forward decls */
637static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100638_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000639static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000642_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000644_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000645static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200646_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000648_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000649static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000650_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000651static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000652_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200653static Py_ssize_t
654_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655
656/*
657 * Helpers
658 */
659
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100660/* Sets the current error to BlockingIOError */
661static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200662_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100663{
664 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200665 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100666 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
667 errno, msg, written);
668 if (err)
669 PyErr_SetObject(PyExc_BlockingIOError, err);
670 Py_XDECREF(err);
671}
672
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673/* Returns the address of the `written` member if a BlockingIOError was
674 raised, NULL otherwise. The error is always re-raised. */
675static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000676_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677{
678 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200679 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680
681 PyErr_Fetch(&t, &v, &tb);
682 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
683 PyErr_Restore(t, v, tb);
684 return NULL;
685 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200686 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000687 /* TODO: sanity check (err->written >= 0) */
688 PyErr_Restore(t, v, tb);
689 return &err->written;
690}
691
692static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000693_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000694{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000696 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000697 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
698 if (res == NULL)
699 return -1;
700 n = PyNumber_AsOff_t(res, PyExc_ValueError);
701 Py_DECREF(res);
702 if (n < 0) {
703 if (!PyErr_Occurred())
704 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000705 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200706 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707 return -1;
708 }
709 self->abs_pos = n;
710 return n;
711}
712
713static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000714_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715{
716 PyObject *res, *posobj, *whenceobj;
717 Py_off_t n;
718
719 posobj = PyLong_FromOff_t(target);
720 if (posobj == NULL)
721 return -1;
722 whenceobj = PyLong_FromLong(whence);
723 if (whenceobj == NULL) {
724 Py_DECREF(posobj);
725 return -1;
726 }
727 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
728 posobj, whenceobj, NULL);
729 Py_DECREF(posobj);
730 Py_DECREF(whenceobj);
731 if (res == NULL)
732 return -1;
733 n = PyNumber_AsOff_t(res, PyExc_ValueError);
734 Py_DECREF(res);
735 if (n < 0) {
736 if (!PyErr_Occurred())
737 PyErr_Format(PyExc_IOError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000738 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200739 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740 return -1;
741 }
742 self->abs_pos = n;
743 return n;
744}
745
746static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000747_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000748{
749 Py_ssize_t n;
750 if (self->buffer_size <= 0) {
751 PyErr_SetString(PyExc_ValueError,
752 "buffer size must be strictly positive");
753 return -1;
754 }
755 if (self->buffer)
756 PyMem_Free(self->buffer);
757 self->buffer = PyMem_Malloc(self->buffer_size);
758 if (self->buffer == NULL) {
759 PyErr_NoMemory();
760 return -1;
761 }
Georg Brandldfd73442009-04-05 11:47:34 +0000762#ifdef WITH_THREAD
Antoine Pitrouc881f152010-08-01 16:53:42 +0000763 if (self->lock)
764 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000765 self->lock = PyThread_allocate_lock();
766 if (self->lock == NULL) {
767 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
768 return -1;
769 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000770 self->owner = 0;
Georg Brandldfd73442009-04-05 11:47:34 +0000771#endif
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000772 /* Find out whether buffer_size is a power of 2 */
773 /* XXX is this optimization useful? */
774 for (n = self->buffer_size - 1; n & 1; n >>= 1)
775 ;
776 if (n == 0)
777 self->buffer_mask = self->buffer_size - 1;
778 else
779 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000780 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000781 PyErr_Clear();
782 return 0;
783}
784
Antoine Pitrou707ce822011-02-25 21:24:11 +0000785/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
786 clears the error indicator), 0 otherwise.
787 Should only be called when PyErr_Occurred() is true.
788*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700789int
790_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000791{
792 static PyObject *eintr_int = NULL;
793 PyObject *typ, *val, *tb;
794 PyEnvironmentErrorObject *env_err;
795
796 if (eintr_int == NULL) {
797 eintr_int = PyLong_FromLong(EINTR);
798 assert(eintr_int != NULL);
799 }
800 if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
801 return 0;
802 PyErr_Fetch(&typ, &val, &tb);
803 PyErr_NormalizeException(&typ, &val, &tb);
804 env_err = (PyEnvironmentErrorObject *) val;
805 assert(env_err != NULL);
806 if (env_err->myerrno != NULL &&
807 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
808 Py_DECREF(typ);
809 Py_DECREF(val);
810 Py_XDECREF(tb);
811 return 1;
812 }
813 /* This silences any error set by PyObject_RichCompareBool() */
814 PyErr_Restore(typ, val, tb);
815 return 0;
816}
817
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000818/*
819 * Shared methods and wrappers
820 */
821
822static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200823buffered_flush_and_rewind_unlocked(buffered *self)
824{
825 PyObject *res;
826
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100827 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200828 if (res == NULL)
829 return NULL;
830 Py_DECREF(res);
831
832 if (self->readable) {
833 /* Rewind the raw stream so that its position corresponds to
834 the current logical position. */
835 Py_off_t n;
836 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
837 _bufferedreader_reset_buf(self);
838 if (n == -1)
839 return NULL;
840 }
841 Py_RETURN_NONE;
842}
843
844static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000845buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000846{
847 PyObject *res;
848
849 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000850 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000851
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000852 if (!ENTER_BUFFERED(self))
853 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200854 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855 LEAVE_BUFFERED(self)
856
857 return res;
858}
859
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300860/*[clinic input]
861_io._Buffered.peek
862 size: Py_ssize_t = 0
863 /
864
865[clinic start generated code]*/
866
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000867static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300868_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
869/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000870{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871 PyObject *res = NULL;
872
873 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300874 CHECK_CLOSED(self, "peek of closed file")
875
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000876 if (!ENTER_BUFFERED(self))
877 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000878
879 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200880 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881 if (res == NULL)
882 goto end;
883 Py_CLEAR(res);
884 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200885 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000886
887end:
888 LEAVE_BUFFERED(self)
889 return res;
890}
891
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300892/*[clinic input]
893_io._Buffered.read
894 size as n: io_ssize_t = -1
895 /
896[clinic start generated code]*/
897
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000898static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300899_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
900/*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902 PyObject *res;
903
904 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000905 if (n < -1) {
906 PyErr_SetString(PyExc_ValueError,
907 "read length must be positive or -1");
908 return NULL;
909 }
910
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000911 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000913 if (n == -1) {
914 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000915 if (!ENTER_BUFFERED(self))
916 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000917 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000918 }
919 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000920 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200921 if (res != Py_None)
922 return res;
923 Py_DECREF(res);
924 if (!ENTER_BUFFERED(self))
925 return NULL;
926 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000927 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000928
Antoine Pitroue05565e2011-08-20 14:39:23 +0200929 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930 return res;
931}
932
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300933/*[clinic input]
934_io._Buffered.read1
935 size as n: Py_ssize_t
936 /
937[clinic start generated code]*/
938
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300940_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
941/*[clinic end generated code: output=bcc4fb4e54d103a3 input=8d2869c18b983184]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300943 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000944 PyObject *res = NULL;
945
946 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947 if (n < 0) {
948 PyErr_SetString(PyExc_ValueError,
949 "read length must be positive");
950 return NULL;
951 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300952
953 CHECK_CLOSED(self, "read of closed file")
954
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000955 if (n == 0)
956 return PyBytes_FromStringAndSize(NULL, 0);
957
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 /* Return up to n bytes. If at least one byte is buffered, we
959 only return buffered bytes. Otherwise, we do one raw read. */
960
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
962 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100963 n = Py_MIN(have, n);
964 res = _bufferedreader_read_fast(self, n);
965 assert(res != Py_None);
966 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100968 res = PyBytes_FromStringAndSize(NULL, n);
969 if (res == NULL)
970 return NULL;
971 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200972 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100973 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200974 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000975 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100976 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
977 LEAVE_BUFFERED(self)
978 if (r == -1) {
979 Py_DECREF(res);
980 return NULL;
981 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982 if (r == -2)
983 r = 0;
984 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100985 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986 return res;
987}
988
989static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300990_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000991{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200992 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993 PyObject *res = NULL;
994
995 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200996
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
998 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300999 if (n >= buffer->len) {
1000 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1001 self->pos += buffer->len;
1002 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001003 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001004 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001005 self->pos += n;
1006 written = n;
1007 }
1008
1009 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001010 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001011
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001013 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014 if (res == NULL)
1015 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001017 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001018
1019 _bufferedreader_reset_buf(self);
1020 self->pos = 0;
1021
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001022 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001023 remaining > 0;
1024 written += n, remaining -= n) {
1025 /* If remaining bytes is larger than internal buffer size, copy
1026 * directly into caller's buffer. */
1027 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001028 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001029 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001030 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001031
1032 /* In readinto1 mode, we do not want to fill the internal
1033 buffer if we already have some data to return */
1034 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001035 n = _bufferedreader_fill_buffer(self);
1036 if (n > 0) {
1037 if (n > remaining)
1038 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001039 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001040 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001041 self->pos += n;
1042 continue; /* short circuit */
1043 }
1044 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001045 else
1046 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001047
Antoine Pitrou3486a982011-05-12 01:57:53 +02001048 if (n == 0 || (n == -2 && written > 0))
1049 break;
1050 if (n < 0) {
1051 if (n == -2) {
1052 Py_INCREF(Py_None);
1053 res = Py_None;
1054 }
1055 goto end;
1056 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001057
Benjamin Petersona96fea02014-06-22 14:17:44 -07001058 /* At most one read in readinto1 mode */
1059 if (readinto1) {
1060 written += n;
1061 break;
1062 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001063 }
1064 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065
1066end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001067 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001068 return res;
1069}
1070
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001071/*[clinic input]
1072_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001073 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001074 /
1075[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001076
1077static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001078_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001079/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001080{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001081 return _buffered_readinto_generic(self, buffer, 0);
1082}
1083
1084/*[clinic input]
1085_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001086 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001087 /
1088[clinic start generated code]*/
1089
1090static PyObject *
1091_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001092/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001093{
1094 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001095}
1096
1097
1098static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001099_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100{
1101 PyObject *res = NULL;
1102 PyObject *chunks = NULL;
1103 Py_ssize_t n, written = 0;
1104 const char *start, *s, *end;
1105
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001106 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001107
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001108 /* First, try to find a line in the buffer. This can run unlocked because
1109 the calls to the C API are simple enough that they can't trigger
1110 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001111 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1112 if (limit >= 0 && n > limit)
1113 n = limit;
1114 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001115 s = memchr(start, '\n', n);
1116 if (s != NULL) {
1117 res = PyBytes_FromStringAndSize(start, s - start + 1);
1118 if (res != NULL)
1119 self->pos += s - start + 1;
1120 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001121 }
1122 if (n == limit) {
1123 res = PyBytes_FromStringAndSize(start, n);
1124 if (res != NULL)
1125 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001126 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001127 }
1128
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001129 if (!ENTER_BUFFERED(self))
1130 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001131
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001132 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001133 chunks = PyList_New(0);
1134 if (chunks == NULL)
1135 goto end;
1136 if (n > 0) {
1137 res = PyBytes_FromStringAndSize(start, n);
1138 if (res == NULL)
1139 goto end;
1140 if (PyList_Append(chunks, res) < 0) {
1141 Py_CLEAR(res);
1142 goto end;
1143 }
1144 Py_CLEAR(res);
1145 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001146 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001147 if (limit >= 0)
1148 limit -= n;
1149 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001150 if (self->writable) {
1151 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1152 if (r == NULL)
1153 goto end;
1154 Py_DECREF(r);
1155 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001156
1157 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001158 _bufferedreader_reset_buf(self);
1159 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001160 if (n == -1)
1161 goto end;
1162 if (n <= 0)
1163 break;
1164 if (limit >= 0 && n > limit)
1165 n = limit;
1166 start = self->buffer;
1167 end = start + n;
1168 s = start;
1169 while (s < end) {
1170 if (*s++ == '\n') {
1171 res = PyBytes_FromStringAndSize(start, s - start);
1172 if (res == NULL)
1173 goto end;
1174 self->pos = s - start;
1175 goto found;
1176 }
1177 }
1178 res = PyBytes_FromStringAndSize(start, n);
1179 if (res == NULL)
1180 goto end;
1181 if (n == limit) {
1182 self->pos = n;
1183 break;
1184 }
1185 if (PyList_Append(chunks, res) < 0) {
1186 Py_CLEAR(res);
1187 goto end;
1188 }
1189 Py_CLEAR(res);
1190 written += n;
1191 if (limit >= 0)
1192 limit -= n;
1193 }
1194found:
1195 if (res != NULL && PyList_Append(chunks, res) < 0) {
1196 Py_CLEAR(res);
1197 goto end;
1198 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001199 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001200
1201end:
1202 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001203end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204 Py_XDECREF(chunks);
1205 return res;
1206}
1207
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001208/*[clinic input]
1209_io._Buffered.readline
1210 size: io_ssize_t = -1
1211 /
1212[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001213
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001214static PyObject *
1215_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
1216/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
1217{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001218 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001219 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220}
1221
1222
1223static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001224buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001225{
1226 Py_off_t pos;
1227
1228 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001229 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230 if (pos == -1)
1231 return NULL;
1232 pos -= RAW_OFFSET(self);
1233 /* TODO: sanity check (pos >= 0) */
1234 return PyLong_FromOff_t(pos);
1235}
1236
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001237/*[clinic input]
1238_io._Buffered.seek
1239 target as targetobj: object
1240 whence: int = 0
1241 /
1242[clinic start generated code]*/
1243
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001244static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001245_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1246/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001247{
1248 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001249 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250
1251 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001252
1253 /* Do some error checking instead of trusting OS 'seek()'
1254 ** error detection, just in case.
1255 */
1256 if ((whence < 0 || whence >2)
1257#ifdef SEEK_HOLE
1258 && (whence != SEEK_HOLE)
1259#endif
1260#ifdef SEEK_DATA
1261 && (whence != SEEK_DATA)
1262#endif
1263 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001265 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266 return NULL;
1267 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001268
1269 CHECK_CLOSED(self, "seek of closed file")
1270
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001271 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1272 return NULL;
1273
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001274 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1275 if (target == -1 && PyErr_Occurred())
1276 return NULL;
1277
Jesus Cea94363612012-06-22 18:32:07 +02001278 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1279 buffer. Other whence values must be managed without this optimization.
1280 Some Operating Systems can provide additional values, like
1281 SEEK_HOLE/SEEK_DATA. */
1282 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001283 Py_off_t current, avail;
1284 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001285 so as to return quickly if possible. Also, we needn't take the
1286 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001287 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001288 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1289 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290 current = RAW_TELL(self);
1291 avail = READAHEAD(self);
1292 if (avail > 0) {
1293 Py_off_t offset;
1294 if (whence == 0)
1295 offset = target - (current - RAW_OFFSET(self));
1296 else
1297 offset = target;
1298 if (offset >= -self->pos && offset <= avail) {
1299 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001300 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 }
1302 }
1303 }
1304
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001305 if (!ENTER_BUFFERED(self))
1306 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001307
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308 /* Fallback: invoke raw seek() method and clear buffer */
1309 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001310 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311 if (res == NULL)
1312 goto end;
1313 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001314 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001315 }
1316
1317 /* TODO: align on block boundary and read buffer if needed? */
1318 if (whence == 1)
1319 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001320 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321 if (n == -1)
1322 goto end;
1323 self->raw_pos = -1;
1324 res = PyLong_FromOff_t(n);
1325 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001326 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001327
1328end:
1329 LEAVE_BUFFERED(self)
1330 return res;
1331}
1332
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001333/*[clinic input]
1334_io._Buffered.truncate
1335 pos: object = None
1336 /
1337[clinic start generated code]*/
1338
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001340_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1341/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001342{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343 PyObject *res = NULL;
1344
1345 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001346 if (!ENTER_BUFFERED(self))
1347 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001348
1349 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001350 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001351 if (res == NULL)
1352 goto end;
1353 Py_CLEAR(res);
1354 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1356 if (res == NULL)
1357 goto end;
1358 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001359 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360 PyErr_Clear();
1361
1362end:
1363 LEAVE_BUFFERED(self)
1364 return res;
1365}
1366
1367static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001368buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001369{
1370 PyObject *line;
1371 PyTypeObject *tp;
1372
1373 CHECK_INITIALIZED(self);
1374
1375 tp = Py_TYPE(self);
1376 if (tp == &PyBufferedReader_Type ||
1377 tp == &PyBufferedRandom_Type) {
1378 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001379 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001380 }
1381 else {
1382 line = PyObject_CallMethodObjArgs((PyObject *)self,
1383 _PyIO_str_readline, NULL);
1384 if (line && !PyBytes_Check(line)) {
1385 PyErr_Format(PyExc_IOError,
1386 "readline() should have returned a bytes object, "
1387 "not '%.200s'", Py_TYPE(line)->tp_name);
1388 Py_DECREF(line);
1389 return NULL;
1390 }
1391 }
1392
1393 if (line == NULL)
1394 return NULL;
1395
1396 if (PyBytes_GET_SIZE(line) == 0) {
1397 /* Reached EOF or would have blocked */
1398 Py_DECREF(line);
1399 return NULL;
1400 }
1401
1402 return line;
1403}
1404
Antoine Pitrou716c4442009-05-23 19:04:03 +00001405static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001406buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001407{
1408 PyObject *nameobj, *res;
1409
Martin v. Löwis767046a2011-10-14 15:35:36 +02001410 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001411 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001412 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001413 PyErr_Clear();
1414 else
1415 return NULL;
1416 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1417 }
1418 else {
Serhiy Storchakafca705d2017-03-19 20:27:16 +02001419 int status = Py_ReprEnter((PyObject *)self);
1420 res = NULL;
1421 if (status == 0) {
1422 res = PyUnicode_FromFormat("<%s name=%R>",
1423 Py_TYPE(self)->tp_name, nameobj);
1424 Py_ReprLeave((PyObject *)self);
1425 }
1426 else if (status > 0) {
1427 PyErr_Format(PyExc_RuntimeError,
1428 "reentrant call inside %s.__repr__",
1429 Py_TYPE(self)->tp_name);
1430 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001431 Py_DECREF(nameobj);
1432 }
1433 return res;
1434}
1435
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001436/*
1437 * class BufferedReader
1438 */
1439
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001440static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441{
1442 self->read_end = -1;
1443}
1444
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001445/*[clinic input]
1446_io.BufferedReader.__init__
1447 raw: object
1448 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001449
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001450Create a new buffered reader using the given readable raw IO object.
1451[clinic start generated code]*/
1452
1453static int
1454_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1455 Py_ssize_t buffer_size)
1456/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1457{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001458 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001459 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001460
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001461 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462 return -1;
1463
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001464 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001465 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 self->buffer_size = buffer_size;
1467 self->readable = 1;
1468 self->writable = 0;
1469
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001470 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001472 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001473
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001474 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1475 Py_TYPE(raw) == &PyFileIO_Type);
1476
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001477 self->ok = 1;
1478 return 0;
1479}
1480
1481static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001482_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001483{
1484 Py_buffer buf;
1485 PyObject *memobj, *res;
1486 Py_ssize_t n;
1487 /* NOTE: the buffer needn't be released as its object is NULL. */
1488 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1489 return -1;
1490 memobj = PyMemoryView_FromBuffer(&buf);
1491 if (memobj == NULL)
1492 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001493 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1494 occurs so we needn't do it ourselves.
1495 We then retry reading, ignoring the signal if no handler has
1496 raised (see issue #10956).
1497 */
1498 do {
1499 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001500 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001501 Py_DECREF(memobj);
1502 if (res == NULL)
1503 return -1;
1504 if (res == Py_None) {
1505 /* Non-blocking stream would have blocked. Special return code! */
1506 Py_DECREF(res);
1507 return -2;
1508 }
1509 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1510 Py_DECREF(res);
1511 if (n < 0 || n > len) {
1512 PyErr_Format(PyExc_IOError,
1513 "raw readinto() returned invalid length %zd "
1514 "(should have been between 0 and %zd)", n, len);
1515 return -1;
1516 }
1517 if (n > 0 && self->abs_pos != -1)
1518 self->abs_pos += n;
1519 return n;
1520}
1521
1522static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001523_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001524{
1525 Py_ssize_t start, len, n;
1526 if (VALID_READ_BUFFER(self))
1527 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1528 else
1529 start = 0;
1530 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001531 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532 if (n <= 0)
1533 return n;
1534 self->read_end = start + n;
1535 self->raw_pos = start + n;
1536 return n;
1537}
1538
1539static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001540_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001541{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001542 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001543 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001544
1545 /* First copy what we have in the current buffer. */
1546 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1547 if (current_size) {
1548 data = PyBytes_FromStringAndSize(
1549 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001550 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001551 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001552 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001554 /* We're going past the buffer's bounds, flush it */
1555 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001556 tmp = buffered_flush_and_rewind_unlocked(self);
1557 if (tmp == NULL)
1558 goto cleanup;
1559 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001560 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001561 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001562
1563 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001564 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1565 if (tmp == NULL)
1566 goto cleanup;
1567 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001568 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001570 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001571 if (tmp == Py_None) {
1572 if (current_size == 0) {
1573 res = Py_None;
1574 goto cleanup;
1575 } else {
1576 res = data;
1577 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001578 }
1579 }
1580 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001581 PyBytes_Concat(&data, tmp);
1582 res = data;
1583 goto cleanup;
1584 }
1585 else {
1586 res = tmp;
1587 goto cleanup;
1588 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001589 }
1590
1591 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001592 if (chunks == NULL)
1593 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001594
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595 while (1) {
1596 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001597 if (PyList_Append(chunks, data) < 0)
1598 goto cleanup;
1599 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001600 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001601
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602 /* Read until EOF or until read() would block. */
1603 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001604 if (data == NULL)
1605 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001606 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001608 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609 }
1610 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1611 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001612 res = data;
1613 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001614 }
1615 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001616 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1617 res = tmp;
1618 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001619 }
1620 }
1621 current_size += PyBytes_GET_SIZE(data);
1622 if (self->abs_pos != -1)
1623 self->abs_pos += PyBytes_GET_SIZE(data);
1624 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001625cleanup:
1626 /* res is either NULL or a borrowed ref */
1627 Py_XINCREF(res);
1628 Py_XDECREF(data);
1629 Py_XDECREF(tmp);
1630 Py_XDECREF(chunks);
1631 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001632}
1633
1634/* Read n bytes from the buffer if it can, otherwise return None.
1635 This function is simple enough that it can run unlocked. */
1636static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001637_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001638{
1639 Py_ssize_t current_size;
1640
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001641 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1642 if (n <= current_size) {
1643 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001644 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1645 if (res != NULL)
1646 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001647 return res;
1648 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001649 Py_RETURN_NONE;
1650}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001651
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001652/* Generic read function: read from the stream until enough bytes are read,
1653 * or until an EOF occurs or until read() would block.
1654 */
1655static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001656_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001657{
1658 PyObject *res = NULL;
1659 Py_ssize_t current_size, remaining, written;
1660 char *out;
1661
1662 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1663 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001664 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001665
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001666 res = PyBytes_FromStringAndSize(NULL, n);
1667 if (res == NULL)
1668 goto error;
1669 out = PyBytes_AS_STRING(res);
1670 remaining = n;
1671 written = 0;
1672 if (current_size > 0) {
1673 memcpy(out, self->buffer + self->pos, current_size);
1674 remaining -= current_size;
1675 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001676 self->pos += current_size;
1677 }
1678 /* Flush the write buffer if necessary */
1679 if (self->writable) {
1680 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1681 if (r == NULL)
1682 goto error;
1683 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001684 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001685 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001686 while (remaining > 0) {
1687 /* We want to read a whole block at the end into buffer.
1688 If we had readv() we could do this in one pass. */
1689 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1690 if (r == 0)
1691 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001692 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693 if (r == -1)
1694 goto error;
1695 if (r == 0 || r == -2) {
1696 /* EOF occurred or read() would block. */
1697 if (r == 0 || written > 0) {
1698 if (_PyBytes_Resize(&res, written))
1699 goto error;
1700 return res;
1701 }
1702 Py_DECREF(res);
1703 Py_INCREF(Py_None);
1704 return Py_None;
1705 }
1706 remaining -= r;
1707 written += r;
1708 }
1709 assert(remaining <= self->buffer_size);
1710 self->pos = 0;
1711 self->raw_pos = 0;
1712 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001713 /* NOTE: when the read is satisfied, we avoid issuing any additional
1714 reads, which could block indefinitely (e.g. on a socket).
1715 See issue #9550. */
1716 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001717 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001718 if (r == -1)
1719 goto error;
1720 if (r == 0 || r == -2) {
1721 /* EOF occurred or read() would block. */
1722 if (r == 0 || written > 0) {
1723 if (_PyBytes_Resize(&res, written))
1724 goto error;
1725 return res;
1726 }
1727 Py_DECREF(res);
1728 Py_INCREF(Py_None);
1729 return Py_None;
1730 }
1731 if (remaining > r) {
1732 memcpy(out + written, self->buffer + self->pos, r);
1733 written += r;
1734 self->pos += r;
1735 remaining -= r;
1736 }
1737 else if (remaining > 0) {
1738 memcpy(out + written, self->buffer + self->pos, remaining);
1739 written += remaining;
1740 self->pos += remaining;
1741 remaining = 0;
1742 }
1743 if (remaining == 0)
1744 break;
1745 }
1746
1747 return res;
1748
1749error:
1750 Py_XDECREF(res);
1751 return NULL;
1752}
1753
1754static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001755_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001756{
1757 Py_ssize_t have, r;
1758
1759 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1760 /* Constraints:
1761 1. we don't want to advance the file position.
1762 2. we don't want to lose block alignment, so we can't shift the buffer
1763 to make some place.
1764 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1765 */
1766 if (have > 0) {
1767 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1768 }
1769
1770 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001771 _bufferedreader_reset_buf(self);
1772 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 if (r == -1)
1774 return NULL;
1775 if (r == -2)
1776 r = 0;
1777 self->pos = 0;
1778 return PyBytes_FromStringAndSize(self->buffer, r);
1779}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780
1781
Benjamin Peterson59406a92009-03-26 17:10:29 +00001782
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783/*
1784 * class BufferedWriter
1785 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788{
1789 self->write_pos = 0;
1790 self->write_end = -1;
1791}
1792
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001793/*[clinic input]
1794_io.BufferedWriter.__init__
1795 raw: object
1796 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001798A buffer for a writeable sequential RawIO object.
1799
1800The constructor creates a BufferedWriter for the given writeable raw
1801stream. If the buffer_size is not given, it defaults to
1802DEFAULT_BUFFER_SIZE.
1803[clinic start generated code]*/
1804
1805static int
1806_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1807 Py_ssize_t buffer_size)
1808/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1809{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001811 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001813 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814 return -1;
1815
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001817 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818 self->readable = 0;
1819 self->writable = 1;
1820
1821 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001822 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 self->pos = 0;
1826
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001827 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1828 Py_TYPE(raw) == &PyFileIO_Type);
1829
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001830 self->ok = 1;
1831 return 0;
1832}
1833
1834static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001835_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836{
1837 Py_buffer buf;
1838 PyObject *memobj, *res;
1839 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001840 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841 /* NOTE: the buffer needn't be released as its object is NULL. */
1842 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1843 return -1;
1844 memobj = PyMemoryView_FromBuffer(&buf);
1845 if (memobj == NULL)
1846 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001847 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1848 occurs so we needn't do it ourselves.
1849 We then retry writing, ignoring the signal if no handler has
1850 raised (see issue #10956).
1851 */
1852 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001853 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001854 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001855 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001856 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001857 Py_DECREF(memobj);
1858 if (res == NULL)
1859 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001860 if (res == Py_None) {
1861 /* Non-blocking stream would have blocked. Special return code!
1862 Being paranoid we reset errno in case it is changed by code
1863 triggered by a decref. errno is used by _set_BlockingIOError(). */
1864 Py_DECREF(res);
1865 errno = errnum;
1866 return -2;
1867 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001868 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1869 Py_DECREF(res);
1870 if (n < 0 || n > len) {
1871 PyErr_Format(PyExc_IOError,
1872 "raw write() returned invalid length %zd "
1873 "(should have been between 0 and %zd)", n, len);
1874 return -1;
1875 }
1876 if (n > 0 && self->abs_pos != -1)
1877 self->abs_pos += n;
1878 return n;
1879}
1880
1881/* `restore_pos` is 1 if we need to restore the raw stream position at
1882 the end, 0 otherwise. */
1883static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001884_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885{
1886 Py_ssize_t written = 0;
1887 Py_off_t n, rewind;
1888
1889 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1890 goto end;
1891 /* First, rewind */
1892 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1893 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001894 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001895 if (n < 0) {
1896 goto error;
1897 }
1898 self->raw_pos -= rewind;
1899 }
1900 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001901 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001902 self->buffer + self->write_pos,
1903 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1904 Py_off_t, Py_ssize_t));
1905 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001906 goto error;
1907 }
1908 else if (n == -2) {
1909 _set_BlockingIOError("write could not complete without blocking",
1910 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001911 goto error;
1912 }
1913 self->write_pos += n;
1914 self->raw_pos = self->write_pos;
1915 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001916 /* Partial writes can return successfully when interrupted by a
1917 signal (see write(2)). We must run signal handlers before
1918 blocking another time, possibly indefinitely. */
1919 if (PyErr_CheckSignals() < 0)
1920 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921 }
1922
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001923 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001924
1925end:
1926 Py_RETURN_NONE;
1927
1928error:
1929 return NULL;
1930}
1931
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001932/*[clinic input]
1933_io.BufferedWriter.write
1934 buffer: Py_buffer
1935 /
1936[clinic start generated code]*/
1937
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001939_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1940/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001941{
1942 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001943 Py_ssize_t written, avail, remaining;
1944 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945
1946 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001947 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 return NULL;
1950 }
1951
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001952 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001953 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001954
1955 /* Fast path: the data to write can be fully buffered. */
1956 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1957 self->pos = 0;
1958 self->raw_pos = 0;
1959 }
1960 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001961 if (buffer->len <= avail) {
1962 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001963 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001964 self->write_pos = self->pos;
1965 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001966 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001967 if (self->pos > self->write_end)
1968 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001969 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970 goto end;
1971 }
1972
1973 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001974 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001975 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001976 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001977 if (w == NULL)
1978 goto error;
1979 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001980 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981 /* Make some place by shifting the buffer. */
1982 assert(VALID_WRITE_BUFFER(self));
1983 memmove(self->buffer, self->buffer + self->write_pos,
1984 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1985 Py_off_t, Py_ssize_t));
1986 self->write_end -= self->write_pos;
1987 self->raw_pos -= self->write_pos;
1988 self->pos -= self->write_pos;
1989 self->write_pos = 0;
1990 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1991 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001992 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993 /* Everything can be buffered */
1994 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001995 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1996 self->write_end += buffer->len;
1997 self->pos += buffer->len;
1998 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 goto end;
2000 }
2001 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002002 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002004 self->pos += avail;
2005 /* XXX Modifying the existing exception e using the pointer w
2006 will change e.characters_written but not e.args[2].
2007 Therefore we just replace with a new error. */
2008 _set_BlockingIOError("write could not complete without blocking",
2009 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 goto error;
2011 }
2012 Py_CLEAR(res);
2013
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002014 /* Adjust the raw stream position if it is away from the logical stream
2015 position. This happens if the read buffer has been filled but not
2016 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2017 the raw stream by itself).
2018 Fixes issue #6629.
2019 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002020 offset = RAW_OFFSET(self);
2021 if (offset != 0) {
2022 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002023 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002024 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002025 }
2026
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002027 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002028 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 written = 0;
2030 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002031 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002032 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002034 goto error;
2035 } else if (n == -2) {
2036 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 if (remaining > self->buffer_size) {
2038 /* Can't buffer everything, still buffer as much as possible */
2039 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002040 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 self->raw_pos = 0;
2042 ADJUST_POSITION(self, self->buffer_size);
2043 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002044 written += self->buffer_size;
2045 _set_BlockingIOError("write could not complete without "
2046 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002047 goto error;
2048 }
2049 PyErr_Clear();
2050 break;
2051 }
2052 written += n;
2053 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002054 /* Partial writes can return successfully when interrupted by a
2055 signal (see write(2)). We must run signal handlers before
2056 blocking another time, possibly indefinitely. */
2057 if (PyErr_CheckSignals() < 0)
2058 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002059 }
2060 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002061 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002062 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002063 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064 written += remaining;
2065 }
2066 self->write_pos = 0;
2067 /* TODO: sanity check (remaining >= 0) */
2068 self->write_end = remaining;
2069 ADJUST_POSITION(self, remaining);
2070 self->raw_pos = 0;
2071
2072end:
2073 res = PyLong_FromSsize_t(written);
2074
2075error:
2076 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002077 return res;
2078}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002079
2080
2081
2082/*
2083 * BufferedRWPair
2084 */
2085
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086/* XXX The usefulness of this (compared to having two separate IO objects) is
2087 * questionable.
2088 */
2089
2090typedef struct {
2091 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002092 buffered *reader;
2093 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002094 PyObject *dict;
2095 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002096} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002097
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002098/*[clinic input]
2099_io.BufferedRWPair.__init__
2100 reader: object
2101 writer: object
2102 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2103 /
2104
2105A buffered reader and writer object together.
2106
2107A buffered reader object and buffered writer object put together to
2108form a sequential IO object that can read and write. This is typically
2109used with a socket or two-way pipe.
2110
2111reader and writer are RawIOBase objects that are readable and
2112writeable respectively. If the buffer_size is omitted it defaults to
2113DEFAULT_BUFFER_SIZE.
2114[clinic start generated code]*/
2115
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002116static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002117_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2118 PyObject *writer, Py_ssize_t buffer_size)
2119/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002120{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002121 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002122 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124 return -1;
2125
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002126 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002127 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128 if (self->reader == NULL)
2129 return -1;
2130
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002131 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002132 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002133 if (self->writer == NULL) {
2134 Py_CLEAR(self->reader);
2135 return -1;
2136 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002137
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138 return 0;
2139}
2140
2141static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002142bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143{
2144 Py_VISIT(self->dict);
2145 return 0;
2146}
2147
2148static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002149bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002150{
2151 Py_CLEAR(self->reader);
2152 Py_CLEAR(self->writer);
2153 Py_CLEAR(self->dict);
2154 return 0;
2155}
2156
2157static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002158bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159{
2160 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002161 if (self->weakreflist != NULL)
2162 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002163 Py_CLEAR(self->reader);
2164 Py_CLEAR(self->writer);
2165 Py_CLEAR(self->dict);
2166 Py_TYPE(self)->tp_free((PyObject *) self);
2167}
2168
2169static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002170_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002172 PyObject *func, *ret;
2173 if (self == NULL) {
2174 PyErr_SetString(PyExc_ValueError,
2175 "I/O operation on uninitialized object");
2176 return NULL;
2177 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002179 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002181 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182 return NULL;
2183 }
2184
2185 ret = PyObject_CallObject(func, args);
2186 Py_DECREF(func);
2187 return ret;
2188}
2189
2190static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002191bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002193 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194}
2195
2196static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002197bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002198{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002199 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002200}
2201
2202static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002203bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002204{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002205 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002206}
2207
2208static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002209bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002210{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002211 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002212}
2213
2214static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002215bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2216{
2217 return _forward_call(self->reader, &PyId_readinto1, args);
2218}
2219
2220static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002221bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002223 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224}
2225
2226static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002228{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002229 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230}
2231
2232static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002233bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002235 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236}
2237
2238static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002239bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002241 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242}
2243
2244static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002245bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002246{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002247 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002248 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002250 PyErr_Fetch(&exc, &val, &tb);
2251 else
2252 Py_DECREF(ret);
2253 ret = _forward_call(self->reader, &PyId_close, args);
2254 if (exc != NULL) {
2255 _PyErr_ChainExceptions(exc, val, tb);
2256 Py_CLEAR(ret);
2257 }
2258 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259}
2260
2261static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002264 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265
2266 if (ret != Py_False) {
2267 /* either True or exception */
2268 return ret;
2269 }
2270 Py_DECREF(ret);
2271
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002272 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273}
2274
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002275static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002276bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002277{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002278 if (self->writer == NULL) {
2279 PyErr_SetString(PyExc_RuntimeError,
2280 "the BufferedRWPair object is being garbage-collected");
2281 return NULL;
2282 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002283 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2284}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002285
2286
2287
2288/*
2289 * BufferedRandom
2290 */
2291
2292/*[clinic input]
2293_io.BufferedRandom.__init__
2294 raw: object
2295 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2296
2297A buffered interface to random access streams.
2298
2299The constructor creates a reader and writer for a seekable stream,
2300raw, given in the first argument. If the buffer_size is omitted it
2301defaults to DEFAULT_BUFFER_SIZE.
2302[clinic start generated code]*/
2303
2304static int
2305_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2306 Py_ssize_t buffer_size)
2307/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2308{
2309 self->ok = 0;
2310 self->detached = 0;
2311
2312 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2313 return -1;
2314 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2315 return -1;
2316 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2317 return -1;
2318
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002319 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002320 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002321 self->buffer_size = buffer_size;
2322 self->readable = 1;
2323 self->writable = 1;
2324
2325 if (_buffered_init(self) < 0)
2326 return -1;
2327 _bufferedreader_reset_buf(self);
2328 _bufferedwriter_reset_buf(self);
2329 self->pos = 0;
2330
2331 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2332 Py_TYPE(raw) == &PyFileIO_Type);
2333
2334 self->ok = 1;
2335 return 0;
2336}
2337
2338#include "clinic/bufferedio.c.h"
2339
2340
2341static PyMethodDef bufferediobase_methods[] = {
2342 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2343 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2344 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2345 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2346 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2347 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2348 {NULL, NULL}
2349};
2350
2351PyTypeObject PyBufferedIOBase_Type = {
2352 PyVarObject_HEAD_INIT(NULL, 0)
2353 "_io._BufferedIOBase", /*tp_name*/
2354 0, /*tp_basicsize*/
2355 0, /*tp_itemsize*/
2356 0, /*tp_dealloc*/
2357 0, /*tp_print*/
2358 0, /*tp_getattr*/
2359 0, /*tp_setattr*/
2360 0, /*tp_compare */
2361 0, /*tp_repr*/
2362 0, /*tp_as_number*/
2363 0, /*tp_as_sequence*/
2364 0, /*tp_as_mapping*/
2365 0, /*tp_hash */
2366 0, /*tp_call*/
2367 0, /*tp_str*/
2368 0, /*tp_getattro*/
2369 0, /*tp_setattro*/
2370 0, /*tp_as_buffer*/
2371 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2372 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2373 bufferediobase_doc, /* tp_doc */
2374 0, /* tp_traverse */
2375 0, /* tp_clear */
2376 0, /* tp_richcompare */
2377 0, /* tp_weaklistoffset */
2378 0, /* tp_iter */
2379 0, /* tp_iternext */
2380 bufferediobase_methods, /* tp_methods */
2381 0, /* tp_members */
2382 0, /* tp_getset */
2383 &PyIOBase_Type, /* tp_base */
2384 0, /* tp_dict */
2385 0, /* tp_descr_get */
2386 0, /* tp_descr_set */
2387 0, /* tp_dictoffset */
2388 0, /* tp_init */
2389 0, /* tp_alloc */
2390 0, /* tp_new */
2391 0, /* tp_free */
2392 0, /* tp_is_gc */
2393 0, /* tp_bases */
2394 0, /* tp_mro */
2395 0, /* tp_cache */
2396 0, /* tp_subclasses */
2397 0, /* tp_weaklist */
2398 0, /* tp_del */
2399 0, /* tp_version_tag */
2400 0, /* tp_finalize */
2401};
2402
2403
2404static PyMethodDef bufferedreader_methods[] = {
2405 /* BufferedIOMixin methods */
2406 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2407 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2408 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2409 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2410 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002411 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2412 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2413 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2414 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2415
2416 _IO__BUFFERED_READ_METHODDEF
2417 _IO__BUFFERED_PEEK_METHODDEF
2418 _IO__BUFFERED_READ1_METHODDEF
2419 _IO__BUFFERED_READINTO_METHODDEF
2420 _IO__BUFFERED_READINTO1_METHODDEF
2421 _IO__BUFFERED_READLINE_METHODDEF
2422 _IO__BUFFERED_SEEK_METHODDEF
2423 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2424 _IO__BUFFERED_TRUNCATE_METHODDEF
2425 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2426 {NULL, NULL}
2427};
2428
2429static PyMemberDef bufferedreader_members[] = {
2430 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2431 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2432 {NULL}
2433};
2434
2435static PyGetSetDef bufferedreader_getset[] = {
2436 {"closed", (getter)buffered_closed_get, NULL, NULL},
2437 {"name", (getter)buffered_name_get, NULL, NULL},
2438 {"mode", (getter)buffered_mode_get, NULL, NULL},
2439 {NULL}
2440};
2441
2442
2443PyTypeObject PyBufferedReader_Type = {
2444 PyVarObject_HEAD_INIT(NULL, 0)
2445 "_io.BufferedReader", /*tp_name*/
2446 sizeof(buffered), /*tp_basicsize*/
2447 0, /*tp_itemsize*/
2448 (destructor)buffered_dealloc, /*tp_dealloc*/
2449 0, /*tp_print*/
2450 0, /*tp_getattr*/
2451 0, /*tp_setattr*/
2452 0, /*tp_compare */
2453 (reprfunc)buffered_repr, /*tp_repr*/
2454 0, /*tp_as_number*/
2455 0, /*tp_as_sequence*/
2456 0, /*tp_as_mapping*/
2457 0, /*tp_hash */
2458 0, /*tp_call*/
2459 0, /*tp_str*/
2460 0, /*tp_getattro*/
2461 0, /*tp_setattro*/
2462 0, /*tp_as_buffer*/
2463 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2464 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2465 _io_BufferedReader___init____doc__, /* tp_doc */
2466 (traverseproc)buffered_traverse, /* tp_traverse */
2467 (inquiry)buffered_clear, /* tp_clear */
2468 0, /* tp_richcompare */
2469 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2470 0, /* tp_iter */
2471 (iternextfunc)buffered_iternext, /* tp_iternext */
2472 bufferedreader_methods, /* tp_methods */
2473 bufferedreader_members, /* tp_members */
2474 bufferedreader_getset, /* tp_getset */
2475 0, /* tp_base */
2476 0, /* tp_dict */
2477 0, /* tp_descr_get */
2478 0, /* tp_descr_set */
2479 offsetof(buffered, dict), /* tp_dictoffset */
2480 _io_BufferedReader___init__, /* tp_init */
2481 0, /* tp_alloc */
2482 PyType_GenericNew, /* tp_new */
2483 0, /* tp_free */
2484 0, /* tp_is_gc */
2485 0, /* tp_bases */
2486 0, /* tp_mro */
2487 0, /* tp_cache */
2488 0, /* tp_subclasses */
2489 0, /* tp_weaklist */
2490 0, /* tp_del */
2491 0, /* tp_version_tag */
2492 0, /* tp_finalize */
2493};
2494
2495
2496static PyMethodDef bufferedwriter_methods[] = {
2497 /* BufferedIOMixin methods */
2498 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2499 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2500 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002501 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2502 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2503 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2504 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2505 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2506
2507 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2508 _IO__BUFFERED_TRUNCATE_METHODDEF
2509 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2510 _IO__BUFFERED_SEEK_METHODDEF
2511 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2512 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2513 {NULL, NULL}
2514};
2515
2516static PyMemberDef bufferedwriter_members[] = {
2517 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2518 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2519 {NULL}
2520};
2521
2522static PyGetSetDef bufferedwriter_getset[] = {
2523 {"closed", (getter)buffered_closed_get, NULL, NULL},
2524 {"name", (getter)buffered_name_get, NULL, NULL},
2525 {"mode", (getter)buffered_mode_get, NULL, NULL},
2526 {NULL}
2527};
2528
2529
2530PyTypeObject PyBufferedWriter_Type = {
2531 PyVarObject_HEAD_INIT(NULL, 0)
2532 "_io.BufferedWriter", /*tp_name*/
2533 sizeof(buffered), /*tp_basicsize*/
2534 0, /*tp_itemsize*/
2535 (destructor)buffered_dealloc, /*tp_dealloc*/
2536 0, /*tp_print*/
2537 0, /*tp_getattr*/
2538 0, /*tp_setattr*/
2539 0, /*tp_compare */
2540 (reprfunc)buffered_repr, /*tp_repr*/
2541 0, /*tp_as_number*/
2542 0, /*tp_as_sequence*/
2543 0, /*tp_as_mapping*/
2544 0, /*tp_hash */
2545 0, /*tp_call*/
2546 0, /*tp_str*/
2547 0, /*tp_getattro*/
2548 0, /*tp_setattro*/
2549 0, /*tp_as_buffer*/
2550 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2551 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2552 _io_BufferedWriter___init____doc__, /* tp_doc */
2553 (traverseproc)buffered_traverse, /* tp_traverse */
2554 (inquiry)buffered_clear, /* tp_clear */
2555 0, /* tp_richcompare */
2556 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2557 0, /* tp_iter */
2558 0, /* tp_iternext */
2559 bufferedwriter_methods, /* tp_methods */
2560 bufferedwriter_members, /* tp_members */
2561 bufferedwriter_getset, /* tp_getset */
2562 0, /* tp_base */
2563 0, /* tp_dict */
2564 0, /* tp_descr_get */
2565 0, /* tp_descr_set */
2566 offsetof(buffered, dict), /* tp_dictoffset */
2567 _io_BufferedWriter___init__, /* tp_init */
2568 0, /* tp_alloc */
2569 PyType_GenericNew, /* tp_new */
2570 0, /* tp_free */
2571 0, /* tp_is_gc */
2572 0, /* tp_bases */
2573 0, /* tp_mro */
2574 0, /* tp_cache */
2575 0, /* tp_subclasses */
2576 0, /* tp_weaklist */
2577 0, /* tp_del */
2578 0, /* tp_version_tag */
2579 0, /* tp_finalize */
2580};
2581
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002583static PyMethodDef bufferedrwpair_methods[] = {
2584 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2585 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2586 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2587 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002588 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002590 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2591 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002592
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002593 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2594 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002595
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002596 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2597 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002598
Antoine Pitrou243757e2010-11-05 21:15:39 +00002599 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2600
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002601 {NULL, NULL}
2602};
2603
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002604static PyGetSetDef bufferedrwpair_getset[] = {
2605 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002606 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002607};
2608
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002609PyTypeObject PyBufferedRWPair_Type = {
2610 PyVarObject_HEAD_INIT(NULL, 0)
2611 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002612 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002614 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002615 0, /*tp_print*/
2616 0, /*tp_getattr*/
2617 0, /*tp_setattr*/
2618 0, /*tp_compare */
2619 0, /*tp_repr*/
2620 0, /*tp_as_number*/
2621 0, /*tp_as_sequence*/
2622 0, /*tp_as_mapping*/
2623 0, /*tp_hash */
2624 0, /*tp_call*/
2625 0, /*tp_str*/
2626 0, /*tp_getattro*/
2627 0, /*tp_setattro*/
2628 0, /*tp_as_buffer*/
2629 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002630 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002631 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002632 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2633 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002634 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002635 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636 0, /* tp_iter */
2637 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002638 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002639 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002640 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002641 0, /* tp_base */
2642 0, /* tp_dict */
2643 0, /* tp_descr_get */
2644 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002645 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002646 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647 0, /* tp_alloc */
2648 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002649 0, /* tp_free */
2650 0, /* tp_is_gc */
2651 0, /* tp_bases */
2652 0, /* tp_mro */
2653 0, /* tp_cache */
2654 0, /* tp_subclasses */
2655 0, /* tp_weaklist */
2656 0, /* tp_del */
2657 0, /* tp_version_tag */
2658 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002659};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002660
2661
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002662static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002664 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2665 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2666 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2667 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2668 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2669 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2670 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002671 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002672 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002673
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002674 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002675
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002676 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002677 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002678 _IO__BUFFERED_TRUNCATE_METHODDEF
2679 _IO__BUFFERED_READ_METHODDEF
2680 _IO__BUFFERED_READ1_METHODDEF
2681 _IO__BUFFERED_READINTO_METHODDEF
2682 _IO__BUFFERED_READINTO1_METHODDEF
2683 _IO__BUFFERED_READLINE_METHODDEF
2684 _IO__BUFFERED_PEEK_METHODDEF
2685 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002686 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002687 {NULL, NULL}
2688};
2689
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002690static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002691 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002692 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002693 {NULL}
2694};
2695
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002696static PyGetSetDef bufferedrandom_getset[] = {
2697 {"closed", (getter)buffered_closed_get, NULL, NULL},
2698 {"name", (getter)buffered_name_get, NULL, NULL},
2699 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002700 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002701};
2702
2703
2704PyTypeObject PyBufferedRandom_Type = {
2705 PyVarObject_HEAD_INIT(NULL, 0)
2706 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002707 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002708 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002709 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002710 0, /*tp_print*/
2711 0, /*tp_getattr*/
2712 0, /*tp_setattr*/
2713 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002714 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002715 0, /*tp_as_number*/
2716 0, /*tp_as_sequence*/
2717 0, /*tp_as_mapping*/
2718 0, /*tp_hash */
2719 0, /*tp_call*/
2720 0, /*tp_str*/
2721 0, /*tp_getattro*/
2722 0, /*tp_setattro*/
2723 0, /*tp_as_buffer*/
2724 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002725 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002726 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002727 (traverseproc)buffered_traverse, /* tp_traverse */
2728 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002729 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002730 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002731 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002732 (iternextfunc)buffered_iternext, /* tp_iternext */
2733 bufferedrandom_methods, /* tp_methods */
2734 bufferedrandom_members, /* tp_members */
2735 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002736 0, /* tp_base */
2737 0, /*tp_dict*/
2738 0, /* tp_descr_get */
2739 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002740 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002741 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002742 0, /* tp_alloc */
2743 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002744 0, /* tp_free */
2745 0, /* tp_is_gc */
2746 0, /* tp_bases */
2747 0, /* tp_mro */
2748 0, /* tp_cache */
2749 0, /* tp_subclasses */
2750 0, /* tp_weaklist */
2751 0, /* tp_del */
2752 0, /* tp_version_tag */
2753 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002754};