blob: 1ae7a70bbda9043b1786f716e64ec7e727102798 [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou3486a982011-05-12 01:57:53 +02003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
Antoine Pitrou3486a982011-05-12 01:57:53 +02006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8*/
9
10#define PY_SSIZE_T_CLEAN
11#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -060012#include "internal/pystate.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000013#include "structmember.h"
14#include "pythread.h"
15#include "_iomodule.h"
16
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030017/*[clinic input]
18module _io
19class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
20class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
21class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
22class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
23class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
24class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
25[clinic start generated code]*/
26/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
27
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020028_Py_IDENTIFIER(close);
29_Py_IDENTIFIER(_dealloc_warn);
30_Py_IDENTIFIER(flush);
31_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020032_Py_IDENTIFIER(mode);
33_Py_IDENTIFIER(name);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020034_Py_IDENTIFIER(peek);
35_Py_IDENTIFIER(read);
36_Py_IDENTIFIER(read1);
37_Py_IDENTIFIER(readable);
38_Py_IDENTIFIER(readinto);
Benjamin Petersona96fea02014-06-22 14:17:44 -070039_Py_IDENTIFIER(readinto1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020040_Py_IDENTIFIER(writable);
41_Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020042
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000043/*
44 * BufferedIOBase class, inherits from IOBase.
45 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000046PyDoc_STRVAR(bufferediobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000047 "Base class for buffered IO objects.\n"
48 "\n"
49 "The main difference with RawIOBase is that the read() method\n"
50 "supports omitting the size argument, and does not have a default\n"
51 "implementation that defers to readinto().\n"
52 "\n"
53 "In addition, read(), readinto() and write() may raise\n"
54 "BlockingIOError if the underlying raw stream is in non-blocking\n"
55 "mode and not ready; unlike their raw counterparts, they will never\n"
56 "return None.\n"
57 "\n"
58 "A typical implementation should not inherit from a RawIOBase\n"
59 "implementation, but wrap one.\n"
60 );
61
62static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030063_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000064{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000065 Py_ssize_t len;
66 PyObject *data;
67
Benjamin Petersona96fea02014-06-22 14:17:44 -070068 data = _PyObject_CallMethodId(self,
69 readinto1 ? &PyId_read1 : &PyId_read,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030070 "n", buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000071 if (data == NULL)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030072 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000073
74 if (!PyBytes_Check(data)) {
75 Py_DECREF(data);
76 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030077 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000078 }
79
Serhiy Storchakafff9a312017-03-21 08:53:25 +020080 len = PyBytes_GET_SIZE(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030081 if (len > buffer->len) {
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030082 PyErr_Format(PyExc_ValueError,
83 "read() returned too much data: "
84 "%zd bytes requested, %zd returned",
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030085 buffer->len, len);
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030086 Py_DECREF(data);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030087 return NULL;
Serhiy Storchaka37a79a12013-05-28 16:24:45 +030088 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030089 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000091 Py_DECREF(data);
92
93 return PyLong_FromSsize_t(len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094}
95
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030096/*[clinic input]
97_io._BufferedIOBase.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -070098 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030099 /
100[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700101
102static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300103_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700104/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -0700105{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300106 return _bufferediobase_readinto_generic(self, buffer, 0);
107}
108
109/*[clinic input]
110_io._BufferedIOBase.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700111 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300112 /
113[clinic start generated code]*/
114
115static PyObject *
116_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700117/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300118{
119 return _bufferediobase_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -0700120}
121
122static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000123bufferediobase_unsupported(const char *message)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000124{
Antoine Pitrou712cb732013-12-21 15:51:54 +0100125 _PyIO_State *state = IO_STATE();
126 if (state != NULL)
127 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000128 return NULL;
129}
130
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300131/*[clinic input]
132_io._BufferedIOBase.detach
133
134Disconnect this buffer from its underlying raw stream and return it.
135
136After the raw stream has been detached, the buffer is in an unusable
137state.
138[clinic start generated code]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000139
140static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300141_io__BufferedIOBase_detach_impl(PyObject *self)
142/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000143{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144 return bufferediobase_unsupported("detach");
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000145}
146
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000147PyDoc_STRVAR(bufferediobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000148 "Read and return up to n bytes.\n"
149 "\n"
150 "If the argument is omitted, None, or negative, reads and\n"
151 "returns all data until EOF.\n"
152 "\n"
153 "If the argument is positive, and the underlying raw stream is\n"
154 "not 'interactive', multiple raw reads may be issued to satisfy\n"
155 "the byte count (unless EOF is reached first). But for\n"
156 "interactive raw streams (as well as sockets and pipes), at most\n"
157 "one raw read will be issued, and a short result does not imply\n"
158 "that EOF is imminent.\n"
159 "\n"
160 "Returns an empty bytes object on EOF.\n"
161 "\n"
162 "Returns None if the underlying raw stream was open in non-blocking\n"
163 "mode and no data is available at the moment.\n");
164
165static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000166bufferediobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000167{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000168 return bufferediobase_unsupported("read");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000169}
170
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000171PyDoc_STRVAR(bufferediobase_read1_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000172 "Read and return up to n bytes, with at most one read() call\n"
173 "to the underlying raw stream. A short result does not imply\n"
174 "that EOF is imminent.\n"
175 "\n"
176 "Returns an empty bytes object on EOF.\n");
177
178static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000179bufferediobase_read1(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000181 return bufferediobase_unsupported("read1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000182}
183
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000184PyDoc_STRVAR(bufferediobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000185 "Write the given buffer to the IO stream.\n"
186 "\n"
Martin Panter6bb91f32016-05-28 00:41:57 +0000187 "Returns the number of bytes written, which is always the length of b\n"
188 "in bytes.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000189 "\n"
190 "Raises BlockingIOError if the buffer is full and the\n"
191 "underlying raw stream cannot accept more data at the moment.\n");
192
193static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194bufferediobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 return bufferediobase_unsupported("write");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197}
198
199
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700200typedef struct _buffered {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000201 PyObject_HEAD
202
203 PyObject *raw;
204 int ok; /* Initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000205 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000206 int readable;
207 int writable;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200208 char finalizing;
Antoine Pitrou3486a982011-05-12 01:57:53 +0200209
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000210 /* True if this is a vanilla Buffered object (rather than a user derived
211 class) *and* the raw stream is a vanilla FileIO object. */
212 int fast_closed_checks;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213
214 /* Absolute position inside the raw stream (-1 if unknown). */
215 Py_off_t abs_pos;
216
217 /* A static buffer of size `buffer_size` */
218 char *buffer;
219 /* Current logical position in the buffer. */
220 Py_off_t pos;
221 /* Position of the raw stream in the buffer. */
222 Py_off_t raw_pos;
223
224 /* Just after the last buffered byte in the buffer, or -1 if the buffer
225 isn't ready for reading. */
226 Py_off_t read_end;
227
228 /* Just after the last byte actually written */
229 Py_off_t write_pos;
230 /* Just after the last byte waiting to be written, or -1 if the buffer
231 isn't ready for writing. */
232 Py_off_t write_end;
233
234 PyThread_type_lock lock;
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200235 volatile unsigned long owner;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000236
237 Py_ssize_t buffer_size;
238 Py_ssize_t buffer_mask;
239
240 PyObject *dict;
241 PyObject *weakreflist;
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700242
243 /* a doubly-linked chained list of "buffered" objects that need to
244 be flushed when the process exits */
245 struct _buffered *next, *prev;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000246} buffered;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000247
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700248/* the actual list of buffered objects */
249static buffered buffer_list_end = {
250 .next = &buffer_list_end,
251 .prev = &buffer_list_end
252};
253
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000254/*
255 Implementation notes:
Antoine Pitrou3486a982011-05-12 01:57:53 +0200256
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000257 * BufferedReader, BufferedWriter and BufferedRandom try to share most
258 methods (this is helped by the members `readable` and `writable`, which
259 are initialized in the respective constructors)
260 * They also share a single buffer for reading and writing. This enables
261 interleaved reads and writes without flushing. It also makes the logic
262 a bit trickier to get right.
263 * The absolute position of the raw stream is cached, if possible, in the
264 `abs_pos` member. It must be updated every time an operation is done
265 on the raw stream. If not sure, it can be reinitialized by calling
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000266 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000267 also does it). To read it, use RAW_TELL().
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000268 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
269 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000270
271 NOTE: we should try to maintain block alignment of reads and writes to the
272 raw stream (according to the buffer size), but for now it is only done
273 in read() and friends.
Antoine Pitrou3486a982011-05-12 01:57:53 +0200274
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000275*/
276
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000277/* These macros protect the buffered object against concurrent operations. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000278
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000279static 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 }
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600289 relax_locking = _Py_IsFinalizing();
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000290 Py_BEGIN_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200291 if (!relax_locking)
292 st = PyThread_acquire_lock(self->lock, 1);
293 else {
294 /* When finalizing, we don't want a deadlock to happen with daemon
295 * threads abruptly shut down while they owned the lock.
296 * Therefore, only wait for a grace period (1 s.).
297 * Note that non-daemon threads have already exited here, so this
298 * shouldn't affect carefully written threaded I/O code.
299 */
Steve Dower6baa0f92015-05-23 08:59:25 -0700300 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200301 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000302 Py_END_ALLOW_THREADS
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200303 if (relax_locking && st != PY_LOCK_ACQUIRED) {
304 PyObject *msgobj = PyUnicode_FromFormat(
305 "could not acquire lock for %A at interpreter "
306 "shutdown, possibly due to daemon threads",
307 (PyObject *) self);
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200308 const char *msg = PyUnicode_AsUTF8(msgobj);
Antoine Pitrou25f85d42015-04-13 19:41:47 +0200309 Py_FatalError(msg);
310 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000311 return 1;
312}
313
314#define ENTER_BUFFERED(self) \
315 ( (PyThread_acquire_lock(self->lock, 0) ? \
316 1 : _enter_buffered_busy(self)) \
317 && (self->owner = PyThread_get_thread_ident(), 1) )
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000318
319#define LEAVE_BUFFERED(self) \
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000320 do { \
321 self->owner = 0; \
322 PyThread_release_lock(self->lock); \
323 } while(0);
324
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000325#define CHECK_INITIALIZED(self) \
326 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000327 if (self->detached) { \
328 PyErr_SetString(PyExc_ValueError, \
329 "raw stream has been detached"); \
330 } else { \
331 PyErr_SetString(PyExc_ValueError, \
332 "I/O operation on uninitialized object"); \
333 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000334 return NULL; \
335 }
336
337#define CHECK_INITIALIZED_INT(self) \
338 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000339 if (self->detached) { \
340 PyErr_SetString(PyExc_ValueError, \
341 "raw stream has been detached"); \
342 } else { \
343 PyErr_SetString(PyExc_ValueError, \
344 "I/O operation on uninitialized object"); \
345 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000346 return -1; \
347 }
348
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000349#define IS_CLOSED(self) \
benfogle9703f092017-11-10 16:03:40 -0500350 (!self->buffer || \
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000351 (self->fast_closed_checks \
352 ? _PyFileIO_closed(self->raw) \
benfogle9703f092017-11-10 16:03:40 -0500353 : buffered_closed(self)))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000354
355#define CHECK_CLOSED(self, error_msg) \
356 if (IS_CLOSED(self)) { \
357 PyErr_SetString(PyExc_ValueError, error_msg); \
358 return NULL; \
359 }
360
361
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000362#define VALID_READ_BUFFER(self) \
363 (self->readable && self->read_end != -1)
364
365#define VALID_WRITE_BUFFER(self) \
366 (self->writable && self->write_end != -1)
367
368#define ADJUST_POSITION(self, _new_pos) \
369 do { \
370 self->pos = _new_pos; \
371 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
372 self->read_end = self->pos; \
373 } while(0)
374
375#define READAHEAD(self) \
376 ((self->readable && VALID_READ_BUFFER(self)) \
377 ? (self->read_end - self->pos) : 0)
378
379#define RAW_OFFSET(self) \
380 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
381 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
382
383#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000384 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385
386#define MINUS_LAST_BLOCK(self, size) \
387 (self->buffer_mask ? \
388 (size & ~self->buffer_mask) : \
389 (self->buffer_size * (size / self->buffer_size)))
390
391
392static void
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700393remove_from_linked_list(buffered *self)
394{
395 self->next->prev = self->prev;
396 self->prev->next = self->next;
397 self->prev = NULL;
398 self->next = NULL;
399}
400
401static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000402buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000403{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200404 self->finalizing = 1;
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700405 if (self->next != NULL)
406 remove_from_linked_list(self);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200407 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000408 return;
409 _PyObject_GC_UNTRACK(self);
410 self->ok = 0;
411 if (self->weakreflist != NULL)
412 PyObject_ClearWeakRefs((PyObject *)self);
413 Py_CLEAR(self->raw);
414 if (self->buffer) {
415 PyMem_Free(self->buffer);
416 self->buffer = NULL;
417 }
418 if (self->lock) {
419 PyThread_free_lock(self->lock);
420 self->lock = NULL;
421 }
422 Py_CLEAR(self->dict);
423 Py_TYPE(self)->tp_free((PyObject *)self);
424}
425
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200426static PyObject *
427buffered_sizeof(buffered *self, void *unused)
428{
429 Py_ssize_t res;
430
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200431 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200432 if (self->buffer)
433 res += self->buffer_size;
434 return PyLong_FromSsize_t(res);
435}
436
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000437static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000438buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000439{
440 Py_VISIT(self->raw);
441 Py_VISIT(self->dict);
442 return 0;
443}
444
445static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000446buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000447{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000448 self->ok = 0;
449 Py_CLEAR(self->raw);
450 Py_CLEAR(self->dict);
451 return 0;
452}
453
Antoine Pitroue033e062010-10-29 10:38:18 +0000454/* Because this can call arbitrary code, it shouldn't be called when
455 the refcount is 0 (that is, not directly from tp_dealloc unless
456 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000457static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000458buffered_dealloc_warn(buffered *self, PyObject *source)
459{
460 if (self->ok && self->raw) {
461 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100462 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
463 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000464 if (r)
465 Py_DECREF(r);
466 else
467 PyErr_Clear();
468 }
469 Py_RETURN_NONE;
470}
471
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000472/*
473 * _BufferedIOMixin methods
474 * This is not a class, just a collection of methods that will be reused
475 * by BufferedReader and BufferedWriter
476 */
477
478/* Flush and close */
479
480static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000481buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482{
483 CHECK_INITIALIZED(self)
484 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
485}
486
487static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000488buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000489{
490 int closed;
491 PyObject *res;
492 CHECK_INITIALIZED_INT(self)
493 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
494 if (res == NULL)
495 return -1;
496 closed = PyObject_IsTrue(res);
497 Py_DECREF(res);
498 return closed;
499}
500
501static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000503{
504 CHECK_INITIALIZED(self)
505 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
506}
507
508static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000509buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510{
Benjamin Peterson68623612012-12-20 11:53:11 -0600511 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512 int r;
513
514 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000515 if (!ENTER_BUFFERED(self))
516 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000517
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000518 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000519 if (r < 0)
520 goto end;
521 if (r > 0) {
522 res = Py_None;
523 Py_INCREF(res);
524 goto end;
525 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000526
Antoine Pitrou796564c2013-07-30 19:59:21 +0200527 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000528 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
529 if (r)
530 Py_DECREF(r);
531 else
532 PyErr_Clear();
533 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000534 /* flush() will most probably re-take the lock, so drop it first */
535 LEAVE_BUFFERED(self)
536 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000537 if (!ENTER_BUFFERED(self))
538 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600539 if (res == NULL)
540 PyErr_Fetch(&exc, &val, &tb);
541 else
542 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543
544 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
545
Jesus Ceadc469452012-10-04 12:37:56 +0200546 if (self->buffer) {
547 PyMem_Free(self->buffer);
548 self->buffer = NULL;
549 }
550
Benjamin Peterson68623612012-12-20 11:53:11 -0600551 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300552 _PyErr_ChainExceptions(exc, val, tb);
553 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600554 }
555
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000556end:
557 LEAVE_BUFFERED(self)
558 return res;
559}
560
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000561/* detach */
562
563static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000564buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000565{
566 PyObject *raw, *res;
567 CHECK_INITIALIZED(self)
568 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
569 if (res == NULL)
570 return NULL;
571 Py_DECREF(res);
572 raw = self->raw;
573 self->raw = NULL;
574 self->detached = 1;
575 self->ok = 0;
576 return raw;
577}
578
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579/* Inquiries */
580
581static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000582buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583{
584 CHECK_INITIALIZED(self)
585 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
586}
587
588static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000589buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590{
591 CHECK_INITIALIZED(self)
592 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
593}
594
595static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000596buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597{
598 CHECK_INITIALIZED(self)
599 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
600}
601
602static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000603buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000604{
605 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200606 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607}
608
609static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000610buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611{
612 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200613 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614}
615
616/* Lower-level APIs */
617
618static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000619buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620{
621 CHECK_INITIALIZED(self)
622 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
623}
624
625static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000626buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627{
628 CHECK_INITIALIZED(self)
629 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
630}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000631
Antoine Pitrou243757e2010-11-05 21:15:39 +0000632/* Serialization */
633
634static PyObject *
635buffered_getstate(buffered *self, PyObject *args)
636{
637 PyErr_Format(PyExc_TypeError,
638 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
639 return NULL;
640}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000641
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642/* Forward decls */
643static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100644_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000645static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000646_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000648_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000650_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200652_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000654_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000655static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000656_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000657static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000658_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200659static Py_ssize_t
660_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000661
662/*
663 * Helpers
664 */
665
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100666/* Sets the current error to BlockingIOError */
667static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200668_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100669{
670 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200671 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100672 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
673 errno, msg, written);
674 if (err)
675 PyErr_SetObject(PyExc_BlockingIOError, err);
676 Py_XDECREF(err);
677}
678
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000679/* Returns the address of the `written` member if a BlockingIOError was
680 raised, NULL otherwise. The error is always re-raised. */
681static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000682_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000683{
684 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200685 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000686
687 PyErr_Fetch(&t, &v, &tb);
688 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
689 PyErr_Restore(t, v, tb);
690 return NULL;
691 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200692 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000693 /* TODO: sanity check (err->written >= 0) */
694 PyErr_Restore(t, v, tb);
695 return &err->written;
696}
697
698static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000699_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000701 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000702 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000703 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
704 if (res == NULL)
705 return -1;
706 n = PyNumber_AsOff_t(res, PyExc_ValueError);
707 Py_DECREF(res);
708 if (n < 0) {
709 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300710 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000711 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200712 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000713 return -1;
714 }
715 self->abs_pos = n;
716 return n;
717}
718
719static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000720_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000721{
722 PyObject *res, *posobj, *whenceobj;
723 Py_off_t n;
724
725 posobj = PyLong_FromOff_t(target);
726 if (posobj == NULL)
727 return -1;
728 whenceobj = PyLong_FromLong(whence);
729 if (whenceobj == NULL) {
730 Py_DECREF(posobj);
731 return -1;
732 }
733 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
734 posobj, whenceobj, NULL);
735 Py_DECREF(posobj);
736 Py_DECREF(whenceobj);
737 if (res == NULL)
738 return -1;
739 n = PyNumber_AsOff_t(res, PyExc_ValueError);
740 Py_DECREF(res);
741 if (n < 0) {
742 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300743 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000744 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200745 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000746 return -1;
747 }
748 self->abs_pos = n;
749 return n;
750}
751
752static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000753_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754{
755 Py_ssize_t n;
756 if (self->buffer_size <= 0) {
757 PyErr_SetString(PyExc_ValueError,
758 "buffer size must be strictly positive");
759 return -1;
760 }
761 if (self->buffer)
762 PyMem_Free(self->buffer);
763 self->buffer = PyMem_Malloc(self->buffer_size);
764 if (self->buffer == NULL) {
765 PyErr_NoMemory();
766 return -1;
767 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000768 if (self->lock)
769 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000770 self->lock = PyThread_allocate_lock();
771 if (self->lock == NULL) {
772 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
773 return -1;
774 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000775 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000776 /* Find out whether buffer_size is a power of 2 */
777 /* XXX is this optimization useful? */
778 for (n = self->buffer_size - 1; n & 1; n >>= 1)
779 ;
780 if (n == 0)
781 self->buffer_mask = self->buffer_size - 1;
782 else
783 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000784 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000785 PyErr_Clear();
786 return 0;
787}
788
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300789/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000790 clears the error indicator), 0 otherwise.
791 Should only be called when PyErr_Occurred() is true.
792*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700793int
794_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000795{
796 static PyObject *eintr_int = NULL;
797 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300798 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000799
800 if (eintr_int == NULL) {
801 eintr_int = PyLong_FromLong(EINTR);
802 assert(eintr_int != NULL);
803 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300804 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000805 return 0;
806 PyErr_Fetch(&typ, &val, &tb);
807 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300808 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000809 assert(env_err != NULL);
810 if (env_err->myerrno != NULL &&
811 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
812 Py_DECREF(typ);
813 Py_DECREF(val);
814 Py_XDECREF(tb);
815 return 1;
816 }
817 /* This silences any error set by PyObject_RichCompareBool() */
818 PyErr_Restore(typ, val, tb);
819 return 0;
820}
821
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822/*
823 * Shared methods and wrappers
824 */
825
826static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200827buffered_flush_and_rewind_unlocked(buffered *self)
828{
829 PyObject *res;
830
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100831 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200832 if (res == NULL)
833 return NULL;
834 Py_DECREF(res);
835
836 if (self->readable) {
837 /* Rewind the raw stream so that its position corresponds to
838 the current logical position. */
839 Py_off_t n;
840 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
841 _bufferedreader_reset_buf(self);
842 if (n == -1)
843 return NULL;
844 }
845 Py_RETURN_NONE;
846}
847
848static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000849buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850{
851 PyObject *res;
852
853 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000854 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000855
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000856 if (!ENTER_BUFFERED(self))
857 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200858 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859 LEAVE_BUFFERED(self)
860
861 return res;
862}
863
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300864/*[clinic input]
865_io._Buffered.peek
866 size: Py_ssize_t = 0
867 /
868
869[clinic start generated code]*/
870
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000871static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300872_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
873/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000874{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000875 PyObject *res = NULL;
876
877 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300878 CHECK_CLOSED(self, "peek of closed file")
879
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000880 if (!ENTER_BUFFERED(self))
881 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882
883 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200884 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885 if (res == NULL)
886 goto end;
887 Py_CLEAR(res);
888 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200889 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000890
891end:
892 LEAVE_BUFFERED(self)
893 return res;
894}
895
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300896/*[clinic input]
897_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300898 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300899 /
900[clinic start generated code]*/
901
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000902static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300903_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300904/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000905{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000906 PyObject *res;
907
908 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909 if (n < -1) {
910 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000911 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912 return NULL;
913 }
914
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000915 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000916
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000917 if (n == -1) {
918 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000919 if (!ENTER_BUFFERED(self))
920 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000921 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000922 }
923 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000924 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200925 if (res != Py_None)
926 return res;
927 Py_DECREF(res);
928 if (!ENTER_BUFFERED(self))
929 return NULL;
930 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000931 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932
Antoine Pitroue05565e2011-08-20 14:39:23 +0200933 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000934 return res;
935}
936
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300937/*[clinic input]
938_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000939 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300940 /
941[clinic start generated code]*/
942
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300944_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000945/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000946{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300947 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000948 PyObject *res = NULL;
949
950 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000951 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000952 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300954
955 CHECK_CLOSED(self, "read of closed file")
956
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 if (n == 0)
958 return PyBytes_FromStringAndSize(NULL, 0);
959
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960 /* Return up to n bytes. If at least one byte is buffered, we
961 only return buffered bytes. Otherwise, we do one raw read. */
962
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
964 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100965 n = Py_MIN(have, n);
966 res = _bufferedreader_read_fast(self, n);
967 assert(res != Py_None);
968 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100970 res = PyBytes_FromStringAndSize(NULL, n);
971 if (res == NULL)
972 return NULL;
973 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200974 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100975 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200976 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000977 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100978 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
979 LEAVE_BUFFERED(self)
980 if (r == -1) {
981 Py_DECREF(res);
982 return NULL;
983 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000984 if (r == -2)
985 r = 0;
986 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100987 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000988 return res;
989}
990
991static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300992_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000993{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200994 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995 PyObject *res = NULL;
996
997 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200998
Antoine Pitrou3486a982011-05-12 01:57:53 +0200999 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1000 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001001 if (n >= buffer->len) {
1002 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1003 self->pos += buffer->len;
1004 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001005 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001006 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001007 self->pos += n;
1008 written = n;
1009 }
1010
1011 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001012 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001013
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001015 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001016 if (res == NULL)
1017 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001018 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001019 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001020
1021 _bufferedreader_reset_buf(self);
1022 self->pos = 0;
1023
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001024 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001025 remaining > 0;
1026 written += n, remaining -= n) {
1027 /* If remaining bytes is larger than internal buffer size, copy
1028 * directly into caller's buffer. */
1029 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001030 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001031 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001032 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001033
1034 /* In readinto1 mode, we do not want to fill the internal
1035 buffer if we already have some data to return */
1036 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001037 n = _bufferedreader_fill_buffer(self);
1038 if (n > 0) {
1039 if (n > remaining)
1040 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001041 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001042 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001043 self->pos += n;
1044 continue; /* short circuit */
1045 }
1046 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001047 else
1048 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001049
Antoine Pitrou3486a982011-05-12 01:57:53 +02001050 if (n == 0 || (n == -2 && written > 0))
1051 break;
1052 if (n < 0) {
1053 if (n == -2) {
1054 Py_INCREF(Py_None);
1055 res = Py_None;
1056 }
1057 goto end;
1058 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001059
Benjamin Petersona96fea02014-06-22 14:17:44 -07001060 /* At most one read in readinto1 mode */
1061 if (readinto1) {
1062 written += n;
1063 break;
1064 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001065 }
1066 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067
1068end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001069 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070 return res;
1071}
1072
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001073/*[clinic input]
1074_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001075 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001076 /
1077[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001078
1079static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001080_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001081/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001082{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001083 return _buffered_readinto_generic(self, buffer, 0);
1084}
1085
1086/*[clinic input]
1087_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001088 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001089 /
1090[clinic start generated code]*/
1091
1092static PyObject *
1093_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001094/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001095{
1096 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001097}
1098
1099
1100static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001101_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001102{
1103 PyObject *res = NULL;
1104 PyObject *chunks = NULL;
1105 Py_ssize_t n, written = 0;
1106 const char *start, *s, *end;
1107
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001108 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001109
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001110 /* First, try to find a line in the buffer. This can run unlocked because
1111 the calls to the C API are simple enough that they can't trigger
1112 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001113 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1114 if (limit >= 0 && n > limit)
1115 n = limit;
1116 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001117 s = memchr(start, '\n', n);
1118 if (s != NULL) {
1119 res = PyBytes_FromStringAndSize(start, s - start + 1);
1120 if (res != NULL)
1121 self->pos += s - start + 1;
1122 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001123 }
1124 if (n == limit) {
1125 res = PyBytes_FromStringAndSize(start, n);
1126 if (res != NULL)
1127 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001128 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001129 }
1130
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001131 if (!ENTER_BUFFERED(self))
1132 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001133
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001134 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001135 chunks = PyList_New(0);
1136 if (chunks == NULL)
1137 goto end;
1138 if (n > 0) {
1139 res = PyBytes_FromStringAndSize(start, n);
1140 if (res == NULL)
1141 goto end;
1142 if (PyList_Append(chunks, res) < 0) {
1143 Py_CLEAR(res);
1144 goto end;
1145 }
1146 Py_CLEAR(res);
1147 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001148 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001149 if (limit >= 0)
1150 limit -= n;
1151 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001152 if (self->writable) {
1153 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1154 if (r == NULL)
1155 goto end;
1156 Py_DECREF(r);
1157 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001158
1159 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001160 _bufferedreader_reset_buf(self);
1161 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001162 if (n == -1)
1163 goto end;
1164 if (n <= 0)
1165 break;
1166 if (limit >= 0 && n > limit)
1167 n = limit;
1168 start = self->buffer;
1169 end = start + n;
1170 s = start;
1171 while (s < end) {
1172 if (*s++ == '\n') {
1173 res = PyBytes_FromStringAndSize(start, s - start);
1174 if (res == NULL)
1175 goto end;
1176 self->pos = s - start;
1177 goto found;
1178 }
1179 }
1180 res = PyBytes_FromStringAndSize(start, n);
1181 if (res == NULL)
1182 goto end;
1183 if (n == limit) {
1184 self->pos = n;
1185 break;
1186 }
1187 if (PyList_Append(chunks, res) < 0) {
1188 Py_CLEAR(res);
1189 goto end;
1190 }
1191 Py_CLEAR(res);
1192 written += n;
1193 if (limit >= 0)
1194 limit -= n;
1195 }
1196found:
1197 if (res != NULL && PyList_Append(chunks, res) < 0) {
1198 Py_CLEAR(res);
1199 goto end;
1200 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001201 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202
1203end:
1204 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001205end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206 Py_XDECREF(chunks);
1207 return res;
1208}
1209
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001210/*[clinic input]
1211_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001212 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001213 /
1214[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001215
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001216static PyObject *
1217_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001218/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001219{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001221 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222}
1223
1224
1225static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001226buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227{
1228 Py_off_t pos;
1229
1230 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001231 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001232 if (pos == -1)
1233 return NULL;
1234 pos -= RAW_OFFSET(self);
1235 /* TODO: sanity check (pos >= 0) */
1236 return PyLong_FromOff_t(pos);
1237}
1238
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001239/*[clinic input]
1240_io._Buffered.seek
1241 target as targetobj: object
1242 whence: int = 0
1243 /
1244[clinic start generated code]*/
1245
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001246static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001247_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1248/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249{
1250 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001251 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001252
1253 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001254
1255 /* Do some error checking instead of trusting OS 'seek()'
1256 ** error detection, just in case.
1257 */
1258 if ((whence < 0 || whence >2)
1259#ifdef SEEK_HOLE
1260 && (whence != SEEK_HOLE)
1261#endif
1262#ifdef SEEK_DATA
1263 && (whence != SEEK_DATA)
1264#endif
1265 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001267 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001268 return NULL;
1269 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001270
1271 CHECK_CLOSED(self, "seek of closed file")
1272
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001273 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1274 return NULL;
1275
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001276 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1277 if (target == -1 && PyErr_Occurred())
1278 return NULL;
1279
Jesus Cea94363612012-06-22 18:32:07 +02001280 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1281 buffer. Other whence values must be managed without this optimization.
1282 Some Operating Systems can provide additional values, like
1283 SEEK_HOLE/SEEK_DATA. */
1284 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285 Py_off_t current, avail;
1286 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001287 so as to return quickly if possible. Also, we needn't take the
1288 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001289 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001290 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1291 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001292 current = RAW_TELL(self);
1293 avail = READAHEAD(self);
1294 if (avail > 0) {
1295 Py_off_t offset;
1296 if (whence == 0)
1297 offset = target - (current - RAW_OFFSET(self));
1298 else
1299 offset = target;
1300 if (offset >= -self->pos && offset <= avail) {
1301 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001302 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001303 }
1304 }
1305 }
1306
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001307 if (!ENTER_BUFFERED(self))
1308 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001309
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 /* Fallback: invoke raw seek() method and clear buffer */
1311 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001312 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 if (res == NULL)
1314 goto end;
1315 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001316 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001317 }
1318
1319 /* TODO: align on block boundary and read buffer if needed? */
1320 if (whence == 1)
1321 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001322 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001323 if (n == -1)
1324 goto end;
1325 self->raw_pos = -1;
1326 res = PyLong_FromOff_t(n);
1327 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001328 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001329
1330end:
1331 LEAVE_BUFFERED(self)
1332 return res;
1333}
1334
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001335/*[clinic input]
1336_io._Buffered.truncate
1337 pos: object = None
1338 /
1339[clinic start generated code]*/
1340
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001342_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1343/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001344{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001345 PyObject *res = NULL;
1346
1347 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001348 if (!ENTER_BUFFERED(self))
1349 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350
1351 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001352 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001353 if (res == NULL)
1354 goto end;
1355 Py_CLEAR(res);
1356 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001357 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1358 if (res == NULL)
1359 goto end;
1360 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001361 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362 PyErr_Clear();
1363
1364end:
1365 LEAVE_BUFFERED(self)
1366 return res;
1367}
1368
1369static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001370buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001371{
1372 PyObject *line;
1373 PyTypeObject *tp;
1374
1375 CHECK_INITIALIZED(self);
1376
1377 tp = Py_TYPE(self);
1378 if (tp == &PyBufferedReader_Type ||
1379 tp == &PyBufferedRandom_Type) {
1380 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001381 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001382 }
1383 else {
1384 line = PyObject_CallMethodObjArgs((PyObject *)self,
1385 _PyIO_str_readline, NULL);
1386 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001387 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388 "readline() should have returned a bytes object, "
1389 "not '%.200s'", Py_TYPE(line)->tp_name);
1390 Py_DECREF(line);
1391 return NULL;
1392 }
1393 }
1394
1395 if (line == NULL)
1396 return NULL;
1397
1398 if (PyBytes_GET_SIZE(line) == 0) {
1399 /* Reached EOF or would have blocked */
1400 Py_DECREF(line);
1401 return NULL;
1402 }
1403
1404 return line;
1405}
1406
Antoine Pitrou716c4442009-05-23 19:04:03 +00001407static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001408buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001409{
1410 PyObject *nameobj, *res;
1411
Martin v. Löwis767046a2011-10-14 15:35:36 +02001412 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001413 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001414 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001415 PyErr_Clear();
1416 else
1417 return NULL;
1418 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1419 }
1420 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001421 int status = Py_ReprEnter((PyObject *)self);
1422 res = NULL;
1423 if (status == 0) {
1424 res = PyUnicode_FromFormat("<%s name=%R>",
1425 Py_TYPE(self)->tp_name, nameobj);
1426 Py_ReprLeave((PyObject *)self);
1427 }
1428 else if (status > 0) {
1429 PyErr_Format(PyExc_RuntimeError,
1430 "reentrant call inside %s.__repr__",
1431 Py_TYPE(self)->tp_name);
1432 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001433 Py_DECREF(nameobj);
1434 }
1435 return res;
1436}
1437
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001438/*
1439 * class BufferedReader
1440 */
1441
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001442static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443{
1444 self->read_end = -1;
1445}
1446
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001447/*[clinic input]
1448_io.BufferedReader.__init__
1449 raw: object
1450 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001451
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001452Create a new buffered reader using the given readable raw IO object.
1453[clinic start generated code]*/
1454
1455static int
1456_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1457 Py_ssize_t buffer_size)
1458/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1459{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001460 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001461 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001463 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001464 return -1;
1465
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001466 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001467 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001468 self->buffer_size = buffer_size;
1469 self->readable = 1;
1470 self->writable = 0;
1471
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001472 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001473 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001474 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001475
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001476 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1477 Py_TYPE(raw) == &PyFileIO_Type);
1478
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 self->ok = 1;
1480 return 0;
1481}
1482
1483static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001484_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001485{
1486 Py_buffer buf;
1487 PyObject *memobj, *res;
1488 Py_ssize_t n;
1489 /* NOTE: the buffer needn't be released as its object is NULL. */
1490 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1491 return -1;
1492 memobj = PyMemoryView_FromBuffer(&buf);
1493 if (memobj == NULL)
1494 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001495 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1496 occurs so we needn't do it ourselves.
1497 We then retry reading, ignoring the signal if no handler has
1498 raised (see issue #10956).
1499 */
1500 do {
1501 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001502 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001503 Py_DECREF(memobj);
1504 if (res == NULL)
1505 return -1;
1506 if (res == Py_None) {
1507 /* Non-blocking stream would have blocked. Special return code! */
1508 Py_DECREF(res);
1509 return -2;
1510 }
1511 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1512 Py_DECREF(res);
1513 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001514 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001515 "raw readinto() returned invalid length %zd "
1516 "(should have been between 0 and %zd)", n, len);
1517 return -1;
1518 }
1519 if (n > 0 && self->abs_pos != -1)
1520 self->abs_pos += n;
1521 return n;
1522}
1523
1524static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001525_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001526{
1527 Py_ssize_t start, len, n;
1528 if (VALID_READ_BUFFER(self))
1529 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1530 else
1531 start = 0;
1532 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001533 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001534 if (n <= 0)
1535 return n;
1536 self->read_end = start + n;
1537 self->raw_pos = start + n;
1538 return n;
1539}
1540
1541static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001542_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001543{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001544 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001545 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001546
1547 /* First copy what we have in the current buffer. */
1548 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1549 if (current_size) {
1550 data = PyBytes_FromStringAndSize(
1551 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001552 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001554 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001555 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001556 /* We're going past the buffer's bounds, flush it */
1557 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001558 tmp = buffered_flush_and_rewind_unlocked(self);
1559 if (tmp == NULL)
1560 goto cleanup;
1561 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001562 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001563 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001564
1565 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001566 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1567 if (tmp == NULL)
1568 goto cleanup;
1569 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001570 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001571 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001572 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001573 if (tmp == Py_None) {
1574 if (current_size == 0) {
1575 res = Py_None;
1576 goto cleanup;
1577 } else {
1578 res = data;
1579 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001580 }
1581 }
1582 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001583 PyBytes_Concat(&data, tmp);
1584 res = data;
1585 goto cleanup;
1586 }
1587 else {
1588 res = tmp;
1589 goto cleanup;
1590 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001591 }
1592
1593 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001594 if (chunks == NULL)
1595 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001596
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001597 while (1) {
1598 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001599 if (PyList_Append(chunks, data) < 0)
1600 goto cleanup;
1601 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001602 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001603
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001604 /* Read until EOF or until read() would block. */
1605 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001606 if (data == NULL)
1607 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001609 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001610 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001611 }
1612 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1613 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001614 res = data;
1615 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001616 }
1617 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001618 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1619 res = tmp;
1620 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001621 }
1622 }
1623 current_size += PyBytes_GET_SIZE(data);
1624 if (self->abs_pos != -1)
1625 self->abs_pos += PyBytes_GET_SIZE(data);
1626 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001627cleanup:
1628 /* res is either NULL or a borrowed ref */
1629 Py_XINCREF(res);
1630 Py_XDECREF(data);
1631 Py_XDECREF(tmp);
1632 Py_XDECREF(chunks);
1633 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001634}
1635
1636/* Read n bytes from the buffer if it can, otherwise return None.
1637 This function is simple enough that it can run unlocked. */
1638static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001639_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001640{
1641 Py_ssize_t current_size;
1642
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001643 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1644 if (n <= current_size) {
1645 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001646 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1647 if (res != NULL)
1648 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001649 return res;
1650 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001651 Py_RETURN_NONE;
1652}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001653
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001654/* Generic read function: read from the stream until enough bytes are read,
1655 * or until an EOF occurs or until read() would block.
1656 */
1657static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001658_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001659{
1660 PyObject *res = NULL;
1661 Py_ssize_t current_size, remaining, written;
1662 char *out;
1663
1664 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1665 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001666 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001667
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001668 res = PyBytes_FromStringAndSize(NULL, n);
1669 if (res == NULL)
1670 goto error;
1671 out = PyBytes_AS_STRING(res);
1672 remaining = n;
1673 written = 0;
1674 if (current_size > 0) {
1675 memcpy(out, self->buffer + self->pos, current_size);
1676 remaining -= current_size;
1677 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001678 self->pos += current_size;
1679 }
1680 /* Flush the write buffer if necessary */
1681 if (self->writable) {
1682 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1683 if (r == NULL)
1684 goto error;
1685 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001686 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001687 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001688 while (remaining > 0) {
1689 /* We want to read a whole block at the end into buffer.
1690 If we had readv() we could do this in one pass. */
1691 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1692 if (r == 0)
1693 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001694 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001695 if (r == -1)
1696 goto error;
1697 if (r == 0 || r == -2) {
1698 /* EOF occurred or read() would block. */
1699 if (r == 0 || written > 0) {
1700 if (_PyBytes_Resize(&res, written))
1701 goto error;
1702 return res;
1703 }
1704 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001705 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 }
1707 remaining -= r;
1708 written += r;
1709 }
1710 assert(remaining <= self->buffer_size);
1711 self->pos = 0;
1712 self->raw_pos = 0;
1713 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001714 /* NOTE: when the read is satisfied, we avoid issuing any additional
1715 reads, which could block indefinitely (e.g. on a socket).
1716 See issue #9550. */
1717 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001718 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719 if (r == -1)
1720 goto error;
1721 if (r == 0 || r == -2) {
1722 /* EOF occurred or read() would block. */
1723 if (r == 0 || written > 0) {
1724 if (_PyBytes_Resize(&res, written))
1725 goto error;
1726 return res;
1727 }
1728 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001729 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001730 }
1731 if (remaining > r) {
1732 memcpy(out + written, self->buffer + self->pos, r);
1733 written += r;
1734 self->pos += r;
1735 remaining -= r;
1736 }
1737 else if (remaining > 0) {
1738 memcpy(out + written, self->buffer + self->pos, remaining);
1739 written += remaining;
1740 self->pos += remaining;
1741 remaining = 0;
1742 }
1743 if (remaining == 0)
1744 break;
1745 }
1746
1747 return res;
1748
1749error:
1750 Py_XDECREF(res);
1751 return NULL;
1752}
1753
1754static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001755_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001756{
1757 Py_ssize_t have, r;
1758
1759 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1760 /* Constraints:
1761 1. we don't want to advance the file position.
1762 2. we don't want to lose block alignment, so we can't shift the buffer
1763 to make some place.
1764 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1765 */
1766 if (have > 0) {
1767 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1768 }
1769
1770 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001771 _bufferedreader_reset_buf(self);
1772 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 if (r == -1)
1774 return NULL;
1775 if (r == -2)
1776 r = 0;
1777 self->pos = 0;
1778 return PyBytes_FromStringAndSize(self->buffer, r);
1779}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780
1781
Benjamin Peterson59406a92009-03-26 17:10:29 +00001782
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001783/*
1784 * class BufferedWriter
1785 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001787_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001788{
1789 self->write_pos = 0;
1790 self->write_end = -1;
1791}
1792
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001793/*[clinic input]
1794_io.BufferedWriter.__init__
1795 raw: object
1796 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001798A buffer for a writeable sequential RawIO object.
1799
1800The constructor creates a BufferedWriter for the given writeable raw
1801stream. If the buffer_size is not given, it defaults to
1802DEFAULT_BUFFER_SIZE.
1803[clinic start generated code]*/
1804
1805static int
1806_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1807 Py_ssize_t buffer_size)
1808/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1809{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001810 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001811 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001812
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001813 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814 return -1;
1815
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001817 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001818 self->readable = 0;
1819 self->writable = 1;
1820
1821 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001822 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001823 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001824 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001825 self->pos = 0;
1826
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001827 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1828 Py_TYPE(raw) == &PyFileIO_Type);
1829
Neil Schemenauer0a1ff242017-09-22 10:17:30 -07001830 if (self->next == NULL) {
1831 self->prev = &buffer_list_end;
1832 self->next = buffer_list_end.next;
1833 buffer_list_end.next->prev = self;
1834 buffer_list_end.next = self;
1835 }
1836
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001837 self->ok = 1;
1838 return 0;
1839}
1840
Neil Schemenauer0a1ff242017-09-22 10:17:30 -07001841/*
1842* Ensure all buffered writers are flushed before proceeding with
1843* normal shutdown. Otherwise, if the underlying file objects get
1844* finalized before the buffered writer wrapping it then any buffered
1845* data will be lost.
1846*/
1847void _PyIO_atexit_flush(void)
1848{
1849 while (buffer_list_end.next != &buffer_list_end) {
1850 buffered *buf = buffer_list_end.next;
1851 remove_from_linked_list(buf);
1852 if (buf->ok && !buf->finalizing) {
1853 /* good state and not finalizing */
1854 Py_INCREF(buf);
1855 buffered_flush(buf, NULL);
1856 Py_DECREF(buf);
1857 PyErr_Clear();
1858 }
1859 }
1860}
1861
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001862static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001863_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864{
1865 Py_buffer buf;
1866 PyObject *memobj, *res;
1867 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001868 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001869 /* NOTE: the buffer needn't be released as its object is NULL. */
1870 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1871 return -1;
1872 memobj = PyMemoryView_FromBuffer(&buf);
1873 if (memobj == NULL)
1874 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001875 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1876 occurs so we needn't do it ourselves.
1877 We then retry writing, ignoring the signal if no handler has
1878 raised (see issue #10956).
1879 */
1880 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001881 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001882 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001883 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001884 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885 Py_DECREF(memobj);
1886 if (res == NULL)
1887 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001888 if (res == Py_None) {
1889 /* Non-blocking stream would have blocked. Special return code!
1890 Being paranoid we reset errno in case it is changed by code
1891 triggered by a decref. errno is used by _set_BlockingIOError(). */
1892 Py_DECREF(res);
1893 errno = errnum;
1894 return -2;
1895 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001896 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1897 Py_DECREF(res);
1898 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001899 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001900 "raw write() returned invalid length %zd "
1901 "(should have been between 0 and %zd)", n, len);
1902 return -1;
1903 }
1904 if (n > 0 && self->abs_pos != -1)
1905 self->abs_pos += n;
1906 return n;
1907}
1908
1909/* `restore_pos` is 1 if we need to restore the raw stream position at
1910 the end, 0 otherwise. */
1911static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001912_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001913{
1914 Py_ssize_t written = 0;
1915 Py_off_t n, rewind;
1916
1917 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1918 goto end;
1919 /* First, rewind */
1920 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1921 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001922 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923 if (n < 0) {
1924 goto error;
1925 }
1926 self->raw_pos -= rewind;
1927 }
1928 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001929 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001930 self->buffer + self->write_pos,
1931 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1932 Py_off_t, Py_ssize_t));
1933 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001934 goto error;
1935 }
1936 else if (n == -2) {
1937 _set_BlockingIOError("write could not complete without blocking",
1938 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939 goto error;
1940 }
1941 self->write_pos += n;
1942 self->raw_pos = self->write_pos;
1943 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001944 /* Partial writes can return successfully when interrupted by a
1945 signal (see write(2)). We must run signal handlers before
1946 blocking another time, possibly indefinitely. */
1947 if (PyErr_CheckSignals() < 0)
1948 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001949 }
1950
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001951 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952
1953end:
1954 Py_RETURN_NONE;
1955
1956error:
1957 return NULL;
1958}
1959
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001960/*[clinic input]
1961_io.BufferedWriter.write
1962 buffer: Py_buffer
1963 /
1964[clinic start generated code]*/
1965
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001967_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1968/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969{
1970 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001971 Py_ssize_t written, avail, remaining;
1972 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973
1974 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001975
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001976 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001977 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978
benfogle9703f092017-11-10 16:03:40 -05001979 /* Issue #31976: Check for closed file after acquiring the lock. Another
1980 thread could be holding the lock while closing the file. */
1981 if (IS_CLOSED(self)) {
1982 PyErr_SetString(PyExc_ValueError, "write to closed file");
1983 goto error;
1984 }
1985
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001986 /* Fast path: the data to write can be fully buffered. */
1987 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1988 self->pos = 0;
1989 self->raw_pos = 0;
1990 }
1991 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001992 if (buffer->len <= avail) {
1993 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001994 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001995 self->write_pos = self->pos;
1996 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001997 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998 if (self->pos > self->write_end)
1999 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002000 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 goto end;
2002 }
2003
2004 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002005 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002006 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002007 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 if (w == NULL)
2009 goto error;
2010 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002011 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002012 /* Make some place by shifting the buffer. */
2013 assert(VALID_WRITE_BUFFER(self));
2014 memmove(self->buffer, self->buffer + self->write_pos,
2015 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2016 Py_off_t, Py_ssize_t));
2017 self->write_end -= self->write_pos;
2018 self->raw_pos -= self->write_pos;
2019 self->pos -= self->write_pos;
2020 self->write_pos = 0;
2021 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2022 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002023 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 /* Everything can be buffered */
2025 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002026 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
2027 self->write_end += buffer->len;
2028 self->pos += buffer->len;
2029 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 goto end;
2031 }
2032 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002033 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002034 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002035 self->pos += avail;
2036 /* XXX Modifying the existing exception e using the pointer w
2037 will change e.characters_written but not e.args[2].
2038 Therefore we just replace with a new error. */
2039 _set_BlockingIOError("write could not complete without blocking",
2040 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 goto error;
2042 }
2043 Py_CLEAR(res);
2044
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002045 /* Adjust the raw stream position if it is away from the logical stream
2046 position. This happens if the read buffer has been filled but not
2047 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2048 the raw stream by itself).
2049 Fixes issue #6629.
2050 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002051 offset = RAW_OFFSET(self);
2052 if (offset != 0) {
2053 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002054 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002055 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002056 }
2057
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002058 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002059 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060 written = 0;
2061 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002062 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002063 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002065 goto error;
2066 } else if (n == -2) {
2067 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068 if (remaining > self->buffer_size) {
2069 /* Can't buffer everything, still buffer as much as possible */
2070 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002071 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002072 self->raw_pos = 0;
2073 ADJUST_POSITION(self, self->buffer_size);
2074 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002075 written += self->buffer_size;
2076 _set_BlockingIOError("write could not complete without "
2077 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078 goto error;
2079 }
2080 PyErr_Clear();
2081 break;
2082 }
2083 written += n;
2084 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002085 /* Partial writes can return successfully when interrupted by a
2086 signal (see write(2)). We must run signal handlers before
2087 blocking another time, possibly indefinitely. */
2088 if (PyErr_CheckSignals() < 0)
2089 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002090 }
2091 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002092 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002093 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002094 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095 written += remaining;
2096 }
2097 self->write_pos = 0;
2098 /* TODO: sanity check (remaining >= 0) */
2099 self->write_end = remaining;
2100 ADJUST_POSITION(self, remaining);
2101 self->raw_pos = 0;
2102
2103end:
2104 res = PyLong_FromSsize_t(written);
2105
2106error:
2107 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108 return res;
2109}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002110
2111
2112
2113/*
2114 * BufferedRWPair
2115 */
2116
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002117/* XXX The usefulness of this (compared to having two separate IO objects) is
2118 * questionable.
2119 */
2120
2121typedef struct {
2122 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123 buffered *reader;
2124 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002125 PyObject *dict;
2126 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002127} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002128
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002129/*[clinic input]
2130_io.BufferedRWPair.__init__
2131 reader: object
2132 writer: object
2133 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2134 /
2135
2136A buffered reader and writer object together.
2137
2138A buffered reader object and buffered writer object put together to
2139form a sequential IO object that can read and write. This is typically
2140used with a socket or two-way pipe.
2141
2142reader and writer are RawIOBase objects that are readable and
2143writeable respectively. If the buffer_size is omitted it defaults to
2144DEFAULT_BUFFER_SIZE.
2145[clinic start generated code]*/
2146
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002148_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2149 PyObject *writer, Py_ssize_t buffer_size)
2150/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002152 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002153 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002154 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155 return -1;
2156
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002157 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002158 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002159 if (self->reader == NULL)
2160 return -1;
2161
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002162 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002163 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002164 if (self->writer == NULL) {
2165 Py_CLEAR(self->reader);
2166 return -1;
2167 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002168
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169 return 0;
2170}
2171
2172static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002173bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002174{
2175 Py_VISIT(self->dict);
2176 return 0;
2177}
2178
2179static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002180bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002181{
2182 Py_CLEAR(self->reader);
2183 Py_CLEAR(self->writer);
2184 Py_CLEAR(self->dict);
2185 return 0;
2186}
2187
2188static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002189bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002190{
2191 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002192 if (self->weakreflist != NULL)
2193 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002194 Py_CLEAR(self->reader);
2195 Py_CLEAR(self->writer);
2196 Py_CLEAR(self->dict);
2197 Py_TYPE(self)->tp_free((PyObject *) self);
2198}
2199
2200static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002201_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002203 PyObject *func, *ret;
2204 if (self == NULL) {
2205 PyErr_SetString(PyExc_ValueError,
2206 "I/O operation on uninitialized object");
2207 return NULL;
2208 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002210 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002211 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002212 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213 return NULL;
2214 }
2215
2216 ret = PyObject_CallObject(func, args);
2217 Py_DECREF(func);
2218 return ret;
2219}
2220
2221static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002222bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002223{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002224 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225}
2226
2227static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002228bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002230 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002231}
2232
2233static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002234bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002236 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002237}
2238
2239static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002240bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002241{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002242 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002243}
2244
2245static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002246bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2247{
2248 return _forward_call(self->reader, &PyId_readinto1, args);
2249}
2250
2251static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002252bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002253{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002254 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255}
2256
2257static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002258bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002260 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261}
2262
2263static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002264bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002265{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002266 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267}
2268
2269static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002270bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002272 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273}
2274
2275static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002276bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002277{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002278 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002279 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002280 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002281 PyErr_Fetch(&exc, &val, &tb);
2282 else
2283 Py_DECREF(ret);
2284 ret = _forward_call(self->reader, &PyId_close, args);
2285 if (exc != NULL) {
2286 _PyErr_ChainExceptions(exc, val, tb);
2287 Py_CLEAR(ret);
2288 }
2289 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290}
2291
2292static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002293bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002294{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002295 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296
2297 if (ret != Py_False) {
2298 /* either True or exception */
2299 return ret;
2300 }
2301 Py_DECREF(ret);
2302
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002303 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002304}
2305
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002306static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002307bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002308{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002309 if (self->writer == NULL) {
2310 PyErr_SetString(PyExc_RuntimeError,
2311 "the BufferedRWPair object is being garbage-collected");
2312 return NULL;
2313 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002314 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2315}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002316
2317
2318
2319/*
2320 * BufferedRandom
2321 */
2322
2323/*[clinic input]
2324_io.BufferedRandom.__init__
2325 raw: object
2326 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2327
2328A buffered interface to random access streams.
2329
2330The constructor creates a reader and writer for a seekable stream,
2331raw, given in the first argument. If the buffer_size is omitted it
2332defaults to DEFAULT_BUFFER_SIZE.
2333[clinic start generated code]*/
2334
2335static int
2336_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2337 Py_ssize_t buffer_size)
2338/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2339{
2340 self->ok = 0;
2341 self->detached = 0;
2342
2343 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2344 return -1;
2345 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2346 return -1;
2347 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2348 return -1;
2349
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002350 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002351 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002352 self->buffer_size = buffer_size;
2353 self->readable = 1;
2354 self->writable = 1;
2355
2356 if (_buffered_init(self) < 0)
2357 return -1;
2358 _bufferedreader_reset_buf(self);
2359 _bufferedwriter_reset_buf(self);
2360 self->pos = 0;
2361
2362 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2363 Py_TYPE(raw) == &PyFileIO_Type);
2364
2365 self->ok = 1;
2366 return 0;
2367}
2368
2369#include "clinic/bufferedio.c.h"
2370
2371
2372static PyMethodDef bufferediobase_methods[] = {
2373 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2374 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2375 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2376 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2377 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2378 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2379 {NULL, NULL}
2380};
2381
2382PyTypeObject PyBufferedIOBase_Type = {
2383 PyVarObject_HEAD_INIT(NULL, 0)
2384 "_io._BufferedIOBase", /*tp_name*/
2385 0, /*tp_basicsize*/
2386 0, /*tp_itemsize*/
2387 0, /*tp_dealloc*/
2388 0, /*tp_print*/
2389 0, /*tp_getattr*/
2390 0, /*tp_setattr*/
2391 0, /*tp_compare */
2392 0, /*tp_repr*/
2393 0, /*tp_as_number*/
2394 0, /*tp_as_sequence*/
2395 0, /*tp_as_mapping*/
2396 0, /*tp_hash */
2397 0, /*tp_call*/
2398 0, /*tp_str*/
2399 0, /*tp_getattro*/
2400 0, /*tp_setattro*/
2401 0, /*tp_as_buffer*/
2402 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2403 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2404 bufferediobase_doc, /* tp_doc */
2405 0, /* tp_traverse */
2406 0, /* tp_clear */
2407 0, /* tp_richcompare */
2408 0, /* tp_weaklistoffset */
2409 0, /* tp_iter */
2410 0, /* tp_iternext */
2411 bufferediobase_methods, /* tp_methods */
2412 0, /* tp_members */
2413 0, /* tp_getset */
2414 &PyIOBase_Type, /* tp_base */
2415 0, /* tp_dict */
2416 0, /* tp_descr_get */
2417 0, /* tp_descr_set */
2418 0, /* tp_dictoffset */
2419 0, /* tp_init */
2420 0, /* tp_alloc */
2421 0, /* tp_new */
2422 0, /* tp_free */
2423 0, /* tp_is_gc */
2424 0, /* tp_bases */
2425 0, /* tp_mro */
2426 0, /* tp_cache */
2427 0, /* tp_subclasses */
2428 0, /* tp_weaklist */
2429 0, /* tp_del */
2430 0, /* tp_version_tag */
2431 0, /* tp_finalize */
2432};
2433
2434
2435static PyMethodDef bufferedreader_methods[] = {
2436 /* BufferedIOMixin methods */
2437 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2438 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2439 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2440 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2441 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002442 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2443 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2444 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2445 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2446
2447 _IO__BUFFERED_READ_METHODDEF
2448 _IO__BUFFERED_PEEK_METHODDEF
2449 _IO__BUFFERED_READ1_METHODDEF
2450 _IO__BUFFERED_READINTO_METHODDEF
2451 _IO__BUFFERED_READINTO1_METHODDEF
2452 _IO__BUFFERED_READLINE_METHODDEF
2453 _IO__BUFFERED_SEEK_METHODDEF
2454 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2455 _IO__BUFFERED_TRUNCATE_METHODDEF
2456 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2457 {NULL, NULL}
2458};
2459
2460static PyMemberDef bufferedreader_members[] = {
2461 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2462 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2463 {NULL}
2464};
2465
2466static PyGetSetDef bufferedreader_getset[] = {
2467 {"closed", (getter)buffered_closed_get, NULL, NULL},
2468 {"name", (getter)buffered_name_get, NULL, NULL},
2469 {"mode", (getter)buffered_mode_get, NULL, NULL},
2470 {NULL}
2471};
2472
2473
2474PyTypeObject PyBufferedReader_Type = {
2475 PyVarObject_HEAD_INIT(NULL, 0)
2476 "_io.BufferedReader", /*tp_name*/
2477 sizeof(buffered), /*tp_basicsize*/
2478 0, /*tp_itemsize*/
2479 (destructor)buffered_dealloc, /*tp_dealloc*/
2480 0, /*tp_print*/
2481 0, /*tp_getattr*/
2482 0, /*tp_setattr*/
2483 0, /*tp_compare */
2484 (reprfunc)buffered_repr, /*tp_repr*/
2485 0, /*tp_as_number*/
2486 0, /*tp_as_sequence*/
2487 0, /*tp_as_mapping*/
2488 0, /*tp_hash */
2489 0, /*tp_call*/
2490 0, /*tp_str*/
2491 0, /*tp_getattro*/
2492 0, /*tp_setattro*/
2493 0, /*tp_as_buffer*/
2494 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2495 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2496 _io_BufferedReader___init____doc__, /* tp_doc */
2497 (traverseproc)buffered_traverse, /* tp_traverse */
2498 (inquiry)buffered_clear, /* tp_clear */
2499 0, /* tp_richcompare */
2500 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2501 0, /* tp_iter */
2502 (iternextfunc)buffered_iternext, /* tp_iternext */
2503 bufferedreader_methods, /* tp_methods */
2504 bufferedreader_members, /* tp_members */
2505 bufferedreader_getset, /* tp_getset */
2506 0, /* tp_base */
2507 0, /* tp_dict */
2508 0, /* tp_descr_get */
2509 0, /* tp_descr_set */
2510 offsetof(buffered, dict), /* tp_dictoffset */
2511 _io_BufferedReader___init__, /* tp_init */
2512 0, /* tp_alloc */
2513 PyType_GenericNew, /* tp_new */
2514 0, /* tp_free */
2515 0, /* tp_is_gc */
2516 0, /* tp_bases */
2517 0, /* tp_mro */
2518 0, /* tp_cache */
2519 0, /* tp_subclasses */
2520 0, /* tp_weaklist */
2521 0, /* tp_del */
2522 0, /* tp_version_tag */
2523 0, /* tp_finalize */
2524};
2525
2526
2527static PyMethodDef bufferedwriter_methods[] = {
2528 /* BufferedIOMixin methods */
2529 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2530 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2531 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002532 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2533 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2534 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2535 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2536 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2537
2538 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2539 _IO__BUFFERED_TRUNCATE_METHODDEF
2540 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2541 _IO__BUFFERED_SEEK_METHODDEF
2542 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2543 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2544 {NULL, NULL}
2545};
2546
2547static PyMemberDef bufferedwriter_members[] = {
2548 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2549 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2550 {NULL}
2551};
2552
2553static PyGetSetDef bufferedwriter_getset[] = {
2554 {"closed", (getter)buffered_closed_get, NULL, NULL},
2555 {"name", (getter)buffered_name_get, NULL, NULL},
2556 {"mode", (getter)buffered_mode_get, NULL, NULL},
2557 {NULL}
2558};
2559
2560
2561PyTypeObject PyBufferedWriter_Type = {
2562 PyVarObject_HEAD_INIT(NULL, 0)
2563 "_io.BufferedWriter", /*tp_name*/
2564 sizeof(buffered), /*tp_basicsize*/
2565 0, /*tp_itemsize*/
2566 (destructor)buffered_dealloc, /*tp_dealloc*/
2567 0, /*tp_print*/
2568 0, /*tp_getattr*/
2569 0, /*tp_setattr*/
2570 0, /*tp_compare */
2571 (reprfunc)buffered_repr, /*tp_repr*/
2572 0, /*tp_as_number*/
2573 0, /*tp_as_sequence*/
2574 0, /*tp_as_mapping*/
2575 0, /*tp_hash */
2576 0, /*tp_call*/
2577 0, /*tp_str*/
2578 0, /*tp_getattro*/
2579 0, /*tp_setattro*/
2580 0, /*tp_as_buffer*/
2581 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2582 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2583 _io_BufferedWriter___init____doc__, /* tp_doc */
2584 (traverseproc)buffered_traverse, /* tp_traverse */
2585 (inquiry)buffered_clear, /* tp_clear */
2586 0, /* tp_richcompare */
2587 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2588 0, /* tp_iter */
2589 0, /* tp_iternext */
2590 bufferedwriter_methods, /* tp_methods */
2591 bufferedwriter_members, /* tp_members */
2592 bufferedwriter_getset, /* tp_getset */
2593 0, /* tp_base */
2594 0, /* tp_dict */
2595 0, /* tp_descr_get */
2596 0, /* tp_descr_set */
2597 offsetof(buffered, dict), /* tp_dictoffset */
2598 _io_BufferedWriter___init__, /* tp_init */
2599 0, /* tp_alloc */
2600 PyType_GenericNew, /* tp_new */
2601 0, /* tp_free */
2602 0, /* tp_is_gc */
2603 0, /* tp_bases */
2604 0, /* tp_mro */
2605 0, /* tp_cache */
2606 0, /* tp_subclasses */
2607 0, /* tp_weaklist */
2608 0, /* tp_del */
2609 0, /* tp_version_tag */
2610 0, /* tp_finalize */
2611};
2612
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002613
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002614static PyMethodDef bufferedrwpair_methods[] = {
2615 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2616 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2617 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2618 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002619 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002620
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002621 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2622 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002623
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002624 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2625 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002626
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002627 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2628 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629
Antoine Pitrou243757e2010-11-05 21:15:39 +00002630 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2631
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002632 {NULL, NULL}
2633};
2634
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002635static PyGetSetDef bufferedrwpair_getset[] = {
2636 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002637 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002638};
2639
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002640PyTypeObject PyBufferedRWPair_Type = {
2641 PyVarObject_HEAD_INIT(NULL, 0)
2642 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002643 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002644 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002645 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002646 0, /*tp_print*/
2647 0, /*tp_getattr*/
2648 0, /*tp_setattr*/
2649 0, /*tp_compare */
2650 0, /*tp_repr*/
2651 0, /*tp_as_number*/
2652 0, /*tp_as_sequence*/
2653 0, /*tp_as_mapping*/
2654 0, /*tp_hash */
2655 0, /*tp_call*/
2656 0, /*tp_str*/
2657 0, /*tp_getattro*/
2658 0, /*tp_setattro*/
2659 0, /*tp_as_buffer*/
2660 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002661 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002662 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002663 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2664 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002665 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002666 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002667 0, /* tp_iter */
2668 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002669 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002670 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002671 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002672 0, /* tp_base */
2673 0, /* tp_dict */
2674 0, /* tp_descr_get */
2675 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002676 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002677 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002678 0, /* tp_alloc */
2679 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002680 0, /* tp_free */
2681 0, /* tp_is_gc */
2682 0, /* tp_bases */
2683 0, /* tp_mro */
2684 0, /* tp_cache */
2685 0, /* tp_subclasses */
2686 0, /* tp_weaklist */
2687 0, /* tp_del */
2688 0, /* tp_version_tag */
2689 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002691
2692
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002693static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002694 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002695 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2696 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2697 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2698 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2699 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2700 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2701 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002702 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002703 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002704
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002705 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002706
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002707 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002708 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002709 _IO__BUFFERED_TRUNCATE_METHODDEF
2710 _IO__BUFFERED_READ_METHODDEF
2711 _IO__BUFFERED_READ1_METHODDEF
2712 _IO__BUFFERED_READINTO_METHODDEF
2713 _IO__BUFFERED_READINTO1_METHODDEF
2714 _IO__BUFFERED_READLINE_METHODDEF
2715 _IO__BUFFERED_PEEK_METHODDEF
2716 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002717 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002718 {NULL, NULL}
2719};
2720
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002721static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002722 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002723 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002724 {NULL}
2725};
2726
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002727static PyGetSetDef bufferedrandom_getset[] = {
2728 {"closed", (getter)buffered_closed_get, NULL, NULL},
2729 {"name", (getter)buffered_name_get, NULL, NULL},
2730 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002731 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002732};
2733
2734
2735PyTypeObject PyBufferedRandom_Type = {
2736 PyVarObject_HEAD_INIT(NULL, 0)
2737 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002738 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002739 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002740 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002741 0, /*tp_print*/
2742 0, /*tp_getattr*/
2743 0, /*tp_setattr*/
2744 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002745 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002746 0, /*tp_as_number*/
2747 0, /*tp_as_sequence*/
2748 0, /*tp_as_mapping*/
2749 0, /*tp_hash */
2750 0, /*tp_call*/
2751 0, /*tp_str*/
2752 0, /*tp_getattro*/
2753 0, /*tp_setattro*/
2754 0, /*tp_as_buffer*/
2755 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002756 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002757 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002758 (traverseproc)buffered_traverse, /* tp_traverse */
2759 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002760 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002761 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002762 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002763 (iternextfunc)buffered_iternext, /* tp_iternext */
2764 bufferedrandom_methods, /* tp_methods */
2765 bufferedrandom_members, /* tp_members */
2766 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002767 0, /* tp_base */
2768 0, /*tp_dict*/
2769 0, /* tp_descr_get */
2770 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002771 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002772 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002773 0, /* tp_alloc */
2774 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002775 0, /* tp_free */
2776 0, /* tp_is_gc */
2777 0, /* tp_bases */
2778 0, /* tp_mro */
2779 0, /* tp_cache */
2780 0, /* tp_subclasses */
2781 0, /* tp_weaklist */
2782 0, /* tp_del */
2783 0, /* tp_version_tag */
2784 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002785};