blob: c760522616ad72c6ab5f7468b8b853173c6b07f8 [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,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000907 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000908 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
Martin Panterccb2c0e2016-10-20 23:48:14 +0000935 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300936 /
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)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000941/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
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) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000948 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000949 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300950
951 CHECK_CLOSED(self, "read of closed file")
952
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 if (n == 0)
954 return PyBytes_FromStringAndSize(NULL, 0);
955
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000956 /* Return up to n bytes. If at least one byte is buffered, we
957 only return buffered bytes. Otherwise, we do one raw read. */
958
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
960 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100961 n = Py_MIN(have, n);
962 res = _bufferedreader_read_fast(self, n);
963 assert(res != Py_None);
964 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000965 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100966 res = PyBytes_FromStringAndSize(NULL, n);
967 if (res == NULL)
968 return NULL;
969 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200970 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100971 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200972 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000973 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100974 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
975 LEAVE_BUFFERED(self)
976 if (r == -1) {
977 Py_DECREF(res);
978 return NULL;
979 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000980 if (r == -2)
981 r = 0;
982 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100983 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 return res;
985}
986
987static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300988_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000989{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200990 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000991 PyObject *res = NULL;
992
993 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200994
Antoine Pitrou3486a982011-05-12 01:57:53 +0200995 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
996 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300997 if (n >= buffer->len) {
998 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
999 self->pos += buffer->len;
1000 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001001 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001002 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001003 self->pos += n;
1004 written = n;
1005 }
1006
1007 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001008 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001009
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001010 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001011 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 if (res == NULL)
1013 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001014 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001015 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001016
1017 _bufferedreader_reset_buf(self);
1018 self->pos = 0;
1019
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001020 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001021 remaining > 0;
1022 written += n, remaining -= n) {
1023 /* If remaining bytes is larger than internal buffer size, copy
1024 * directly into caller's buffer. */
1025 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001026 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001027 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001028 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001029
1030 /* In readinto1 mode, we do not want to fill the internal
1031 buffer if we already have some data to return */
1032 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001033 n = _bufferedreader_fill_buffer(self);
1034 if (n > 0) {
1035 if (n > remaining)
1036 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001037 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001038 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001039 self->pos += n;
1040 continue; /* short circuit */
1041 }
1042 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001043 else
1044 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001045
Antoine Pitrou3486a982011-05-12 01:57:53 +02001046 if (n == 0 || (n == -2 && written > 0))
1047 break;
1048 if (n < 0) {
1049 if (n == -2) {
1050 Py_INCREF(Py_None);
1051 res = Py_None;
1052 }
1053 goto end;
1054 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001055
Benjamin Petersona96fea02014-06-22 14:17:44 -07001056 /* At most one read in readinto1 mode */
1057 if (readinto1) {
1058 written += n;
1059 break;
1060 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001061 }
1062 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001063
1064end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001065 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001066 return res;
1067}
1068
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001069/*[clinic input]
1070_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001071 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001072 /
1073[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001074
1075static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001076_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001077/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001078{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001079 return _buffered_readinto_generic(self, buffer, 0);
1080}
1081
1082/*[clinic input]
1083_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001084 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001085 /
1086[clinic start generated code]*/
1087
1088static PyObject *
1089_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001090/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001091{
1092 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001093}
1094
1095
1096static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001097_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001098{
1099 PyObject *res = NULL;
1100 PyObject *chunks = NULL;
1101 Py_ssize_t n, written = 0;
1102 const char *start, *s, *end;
1103
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001104 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001106 /* First, try to find a line in the buffer. This can run unlocked because
1107 the calls to the C API are simple enough that they can't trigger
1108 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001109 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1110 if (limit >= 0 && n > limit)
1111 n = limit;
1112 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001113 s = memchr(start, '\n', n);
1114 if (s != NULL) {
1115 res = PyBytes_FromStringAndSize(start, s - start + 1);
1116 if (res != NULL)
1117 self->pos += s - start + 1;
1118 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119 }
1120 if (n == limit) {
1121 res = PyBytes_FromStringAndSize(start, n);
1122 if (res != NULL)
1123 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001124 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001125 }
1126
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001127 if (!ENTER_BUFFERED(self))
1128 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001129
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001130 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001131 chunks = PyList_New(0);
1132 if (chunks == NULL)
1133 goto end;
1134 if (n > 0) {
1135 res = PyBytes_FromStringAndSize(start, n);
1136 if (res == NULL)
1137 goto end;
1138 if (PyList_Append(chunks, res) < 0) {
1139 Py_CLEAR(res);
1140 goto end;
1141 }
1142 Py_CLEAR(res);
1143 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001144 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001145 if (limit >= 0)
1146 limit -= n;
1147 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001148 if (self->writable) {
1149 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1150 if (r == NULL)
1151 goto end;
1152 Py_DECREF(r);
1153 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001154
1155 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001156 _bufferedreader_reset_buf(self);
1157 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001158 if (n == -1)
1159 goto end;
1160 if (n <= 0)
1161 break;
1162 if (limit >= 0 && n > limit)
1163 n = limit;
1164 start = self->buffer;
1165 end = start + n;
1166 s = start;
1167 while (s < end) {
1168 if (*s++ == '\n') {
1169 res = PyBytes_FromStringAndSize(start, s - start);
1170 if (res == NULL)
1171 goto end;
1172 self->pos = s - start;
1173 goto found;
1174 }
1175 }
1176 res = PyBytes_FromStringAndSize(start, n);
1177 if (res == NULL)
1178 goto end;
1179 if (n == limit) {
1180 self->pos = n;
1181 break;
1182 }
1183 if (PyList_Append(chunks, res) < 0) {
1184 Py_CLEAR(res);
1185 goto end;
1186 }
1187 Py_CLEAR(res);
1188 written += n;
1189 if (limit >= 0)
1190 limit -= n;
1191 }
1192found:
1193 if (res != NULL && PyList_Append(chunks, res) < 0) {
1194 Py_CLEAR(res);
1195 goto end;
1196 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001197 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001198
1199end:
1200 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001201end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202 Py_XDECREF(chunks);
1203 return res;
1204}
1205
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001206/*[clinic input]
1207_io._Buffered.readline
1208 size: io_ssize_t = -1
1209 /
1210[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001211
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001212static PyObject *
1213_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
1214/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
1215{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001216 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001217 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001218}
1219
1220
1221static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001222buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001223{
1224 Py_off_t pos;
1225
1226 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001227 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001228 if (pos == -1)
1229 return NULL;
1230 pos -= RAW_OFFSET(self);
1231 /* TODO: sanity check (pos >= 0) */
1232 return PyLong_FromOff_t(pos);
1233}
1234
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001235/*[clinic input]
1236_io._Buffered.seek
1237 target as targetobj: object
1238 whence: int = 0
1239 /
1240[clinic start generated code]*/
1241
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001242static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001243_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1244/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245{
1246 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001247 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001248
1249 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001250
1251 /* Do some error checking instead of trusting OS 'seek()'
1252 ** error detection, just in case.
1253 */
1254 if ((whence < 0 || whence >2)
1255#ifdef SEEK_HOLE
1256 && (whence != SEEK_HOLE)
1257#endif
1258#ifdef SEEK_DATA
1259 && (whence != SEEK_DATA)
1260#endif
1261 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001262 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001263 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001264 return NULL;
1265 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001266
1267 CHECK_CLOSED(self, "seek of closed file")
1268
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001269 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1270 return NULL;
1271
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001272 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1273 if (target == -1 && PyErr_Occurred())
1274 return NULL;
1275
Jesus Cea94363612012-06-22 18:32:07 +02001276 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1277 buffer. Other whence values must be managed without this optimization.
1278 Some Operating Systems can provide additional values, like
1279 SEEK_HOLE/SEEK_DATA. */
1280 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001281 Py_off_t current, avail;
1282 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001283 so as to return quickly if possible. Also, we needn't take the
1284 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001286 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1287 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 current = RAW_TELL(self);
1289 avail = READAHEAD(self);
1290 if (avail > 0) {
1291 Py_off_t offset;
1292 if (whence == 0)
1293 offset = target - (current - RAW_OFFSET(self));
1294 else
1295 offset = target;
1296 if (offset >= -self->pos && offset <= avail) {
1297 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001298 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001299 }
1300 }
1301 }
1302
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001303 if (!ENTER_BUFFERED(self))
1304 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001305
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001306 /* Fallback: invoke raw seek() method and clear buffer */
1307 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001308 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001309 if (res == NULL)
1310 goto end;
1311 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001312 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 }
1314
1315 /* TODO: align on block boundary and read buffer if needed? */
1316 if (whence == 1)
1317 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001318 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001319 if (n == -1)
1320 goto end;
1321 self->raw_pos = -1;
1322 res = PyLong_FromOff_t(n);
1323 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001324 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001325
1326end:
1327 LEAVE_BUFFERED(self)
1328 return res;
1329}
1330
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001331/*[clinic input]
1332_io._Buffered.truncate
1333 pos: object = None
1334 /
1335[clinic start generated code]*/
1336
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001337static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001338_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1339/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341 PyObject *res = NULL;
1342
1343 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001344 if (!ENTER_BUFFERED(self))
1345 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001346
1347 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001348 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349 if (res == NULL)
1350 goto end;
1351 Py_CLEAR(res);
1352 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001353 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1354 if (res == NULL)
1355 goto end;
1356 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001357 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001358 PyErr_Clear();
1359
1360end:
1361 LEAVE_BUFFERED(self)
1362 return res;
1363}
1364
1365static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001366buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001367{
1368 PyObject *line;
1369 PyTypeObject *tp;
1370
1371 CHECK_INITIALIZED(self);
1372
1373 tp = Py_TYPE(self);
1374 if (tp == &PyBufferedReader_Type ||
1375 tp == &PyBufferedRandom_Type) {
1376 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001377 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001378 }
1379 else {
1380 line = PyObject_CallMethodObjArgs((PyObject *)self,
1381 _PyIO_str_readline, NULL);
1382 if (line && !PyBytes_Check(line)) {
1383 PyErr_Format(PyExc_IOError,
1384 "readline() should have returned a bytes object, "
1385 "not '%.200s'", Py_TYPE(line)->tp_name);
1386 Py_DECREF(line);
1387 return NULL;
1388 }
1389 }
1390
1391 if (line == NULL)
1392 return NULL;
1393
1394 if (PyBytes_GET_SIZE(line) == 0) {
1395 /* Reached EOF or would have blocked */
1396 Py_DECREF(line);
1397 return NULL;
1398 }
1399
1400 return line;
1401}
1402
Antoine Pitrou716c4442009-05-23 19:04:03 +00001403static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001404buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001405{
1406 PyObject *nameobj, *res;
1407
Martin v. Löwis767046a2011-10-14 15:35:36 +02001408 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001409 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001410 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001411 PyErr_Clear();
1412 else
1413 return NULL;
1414 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1415 }
1416 else {
1417 res = PyUnicode_FromFormat("<%s name=%R>",
1418 Py_TYPE(self)->tp_name, nameobj);
1419 Py_DECREF(nameobj);
1420 }
1421 return res;
1422}
1423
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001424/*
1425 * class BufferedReader
1426 */
1427
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001428static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001429{
1430 self->read_end = -1;
1431}
1432
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001433/*[clinic input]
1434_io.BufferedReader.__init__
1435 raw: object
1436 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001438Create a new buffered reader using the given readable raw IO object.
1439[clinic start generated code]*/
1440
1441static int
1442_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1443 Py_ssize_t buffer_size)
1444/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1445{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001446 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001447 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001449 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450 return -1;
1451
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001452 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001453 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454 self->buffer_size = buffer_size;
1455 self->readable = 1;
1456 self->writable = 0;
1457
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001458 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001459 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001460 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001461
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001462 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1463 Py_TYPE(raw) == &PyFileIO_Type);
1464
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465 self->ok = 1;
1466 return 0;
1467}
1468
1469static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001470_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471{
1472 Py_buffer buf;
1473 PyObject *memobj, *res;
1474 Py_ssize_t n;
1475 /* NOTE: the buffer needn't be released as its object is NULL. */
1476 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1477 return -1;
1478 memobj = PyMemoryView_FromBuffer(&buf);
1479 if (memobj == NULL)
1480 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001481 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1482 occurs so we needn't do it ourselves.
1483 We then retry reading, ignoring the signal if no handler has
1484 raised (see issue #10956).
1485 */
1486 do {
1487 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001488 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001489 Py_DECREF(memobj);
1490 if (res == NULL)
1491 return -1;
1492 if (res == Py_None) {
1493 /* Non-blocking stream would have blocked. Special return code! */
1494 Py_DECREF(res);
1495 return -2;
1496 }
1497 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1498 Py_DECREF(res);
1499 if (n < 0 || n > len) {
1500 PyErr_Format(PyExc_IOError,
1501 "raw readinto() returned invalid length %zd "
1502 "(should have been between 0 and %zd)", n, len);
1503 return -1;
1504 }
1505 if (n > 0 && self->abs_pos != -1)
1506 self->abs_pos += n;
1507 return n;
1508}
1509
1510static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001511_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001512{
1513 Py_ssize_t start, len, n;
1514 if (VALID_READ_BUFFER(self))
1515 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1516 else
1517 start = 0;
1518 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001519 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001520 if (n <= 0)
1521 return n;
1522 self->read_end = start + n;
1523 self->raw_pos = start + n;
1524 return n;
1525}
1526
1527static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001528_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001529{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001530 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001531 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001532
1533 /* First copy what we have in the current buffer. */
1534 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1535 if (current_size) {
1536 data = PyBytes_FromStringAndSize(
1537 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001538 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001539 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001540 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001541 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001542 /* We're going past the buffer's bounds, flush it */
1543 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001544 tmp = buffered_flush_and_rewind_unlocked(self);
1545 if (tmp == NULL)
1546 goto cleanup;
1547 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001548 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001549 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001550
1551 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001552 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1553 if (tmp == NULL)
1554 goto cleanup;
1555 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001556 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001558 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001559 if (tmp == Py_None) {
1560 if (current_size == 0) {
1561 res = Py_None;
1562 goto cleanup;
1563 } else {
1564 res = data;
1565 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001566 }
1567 }
1568 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001569 PyBytes_Concat(&data, tmp);
1570 res = data;
1571 goto cleanup;
1572 }
1573 else {
1574 res = tmp;
1575 goto cleanup;
1576 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001577 }
1578
1579 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001580 if (chunks == NULL)
1581 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001582
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001583 while (1) {
1584 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001585 if (PyList_Append(chunks, data) < 0)
1586 goto cleanup;
1587 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001588 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001589
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001590 /* Read until EOF or until read() would block. */
1591 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001592 if (data == NULL)
1593 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001594 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001595 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001596 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001597 }
1598 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1599 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001600 res = data;
1601 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602 }
1603 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001604 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1605 res = tmp;
1606 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607 }
1608 }
1609 current_size += PyBytes_GET_SIZE(data);
1610 if (self->abs_pos != -1)
1611 self->abs_pos += PyBytes_GET_SIZE(data);
1612 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001613cleanup:
1614 /* res is either NULL or a borrowed ref */
1615 Py_XINCREF(res);
1616 Py_XDECREF(data);
1617 Py_XDECREF(tmp);
1618 Py_XDECREF(chunks);
1619 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001620}
1621
1622/* Read n bytes from the buffer if it can, otherwise return None.
1623 This function is simple enough that it can run unlocked. */
1624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001625_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001626{
1627 Py_ssize_t current_size;
1628
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001629 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1630 if (n <= current_size) {
1631 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001632 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1633 if (res != NULL)
1634 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001635 return res;
1636 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001637 Py_RETURN_NONE;
1638}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001639
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001640/* Generic read function: read from the stream until enough bytes are read,
1641 * or until an EOF occurs or until read() would block.
1642 */
1643static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001644_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001645{
1646 PyObject *res = NULL;
1647 Py_ssize_t current_size, remaining, written;
1648 char *out;
1649
1650 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1651 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001652 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001653
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001654 res = PyBytes_FromStringAndSize(NULL, n);
1655 if (res == NULL)
1656 goto error;
1657 out = PyBytes_AS_STRING(res);
1658 remaining = n;
1659 written = 0;
1660 if (current_size > 0) {
1661 memcpy(out, self->buffer + self->pos, current_size);
1662 remaining -= current_size;
1663 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001664 self->pos += current_size;
1665 }
1666 /* Flush the write buffer if necessary */
1667 if (self->writable) {
1668 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1669 if (r == NULL)
1670 goto error;
1671 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001672 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001673 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001674 while (remaining > 0) {
1675 /* We want to read a whole block at the end into buffer.
1676 If we had readv() we could do this in one pass. */
1677 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1678 if (r == 0)
1679 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001680 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001681 if (r == -1)
1682 goto error;
1683 if (r == 0 || r == -2) {
1684 /* EOF occurred or read() would block. */
1685 if (r == 0 || written > 0) {
1686 if (_PyBytes_Resize(&res, written))
1687 goto error;
1688 return res;
1689 }
1690 Py_DECREF(res);
1691 Py_INCREF(Py_None);
1692 return Py_None;
1693 }
1694 remaining -= r;
1695 written += r;
1696 }
1697 assert(remaining <= self->buffer_size);
1698 self->pos = 0;
1699 self->raw_pos = 0;
1700 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001701 /* NOTE: when the read is satisfied, we avoid issuing any additional
1702 reads, which could block indefinitely (e.g. on a socket).
1703 See issue #9550. */
1704 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 if (r == -1)
1707 goto error;
1708 if (r == 0 || r == -2) {
1709 /* EOF occurred or read() would block. */
1710 if (r == 0 || written > 0) {
1711 if (_PyBytes_Resize(&res, written))
1712 goto error;
1713 return res;
1714 }
1715 Py_DECREF(res);
1716 Py_INCREF(Py_None);
1717 return Py_None;
1718 }
1719 if (remaining > r) {
1720 memcpy(out + written, self->buffer + self->pos, r);
1721 written += r;
1722 self->pos += r;
1723 remaining -= r;
1724 }
1725 else if (remaining > 0) {
1726 memcpy(out + written, self->buffer + self->pos, remaining);
1727 written += remaining;
1728 self->pos += remaining;
1729 remaining = 0;
1730 }
1731 if (remaining == 0)
1732 break;
1733 }
1734
1735 return res;
1736
1737error:
1738 Py_XDECREF(res);
1739 return NULL;
1740}
1741
1742static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001743_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001744{
1745 Py_ssize_t have, r;
1746
1747 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1748 /* Constraints:
1749 1. we don't want to advance the file position.
1750 2. we don't want to lose block alignment, so we can't shift the buffer
1751 to make some place.
1752 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1753 */
1754 if (have > 0) {
1755 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1756 }
1757
1758 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001759 _bufferedreader_reset_buf(self);
1760 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761 if (r == -1)
1762 return NULL;
1763 if (r == -2)
1764 r = 0;
1765 self->pos = 0;
1766 return PyBytes_FromStringAndSize(self->buffer, r);
1767}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001768
1769
Benjamin Peterson59406a92009-03-26 17:10:29 +00001770
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001771/*
1772 * class BufferedWriter
1773 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001774static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001775_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776{
1777 self->write_pos = 0;
1778 self->write_end = -1;
1779}
1780
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001781/*[clinic input]
1782_io.BufferedWriter.__init__
1783 raw: object
1784 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001786A buffer for a writeable sequential RawIO object.
1787
1788The constructor creates a BufferedWriter for the given writeable raw
1789stream. If the buffer_size is not given, it defaults to
1790DEFAULT_BUFFER_SIZE.
1791[clinic start generated code]*/
1792
1793static int
1794_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1795 Py_ssize_t buffer_size)
1796/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1797{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001798 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001799 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001801 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802 return -1;
1803
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001804 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001805 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001806 self->readable = 0;
1807 self->writable = 1;
1808
1809 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001810 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813 self->pos = 0;
1814
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001815 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1816 Py_TYPE(raw) == &PyFileIO_Type);
1817
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818 self->ok = 1;
1819 return 0;
1820}
1821
1822static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001823_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001824{
1825 Py_buffer buf;
1826 PyObject *memobj, *res;
1827 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001828 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001829 /* NOTE: the buffer needn't be released as its object is NULL. */
1830 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1831 return -1;
1832 memobj = PyMemoryView_FromBuffer(&buf);
1833 if (memobj == NULL)
1834 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001835 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1836 occurs so we needn't do it ourselves.
1837 We then retry writing, ignoring the signal if no handler has
1838 raised (see issue #10956).
1839 */
1840 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001841 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001842 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001843 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001844 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001845 Py_DECREF(memobj);
1846 if (res == NULL)
1847 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001848 if (res == Py_None) {
1849 /* Non-blocking stream would have blocked. Special return code!
1850 Being paranoid we reset errno in case it is changed by code
1851 triggered by a decref. errno is used by _set_BlockingIOError(). */
1852 Py_DECREF(res);
1853 errno = errnum;
1854 return -2;
1855 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1857 Py_DECREF(res);
1858 if (n < 0 || n > len) {
1859 PyErr_Format(PyExc_IOError,
1860 "raw write() returned invalid length %zd "
1861 "(should have been between 0 and %zd)", n, len);
1862 return -1;
1863 }
1864 if (n > 0 && self->abs_pos != -1)
1865 self->abs_pos += n;
1866 return n;
1867}
1868
1869/* `restore_pos` is 1 if we need to restore the raw stream position at
1870 the end, 0 otherwise. */
1871static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001872_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001873{
1874 Py_ssize_t written = 0;
1875 Py_off_t n, rewind;
1876
1877 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1878 goto end;
1879 /* First, rewind */
1880 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1881 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001882 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001883 if (n < 0) {
1884 goto error;
1885 }
1886 self->raw_pos -= rewind;
1887 }
1888 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001889 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001890 self->buffer + self->write_pos,
1891 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1892 Py_off_t, Py_ssize_t));
1893 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001894 goto error;
1895 }
1896 else if (n == -2) {
1897 _set_BlockingIOError("write could not complete without blocking",
1898 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001899 goto error;
1900 }
1901 self->write_pos += n;
1902 self->raw_pos = self->write_pos;
1903 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001904 /* Partial writes can return successfully when interrupted by a
1905 signal (see write(2)). We must run signal handlers before
1906 blocking another time, possibly indefinitely. */
1907 if (PyErr_CheckSignals() < 0)
1908 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001909 }
1910
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001911 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912
1913end:
1914 Py_RETURN_NONE;
1915
1916error:
1917 return NULL;
1918}
1919
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001920/*[clinic input]
1921_io.BufferedWriter.write
1922 buffer: Py_buffer
1923 /
1924[clinic start generated code]*/
1925
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001926static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001927_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1928/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929{
1930 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001931 Py_ssize_t written, avail, remaining;
1932 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001933
1934 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001935 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001937 return NULL;
1938 }
1939
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001940 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001941 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942
1943 /* Fast path: the data to write can be fully buffered. */
1944 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1945 self->pos = 0;
1946 self->raw_pos = 0;
1947 }
1948 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001949 if (buffer->len <= avail) {
1950 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001951 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952 self->write_pos = self->pos;
1953 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001954 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001955 if (self->pos > self->write_end)
1956 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001957 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 goto end;
1959 }
1960
1961 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001962 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001963 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001964 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965 if (w == NULL)
1966 goto error;
1967 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001968 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969 /* Make some place by shifting the buffer. */
1970 assert(VALID_WRITE_BUFFER(self));
1971 memmove(self->buffer, self->buffer + self->write_pos,
1972 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1973 Py_off_t, Py_ssize_t));
1974 self->write_end -= self->write_pos;
1975 self->raw_pos -= self->write_pos;
1976 self->pos -= self->write_pos;
1977 self->write_pos = 0;
1978 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1979 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001980 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981 /* Everything can be buffered */
1982 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001983 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1984 self->write_end += buffer->len;
1985 self->pos += buffer->len;
1986 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001987 goto end;
1988 }
1989 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001990 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001992 self->pos += avail;
1993 /* XXX Modifying the existing exception e using the pointer w
1994 will change e.characters_written but not e.args[2].
1995 Therefore we just replace with a new error. */
1996 _set_BlockingIOError("write could not complete without blocking",
1997 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998 goto error;
1999 }
2000 Py_CLEAR(res);
2001
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002002 /* Adjust the raw stream position if it is away from the logical stream
2003 position. This happens if the read buffer has been filled but not
2004 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2005 the raw stream by itself).
2006 Fixes issue #6629.
2007 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002008 offset = RAW_OFFSET(self);
2009 if (offset != 0) {
2010 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002011 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002012 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002013 }
2014
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002016 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002017 written = 0;
2018 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002019 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002020 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002021 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002022 goto error;
2023 } else if (n == -2) {
2024 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002025 if (remaining > self->buffer_size) {
2026 /* Can't buffer everything, still buffer as much as possible */
2027 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002028 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 self->raw_pos = 0;
2030 ADJUST_POSITION(self, self->buffer_size);
2031 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002032 written += self->buffer_size;
2033 _set_BlockingIOError("write could not complete without "
2034 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002035 goto error;
2036 }
2037 PyErr_Clear();
2038 break;
2039 }
2040 written += n;
2041 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002042 /* Partial writes can return successfully when interrupted by a
2043 signal (see write(2)). We must run signal handlers before
2044 blocking another time, possibly indefinitely. */
2045 if (PyErr_CheckSignals() < 0)
2046 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002047 }
2048 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002049 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002050 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002051 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002052 written += remaining;
2053 }
2054 self->write_pos = 0;
2055 /* TODO: sanity check (remaining >= 0) */
2056 self->write_end = remaining;
2057 ADJUST_POSITION(self, remaining);
2058 self->raw_pos = 0;
2059
2060end:
2061 res = PyLong_FromSsize_t(written);
2062
2063error:
2064 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002065 return res;
2066}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002067
2068
2069
2070/*
2071 * BufferedRWPair
2072 */
2073
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074/* XXX The usefulness of this (compared to having two separate IO objects) is
2075 * questionable.
2076 */
2077
2078typedef struct {
2079 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002080 buffered *reader;
2081 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002082 PyObject *dict;
2083 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002084} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002085
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002086/*[clinic input]
2087_io.BufferedRWPair.__init__
2088 reader: object
2089 writer: object
2090 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2091 /
2092
2093A buffered reader and writer object together.
2094
2095A buffered reader object and buffered writer object put together to
2096form a sequential IO object that can read and write. This is typically
2097used with a socket or two-way pipe.
2098
2099reader and writer are RawIOBase objects that are readable and
2100writeable respectively. If the buffer_size is omitted it defaults to
2101DEFAULT_BUFFER_SIZE.
2102[clinic start generated code]*/
2103
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002105_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2106 PyObject *writer, Py_ssize_t buffer_size)
2107/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002109 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002111 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002112 return -1;
2113
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002114 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002115 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002116 if (self->reader == NULL)
2117 return -1;
2118
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002119 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002120 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121 if (self->writer == NULL) {
2122 Py_CLEAR(self->reader);
2123 return -1;
2124 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002125
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002126 return 0;
2127}
2128
2129static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002130bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002131{
2132 Py_VISIT(self->dict);
2133 return 0;
2134}
2135
2136static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002137bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138{
2139 Py_CLEAR(self->reader);
2140 Py_CLEAR(self->writer);
2141 Py_CLEAR(self->dict);
2142 return 0;
2143}
2144
2145static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002146bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147{
2148 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002149 if (self->weakreflist != NULL)
2150 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151 Py_CLEAR(self->reader);
2152 Py_CLEAR(self->writer);
2153 Py_CLEAR(self->dict);
2154 Py_TYPE(self)->tp_free((PyObject *) self);
2155}
2156
2157static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002158_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002160 PyObject *func, *ret;
2161 if (self == NULL) {
2162 PyErr_SetString(PyExc_ValueError,
2163 "I/O operation on uninitialized object");
2164 return NULL;
2165 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002167 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002168 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002169 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170 return NULL;
2171 }
2172
2173 ret = PyObject_CallObject(func, args);
2174 Py_DECREF(func);
2175 return ret;
2176}
2177
2178static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002179bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002181 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002182}
2183
2184static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002185bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002187 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188}
2189
2190static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002191bufferedrwpair_read1(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_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194}
2195
2196static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002197bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002198{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002199 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002200}
2201
2202static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002203bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2204{
2205 return _forward_call(self->reader, &PyId_readinto1, args);
2206}
2207
2208static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002209bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002211 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002212}
2213
2214static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002215bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002216{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002217 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002218}
2219
2220static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002221bufferedrwpair_readable(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->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224}
2225
2226static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227bufferedrwpair_writable(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_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002230}
2231
2232static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002233bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002234{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002235 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002236 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002238 PyErr_Fetch(&exc, &val, &tb);
2239 else
2240 Py_DECREF(ret);
2241 ret = _forward_call(self->reader, &PyId_close, args);
2242 if (exc != NULL) {
2243 _PyErr_ChainExceptions(exc, val, tb);
2244 Py_CLEAR(ret);
2245 }
2246 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002247}
2248
2249static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002250bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002252 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002253
2254 if (ret != Py_False) {
2255 /* either True or exception */
2256 return ret;
2257 }
2258 Py_DECREF(ret);
2259
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002260 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261}
2262
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002263static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002264bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002265{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002266 if (self->writer == NULL) {
2267 PyErr_SetString(PyExc_RuntimeError,
2268 "the BufferedRWPair object is being garbage-collected");
2269 return NULL;
2270 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002271 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2272}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002273
2274
2275
2276/*
2277 * BufferedRandom
2278 */
2279
2280/*[clinic input]
2281_io.BufferedRandom.__init__
2282 raw: object
2283 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2284
2285A buffered interface to random access streams.
2286
2287The constructor creates a reader and writer for a seekable stream,
2288raw, given in the first argument. If the buffer_size is omitted it
2289defaults to DEFAULT_BUFFER_SIZE.
2290[clinic start generated code]*/
2291
2292static int
2293_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2294 Py_ssize_t buffer_size)
2295/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2296{
2297 self->ok = 0;
2298 self->detached = 0;
2299
2300 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2301 return -1;
2302 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2303 return -1;
2304 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2305 return -1;
2306
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002307 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002308 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002309 self->buffer_size = buffer_size;
2310 self->readable = 1;
2311 self->writable = 1;
2312
2313 if (_buffered_init(self) < 0)
2314 return -1;
2315 _bufferedreader_reset_buf(self);
2316 _bufferedwriter_reset_buf(self);
2317 self->pos = 0;
2318
2319 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2320 Py_TYPE(raw) == &PyFileIO_Type);
2321
2322 self->ok = 1;
2323 return 0;
2324}
2325
2326#include "clinic/bufferedio.c.h"
2327
2328
2329static PyMethodDef bufferediobase_methods[] = {
2330 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2331 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2332 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2333 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2334 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2335 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2336 {NULL, NULL}
2337};
2338
2339PyTypeObject PyBufferedIOBase_Type = {
2340 PyVarObject_HEAD_INIT(NULL, 0)
2341 "_io._BufferedIOBase", /*tp_name*/
2342 0, /*tp_basicsize*/
2343 0, /*tp_itemsize*/
2344 0, /*tp_dealloc*/
2345 0, /*tp_print*/
2346 0, /*tp_getattr*/
2347 0, /*tp_setattr*/
2348 0, /*tp_compare */
2349 0, /*tp_repr*/
2350 0, /*tp_as_number*/
2351 0, /*tp_as_sequence*/
2352 0, /*tp_as_mapping*/
2353 0, /*tp_hash */
2354 0, /*tp_call*/
2355 0, /*tp_str*/
2356 0, /*tp_getattro*/
2357 0, /*tp_setattro*/
2358 0, /*tp_as_buffer*/
2359 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2360 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2361 bufferediobase_doc, /* tp_doc */
2362 0, /* tp_traverse */
2363 0, /* tp_clear */
2364 0, /* tp_richcompare */
2365 0, /* tp_weaklistoffset */
2366 0, /* tp_iter */
2367 0, /* tp_iternext */
2368 bufferediobase_methods, /* tp_methods */
2369 0, /* tp_members */
2370 0, /* tp_getset */
2371 &PyIOBase_Type, /* tp_base */
2372 0, /* tp_dict */
2373 0, /* tp_descr_get */
2374 0, /* tp_descr_set */
2375 0, /* tp_dictoffset */
2376 0, /* tp_init */
2377 0, /* tp_alloc */
2378 0, /* tp_new */
2379 0, /* tp_free */
2380 0, /* tp_is_gc */
2381 0, /* tp_bases */
2382 0, /* tp_mro */
2383 0, /* tp_cache */
2384 0, /* tp_subclasses */
2385 0, /* tp_weaklist */
2386 0, /* tp_del */
2387 0, /* tp_version_tag */
2388 0, /* tp_finalize */
2389};
2390
2391
2392static PyMethodDef bufferedreader_methods[] = {
2393 /* BufferedIOMixin methods */
2394 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2395 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2396 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2397 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2398 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002399 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2400 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2401 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2402 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2403
2404 _IO__BUFFERED_READ_METHODDEF
2405 _IO__BUFFERED_PEEK_METHODDEF
2406 _IO__BUFFERED_READ1_METHODDEF
2407 _IO__BUFFERED_READINTO_METHODDEF
2408 _IO__BUFFERED_READINTO1_METHODDEF
2409 _IO__BUFFERED_READLINE_METHODDEF
2410 _IO__BUFFERED_SEEK_METHODDEF
2411 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2412 _IO__BUFFERED_TRUNCATE_METHODDEF
2413 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2414 {NULL, NULL}
2415};
2416
2417static PyMemberDef bufferedreader_members[] = {
2418 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2419 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2420 {NULL}
2421};
2422
2423static PyGetSetDef bufferedreader_getset[] = {
2424 {"closed", (getter)buffered_closed_get, NULL, NULL},
2425 {"name", (getter)buffered_name_get, NULL, NULL},
2426 {"mode", (getter)buffered_mode_get, NULL, NULL},
2427 {NULL}
2428};
2429
2430
2431PyTypeObject PyBufferedReader_Type = {
2432 PyVarObject_HEAD_INIT(NULL, 0)
2433 "_io.BufferedReader", /*tp_name*/
2434 sizeof(buffered), /*tp_basicsize*/
2435 0, /*tp_itemsize*/
2436 (destructor)buffered_dealloc, /*tp_dealloc*/
2437 0, /*tp_print*/
2438 0, /*tp_getattr*/
2439 0, /*tp_setattr*/
2440 0, /*tp_compare */
2441 (reprfunc)buffered_repr, /*tp_repr*/
2442 0, /*tp_as_number*/
2443 0, /*tp_as_sequence*/
2444 0, /*tp_as_mapping*/
2445 0, /*tp_hash */
2446 0, /*tp_call*/
2447 0, /*tp_str*/
2448 0, /*tp_getattro*/
2449 0, /*tp_setattro*/
2450 0, /*tp_as_buffer*/
2451 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2452 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2453 _io_BufferedReader___init____doc__, /* tp_doc */
2454 (traverseproc)buffered_traverse, /* tp_traverse */
2455 (inquiry)buffered_clear, /* tp_clear */
2456 0, /* tp_richcompare */
2457 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2458 0, /* tp_iter */
2459 (iternextfunc)buffered_iternext, /* tp_iternext */
2460 bufferedreader_methods, /* tp_methods */
2461 bufferedreader_members, /* tp_members */
2462 bufferedreader_getset, /* tp_getset */
2463 0, /* tp_base */
2464 0, /* tp_dict */
2465 0, /* tp_descr_get */
2466 0, /* tp_descr_set */
2467 offsetof(buffered, dict), /* tp_dictoffset */
2468 _io_BufferedReader___init__, /* tp_init */
2469 0, /* tp_alloc */
2470 PyType_GenericNew, /* tp_new */
2471 0, /* tp_free */
2472 0, /* tp_is_gc */
2473 0, /* tp_bases */
2474 0, /* tp_mro */
2475 0, /* tp_cache */
2476 0, /* tp_subclasses */
2477 0, /* tp_weaklist */
2478 0, /* tp_del */
2479 0, /* tp_version_tag */
2480 0, /* tp_finalize */
2481};
2482
2483
2484static PyMethodDef bufferedwriter_methods[] = {
2485 /* BufferedIOMixin methods */
2486 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2487 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2488 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002489 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2490 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2491 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2492 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2493 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2494
2495 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2496 _IO__BUFFERED_TRUNCATE_METHODDEF
2497 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2498 _IO__BUFFERED_SEEK_METHODDEF
2499 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2500 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2501 {NULL, NULL}
2502};
2503
2504static PyMemberDef bufferedwriter_members[] = {
2505 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2506 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2507 {NULL}
2508};
2509
2510static PyGetSetDef bufferedwriter_getset[] = {
2511 {"closed", (getter)buffered_closed_get, NULL, NULL},
2512 {"name", (getter)buffered_name_get, NULL, NULL},
2513 {"mode", (getter)buffered_mode_get, NULL, NULL},
2514 {NULL}
2515};
2516
2517
2518PyTypeObject PyBufferedWriter_Type = {
2519 PyVarObject_HEAD_INIT(NULL, 0)
2520 "_io.BufferedWriter", /*tp_name*/
2521 sizeof(buffered), /*tp_basicsize*/
2522 0, /*tp_itemsize*/
2523 (destructor)buffered_dealloc, /*tp_dealloc*/
2524 0, /*tp_print*/
2525 0, /*tp_getattr*/
2526 0, /*tp_setattr*/
2527 0, /*tp_compare */
2528 (reprfunc)buffered_repr, /*tp_repr*/
2529 0, /*tp_as_number*/
2530 0, /*tp_as_sequence*/
2531 0, /*tp_as_mapping*/
2532 0, /*tp_hash */
2533 0, /*tp_call*/
2534 0, /*tp_str*/
2535 0, /*tp_getattro*/
2536 0, /*tp_setattro*/
2537 0, /*tp_as_buffer*/
2538 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2539 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2540 _io_BufferedWriter___init____doc__, /* tp_doc */
2541 (traverseproc)buffered_traverse, /* tp_traverse */
2542 (inquiry)buffered_clear, /* tp_clear */
2543 0, /* tp_richcompare */
2544 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2545 0, /* tp_iter */
2546 0, /* tp_iternext */
2547 bufferedwriter_methods, /* tp_methods */
2548 bufferedwriter_members, /* tp_members */
2549 bufferedwriter_getset, /* tp_getset */
2550 0, /* tp_base */
2551 0, /* tp_dict */
2552 0, /* tp_descr_get */
2553 0, /* tp_descr_set */
2554 offsetof(buffered, dict), /* tp_dictoffset */
2555 _io_BufferedWriter___init__, /* tp_init */
2556 0, /* tp_alloc */
2557 PyType_GenericNew, /* tp_new */
2558 0, /* tp_free */
2559 0, /* tp_is_gc */
2560 0, /* tp_bases */
2561 0, /* tp_mro */
2562 0, /* tp_cache */
2563 0, /* tp_subclasses */
2564 0, /* tp_weaklist */
2565 0, /* tp_del */
2566 0, /* tp_version_tag */
2567 0, /* tp_finalize */
2568};
2569
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002570
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002571static PyMethodDef bufferedrwpair_methods[] = {
2572 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2573 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2574 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2575 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002576 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002577
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002578 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2579 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002580
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002581 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2582 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002583
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002584 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2585 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586
Antoine Pitrou243757e2010-11-05 21:15:39 +00002587 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2588
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589 {NULL, NULL}
2590};
2591
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002592static PyGetSetDef bufferedrwpair_getset[] = {
2593 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002594 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002595};
2596
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002597PyTypeObject PyBufferedRWPair_Type = {
2598 PyVarObject_HEAD_INIT(NULL, 0)
2599 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002600 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002601 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002602 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002603 0, /*tp_print*/
2604 0, /*tp_getattr*/
2605 0, /*tp_setattr*/
2606 0, /*tp_compare */
2607 0, /*tp_repr*/
2608 0, /*tp_as_number*/
2609 0, /*tp_as_sequence*/
2610 0, /*tp_as_mapping*/
2611 0, /*tp_hash */
2612 0, /*tp_call*/
2613 0, /*tp_str*/
2614 0, /*tp_getattro*/
2615 0, /*tp_setattro*/
2616 0, /*tp_as_buffer*/
2617 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002618 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002619 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002620 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2621 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002622 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002623 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002624 0, /* tp_iter */
2625 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002626 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002627 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002628 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629 0, /* tp_base */
2630 0, /* tp_dict */
2631 0, /* tp_descr_get */
2632 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002633 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002634 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635 0, /* tp_alloc */
2636 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002637 0, /* tp_free */
2638 0, /* tp_is_gc */
2639 0, /* tp_bases */
2640 0, /* tp_mro */
2641 0, /* tp_cache */
2642 0, /* tp_subclasses */
2643 0, /* tp_weaklist */
2644 0, /* tp_del */
2645 0, /* tp_version_tag */
2646 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002648
2649
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002650static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002651 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002652 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2653 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2654 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2655 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2656 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2657 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2658 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002659 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002660 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002661
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002662 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002664 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002665 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002666 _IO__BUFFERED_TRUNCATE_METHODDEF
2667 _IO__BUFFERED_READ_METHODDEF
2668 _IO__BUFFERED_READ1_METHODDEF
2669 _IO__BUFFERED_READINTO_METHODDEF
2670 _IO__BUFFERED_READINTO1_METHODDEF
2671 _IO__BUFFERED_READLINE_METHODDEF
2672 _IO__BUFFERED_PEEK_METHODDEF
2673 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002674 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002675 {NULL, NULL}
2676};
2677
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002678static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002679 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002680 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002681 {NULL}
2682};
2683
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002684static PyGetSetDef bufferedrandom_getset[] = {
2685 {"closed", (getter)buffered_closed_get, NULL, NULL},
2686 {"name", (getter)buffered_name_get, NULL, NULL},
2687 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002688 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002689};
2690
2691
2692PyTypeObject PyBufferedRandom_Type = {
2693 PyVarObject_HEAD_INIT(NULL, 0)
2694 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002695 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002696 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002697 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002698 0, /*tp_print*/
2699 0, /*tp_getattr*/
2700 0, /*tp_setattr*/
2701 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002702 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002703 0, /*tp_as_number*/
2704 0, /*tp_as_sequence*/
2705 0, /*tp_as_mapping*/
2706 0, /*tp_hash */
2707 0, /*tp_call*/
2708 0, /*tp_str*/
2709 0, /*tp_getattro*/
2710 0, /*tp_setattro*/
2711 0, /*tp_as_buffer*/
2712 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002713 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002714 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002715 (traverseproc)buffered_traverse, /* tp_traverse */
2716 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002717 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002718 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002720 (iternextfunc)buffered_iternext, /* tp_iternext */
2721 bufferedrandom_methods, /* tp_methods */
2722 bufferedrandom_members, /* tp_members */
2723 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002724 0, /* tp_base */
2725 0, /*tp_dict*/
2726 0, /* tp_descr_get */
2727 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002728 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002729 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002730 0, /* tp_alloc */
2731 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002732 0, /* tp_free */
2733 0, /* tp_is_gc */
2734 0, /* tp_bases */
2735 0, /* tp_mro */
2736 0, /* tp_cache */
2737 0, /* tp_subclasses */
2738 0, /* tp_weaklist */
2739 0, /* tp_del */
2740 0, /* tp_version_tag */
2741 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002742};