blob: edc4ba5a537632aa1352f03e7e5fbe602c36bbf4 [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) \
350 (self->fast_closed_checks \
351 ? _PyFileIO_closed(self->raw) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000352 : buffered_closed(self))
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000353
354#define CHECK_CLOSED(self, error_msg) \
355 if (IS_CLOSED(self)) { \
356 PyErr_SetString(PyExc_ValueError, error_msg); \
357 return NULL; \
358 }
359
360
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000361#define VALID_READ_BUFFER(self) \
362 (self->readable && self->read_end != -1)
363
364#define VALID_WRITE_BUFFER(self) \
365 (self->writable && self->write_end != -1)
366
367#define ADJUST_POSITION(self, _new_pos) \
368 do { \
369 self->pos = _new_pos; \
370 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
371 self->read_end = self->pos; \
372 } while(0)
373
374#define READAHEAD(self) \
375 ((self->readable && VALID_READ_BUFFER(self)) \
376 ? (self->read_end - self->pos) : 0)
377
378#define RAW_OFFSET(self) \
379 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
380 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
381
382#define RAW_TELL(self) \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000383 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000384
385#define MINUS_LAST_BLOCK(self, size) \
386 (self->buffer_mask ? \
387 (size & ~self->buffer_mask) : \
388 (self->buffer_size * (size / self->buffer_size)))
389
390
391static void
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700392remove_from_linked_list(buffered *self)
393{
394 self->next->prev = self->prev;
395 self->prev->next = self->next;
396 self->prev = NULL;
397 self->next = NULL;
398}
399
400static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000401buffered_dealloc(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000402{
Antoine Pitrou796564c2013-07-30 19:59:21 +0200403 self->finalizing = 1;
Neil Schemenauer0a1ff242017-09-22 10:17:30 -0700404 if (self->next != NULL)
405 remove_from_linked_list(self);
Antoine Pitrou796564c2013-07-30 19:59:21 +0200406 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000407 return;
408 _PyObject_GC_UNTRACK(self);
409 self->ok = 0;
410 if (self->weakreflist != NULL)
411 PyObject_ClearWeakRefs((PyObject *)self);
412 Py_CLEAR(self->raw);
413 if (self->buffer) {
414 PyMem_Free(self->buffer);
415 self->buffer = NULL;
416 }
417 if (self->lock) {
418 PyThread_free_lock(self->lock);
419 self->lock = NULL;
420 }
421 Py_CLEAR(self->dict);
422 Py_TYPE(self)->tp_free((PyObject *)self);
423}
424
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200425static PyObject *
426buffered_sizeof(buffered *self, void *unused)
427{
428 Py_ssize_t res;
429
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200430 res = _PyObject_SIZE(Py_TYPE(self));
Antoine Pitrou10f0c502012-07-29 19:02:46 +0200431 if (self->buffer)
432 res += self->buffer_size;
433 return PyLong_FromSsize_t(res);
434}
435
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000436static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000437buffered_traverse(buffered *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000438{
439 Py_VISIT(self->raw);
440 Py_VISIT(self->dict);
441 return 0;
442}
443
444static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000445buffered_clear(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000446{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000447 self->ok = 0;
448 Py_CLEAR(self->raw);
449 Py_CLEAR(self->dict);
450 return 0;
451}
452
Antoine Pitroue033e062010-10-29 10:38:18 +0000453/* Because this can call arbitrary code, it shouldn't be called when
454 the refcount is 0 (that is, not directly from tp_dealloc unless
455 the refcount has been temporarily re-incremented). */
Matthias Klosebee33162010-11-16 20:07:51 +0000456static PyObject *
Antoine Pitroue033e062010-10-29 10:38:18 +0000457buffered_dealloc_warn(buffered *self, PyObject *source)
458{
459 if (self->ok && self->raw) {
460 PyObject *r;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100461 r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
462 source, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +0000463 if (r)
464 Py_DECREF(r);
465 else
466 PyErr_Clear();
467 }
468 Py_RETURN_NONE;
469}
470
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000471/*
472 * _BufferedIOMixin methods
473 * This is not a class, just a collection of methods that will be reused
474 * by BufferedReader and BufferedWriter
475 */
476
477/* Flush and close */
478
479static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000480buffered_simple_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481{
482 CHECK_INITIALIZED(self)
483 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
484}
485
486static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000487buffered_closed(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000488{
489 int closed;
490 PyObject *res;
491 CHECK_INITIALIZED_INT(self)
492 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
493 if (res == NULL)
494 return -1;
495 closed = PyObject_IsTrue(res);
496 Py_DECREF(res);
497 return closed;
498}
499
500static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000501buffered_closed_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000502{
503 CHECK_INITIALIZED(self)
504 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
505}
506
507static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000508buffered_close(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509{
Benjamin Peterson68623612012-12-20 11:53:11 -0600510 PyObject *res = NULL, *exc = NULL, *val, *tb;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511 int r;
512
513 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000514 if (!ENTER_BUFFERED(self))
515 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000516
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000517 r = buffered_closed(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000518 if (r < 0)
519 goto end;
520 if (r > 0) {
521 res = Py_None;
522 Py_INCREF(res);
523 goto end;
524 }
Antoine Pitroue033e062010-10-29 10:38:18 +0000525
Antoine Pitrou796564c2013-07-30 19:59:21 +0200526 if (self->finalizing) {
Antoine Pitroue033e062010-10-29 10:38:18 +0000527 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
528 if (r)
529 Py_DECREF(r);
530 else
531 PyErr_Clear();
532 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000533 /* flush() will most probably re-take the lock, so drop it first */
534 LEAVE_BUFFERED(self)
535 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000536 if (!ENTER_BUFFERED(self))
537 return NULL;
Benjamin Peterson68623612012-12-20 11:53:11 -0600538 if (res == NULL)
539 PyErr_Fetch(&exc, &val, &tb);
540 else
541 Py_DECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000542
543 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
544
Jesus Ceadc469452012-10-04 12:37:56 +0200545 if (self->buffer) {
546 PyMem_Free(self->buffer);
547 self->buffer = NULL;
548 }
549
Benjamin Peterson68623612012-12-20 11:53:11 -0600550 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +0300551 _PyErr_ChainExceptions(exc, val, tb);
552 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -0600553 }
554
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000555end:
556 LEAVE_BUFFERED(self)
557 return res;
558}
559
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000560/* detach */
561
562static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000563buffered_detach(buffered *self, PyObject *args)
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000564{
565 PyObject *raw, *res;
566 CHECK_INITIALIZED(self)
567 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
568 if (res == NULL)
569 return NULL;
570 Py_DECREF(res);
571 raw = self->raw;
572 self->raw = NULL;
573 self->detached = 1;
574 self->ok = 0;
575 return raw;
576}
577
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578/* Inquiries */
579
580static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000581buffered_seekable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582{
583 CHECK_INITIALIZED(self)
584 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
585}
586
587static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000588buffered_readable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589{
590 CHECK_INITIALIZED(self)
591 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
592}
593
594static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000595buffered_writable(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000596{
597 CHECK_INITIALIZED(self)
598 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
599}
600
601static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000602buffered_name_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000603{
604 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200605 return _PyObject_GetAttrId(self->raw, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000606}
607
608static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000609buffered_mode_get(buffered *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000610{
611 CHECK_INITIALIZED(self)
Martin v. Löwis767046a2011-10-14 15:35:36 +0200612 return _PyObject_GetAttrId(self->raw, &PyId_mode);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000613}
614
615/* Lower-level APIs */
616
617static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000618buffered_fileno(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619{
620 CHECK_INITIALIZED(self)
621 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
622}
623
624static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000625buffered_isatty(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000626{
627 CHECK_INITIALIZED(self)
628 return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
629}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000630
Antoine Pitrou243757e2010-11-05 21:15:39 +0000631/* Serialization */
632
633static PyObject *
634buffered_getstate(buffered *self, PyObject *args)
635{
636 PyErr_Format(PyExc_TypeError,
637 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
638 return NULL;
639}
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000640
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641/* Forward decls */
642static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100643_bufferedwriter_flush_unlocked(buffered *);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000644static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000645_bufferedreader_fill_buffer(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000647_bufferedreader_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000649_bufferedwriter_reset_buf(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000650static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +0200651_bufferedreader_peek_unlocked(buffered *self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000653_bufferedreader_read_all(buffered *self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000654static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000655_bufferedreader_read_fast(buffered *self, Py_ssize_t);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000656static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000657_bufferedreader_read_generic(buffered *self, Py_ssize_t);
Antoine Pitrou3486a982011-05-12 01:57:53 +0200658static Py_ssize_t
659_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660
661/*
662 * Helpers
663 */
664
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100665/* Sets the current error to BlockingIOError */
666static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200667_set_BlockingIOError(const char *msg, Py_ssize_t written)
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100668{
669 PyObject *err;
Victor Stinnerace47d72013-07-18 01:41:08 +0200670 PyErr_Clear();
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100671 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
672 errno, msg, written);
673 if (err)
674 PyErr_SetObject(PyExc_BlockingIOError, err);
675 Py_XDECREF(err);
676}
677
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678/* Returns the address of the `written` member if a BlockingIOError was
679 raised, NULL otherwise. The error is always re-raised. */
680static Py_ssize_t *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000681_buffered_check_blocking_error(void)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682{
683 PyObject *t, *v, *tb;
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200684 PyOSErrorObject *err;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000685
686 PyErr_Fetch(&t, &v, &tb);
687 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
688 PyErr_Restore(t, v, tb);
689 return NULL;
690 }
Antoine Pitrou6b4883d2011-10-12 02:54:14 +0200691 err = (PyOSErrorObject *) v;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000692 /* TODO: sanity check (err->written >= 0) */
693 PyErr_Restore(t, v, tb);
694 return &err->written;
695}
696
697static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000698_buffered_raw_tell(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000699{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700 Py_off_t n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000701 PyObject *res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
703 if (res == NULL)
704 return -1;
705 n = PyNumber_AsOff_t(res, PyExc_ValueError);
706 Py_DECREF(res);
707 if (n < 0) {
708 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300709 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000710 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200711 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712 return -1;
713 }
714 self->abs_pos = n;
715 return n;
716}
717
718static Py_off_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000719_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000720{
721 PyObject *res, *posobj, *whenceobj;
722 Py_off_t n;
723
724 posobj = PyLong_FromOff_t(target);
725 if (posobj == NULL)
726 return -1;
727 whenceobj = PyLong_FromLong(whence);
728 if (whenceobj == NULL) {
729 Py_DECREF(posobj);
730 return -1;
731 }
732 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
733 posobj, whenceobj, NULL);
734 Py_DECREF(posobj);
735 Py_DECREF(whenceobj);
736 if (res == NULL)
737 return -1;
738 n = PyNumber_AsOff_t(res, PyExc_ValueError);
739 Py_DECREF(res);
740 if (n < 0) {
741 if (!PyErr_Occurred())
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300742 PyErr_Format(PyExc_OSError,
Mark Dickinson1a0aaaa2009-11-24 20:54:11 +0000743 "Raw stream returned invalid position %" PY_PRIdOFF,
Antoine Pitrou3486a982011-05-12 01:57:53 +0200744 (PY_OFF_T_COMPAT)n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000745 return -1;
746 }
747 self->abs_pos = n;
748 return n;
749}
750
751static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000752_buffered_init(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000753{
754 Py_ssize_t n;
755 if (self->buffer_size <= 0) {
756 PyErr_SetString(PyExc_ValueError,
757 "buffer size must be strictly positive");
758 return -1;
759 }
760 if (self->buffer)
761 PyMem_Free(self->buffer);
762 self->buffer = PyMem_Malloc(self->buffer_size);
763 if (self->buffer == NULL) {
764 PyErr_NoMemory();
765 return -1;
766 }
Antoine Pitrouc881f152010-08-01 16:53:42 +0000767 if (self->lock)
768 PyThread_free_lock(self->lock);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000769 self->lock = PyThread_allocate_lock();
770 if (self->lock == NULL) {
771 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
772 return -1;
773 }
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000774 self->owner = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000775 /* Find out whether buffer_size is a power of 2 */
776 /* XXX is this optimization useful? */
777 for (n = self->buffer_size - 1; n & 1; n >>= 1)
778 ;
779 if (n == 0)
780 self->buffer_mask = self->buffer_size - 1;
781 else
782 self->buffer_mask = 0;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000783 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000784 PyErr_Clear();
785 return 0;
786}
787
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300788/* Return 1 if an OSError with errno == EINTR is set (and then
Antoine Pitrou707ce822011-02-25 21:24:11 +0000789 clears the error indicator), 0 otherwise.
790 Should only be called when PyErr_Occurred() is true.
791*/
Gregory P. Smith51359922012-06-23 23:55:39 -0700792int
793_PyIO_trap_eintr(void)
Antoine Pitrou707ce822011-02-25 21:24:11 +0000794{
795 static PyObject *eintr_int = NULL;
796 PyObject *typ, *val, *tb;
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300797 PyOSErrorObject *env_err;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000798
799 if (eintr_int == NULL) {
800 eintr_int = PyLong_FromLong(EINTR);
801 assert(eintr_int != NULL);
802 }
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300803 if (!PyErr_ExceptionMatches(PyExc_OSError))
Antoine Pitrou707ce822011-02-25 21:24:11 +0000804 return 0;
805 PyErr_Fetch(&typ, &val, &tb);
806 PyErr_NormalizeException(&typ, &val, &tb);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300807 env_err = (PyOSErrorObject *) val;
Antoine Pitrou707ce822011-02-25 21:24:11 +0000808 assert(env_err != NULL);
809 if (env_err->myerrno != NULL &&
810 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
811 Py_DECREF(typ);
812 Py_DECREF(val);
813 Py_XDECREF(tb);
814 return 1;
815 }
816 /* This silences any error set by PyObject_RichCompareBool() */
817 PyErr_Restore(typ, val, tb);
818 return 0;
819}
820
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000821/*
822 * Shared methods and wrappers
823 */
824
825static PyObject *
Antoine Pitroue05565e2011-08-20 14:39:23 +0200826buffered_flush_and_rewind_unlocked(buffered *self)
827{
828 PyObject *res;
829
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +0100830 res = _bufferedwriter_flush_unlocked(self);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200831 if (res == NULL)
832 return NULL;
833 Py_DECREF(res);
834
835 if (self->readable) {
836 /* Rewind the raw stream so that its position corresponds to
837 the current logical position. */
838 Py_off_t n;
839 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
840 _bufferedreader_reset_buf(self);
841 if (n == -1)
842 return NULL;
843 }
844 Py_RETURN_NONE;
845}
846
847static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000848buffered_flush(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000849{
850 PyObject *res;
851
852 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000853 CHECK_CLOSED(self, "flush of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000854
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000855 if (!ENTER_BUFFERED(self))
856 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200857 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000858 LEAVE_BUFFERED(self)
859
860 return res;
861}
862
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300863/*[clinic input]
864_io._Buffered.peek
865 size: Py_ssize_t = 0
866 /
867
868[clinic start generated code]*/
869
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000870static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300871_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
872/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000873{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000874 PyObject *res = NULL;
875
876 CHECK_INITIALIZED(self)
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300877 CHECK_CLOSED(self, "peek of closed file")
878
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000879 if (!ENTER_BUFFERED(self))
880 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000881
882 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200883 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000884 if (res == NULL)
885 goto end;
886 Py_CLEAR(res);
887 }
Victor Stinnerbc93a112011-06-01 00:01:24 +0200888 res = _bufferedreader_peek_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000889
890end:
891 LEAVE_BUFFERED(self)
892 return res;
893}
894
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300895/*[clinic input]
896_io._Buffered.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300897 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300898 /
899[clinic start generated code]*/
900
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000901static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300902_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300903/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000904{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000905 PyObject *res;
906
907 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000908 if (n < -1) {
909 PyErr_SetString(PyExc_ValueError,
Martin Panterccb2c0e2016-10-20 23:48:14 +0000910 "read length must be non-negative or -1");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000911 return NULL;
912 }
913
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000914 CHECK_CLOSED(self, "read of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000916 if (n == -1) {
917 /* The number of bytes is unspecified, read until the end of stream */
Antoine Pitrouf3b68b32010-12-03 18:41:39 +0000918 if (!ENTER_BUFFERED(self))
919 return NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000920 res = _bufferedreader_read_all(self);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000921 }
922 else {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000923 res = _bufferedreader_read_fast(self, n);
Antoine Pitroue05565e2011-08-20 14:39:23 +0200924 if (res != Py_None)
925 return res;
926 Py_DECREF(res);
927 if (!ENTER_BUFFERED(self))
928 return NULL;
929 res = _bufferedreader_read_generic(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +0000930 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000931
Antoine Pitroue05565e2011-08-20 14:39:23 +0200932 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000933 return res;
934}
935
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300936/*[clinic input]
937_io._Buffered.read1
Martin Panterccb2c0e2016-10-20 23:48:14 +0000938 size as n: Py_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300939 /
940[clinic start generated code]*/
941
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300943_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
Martin Panterccb2c0e2016-10-20 23:48:14 +0000944/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000945{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300946 Py_ssize_t have, r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000947 PyObject *res = NULL;
948
949 CHECK_INITIALIZED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950 if (n < 0) {
Martin Panterccb2c0e2016-10-20 23:48:14 +0000951 n = self->buffer_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000952 }
Berker Peksagd10d6ae2015-05-12 17:01:05 +0300953
954 CHECK_CLOSED(self, "read of closed file")
955
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000956 if (n == 0)
957 return PyBytes_FromStringAndSize(NULL, 0);
958
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 /* Return up to n bytes. If at least one byte is buffered, we
960 only return buffered bytes. Otherwise, we do one raw read. */
961
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
963 if (have > 0) {
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100964 n = Py_MIN(have, n);
965 res = _bufferedreader_read_fast(self, n);
966 assert(res != Py_None);
967 return res;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968 }
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100969 res = PyBytes_FromStringAndSize(NULL, n);
970 if (res == NULL)
971 return NULL;
972 if (!ENTER_BUFFERED(self)) {
Antoine Pitroue05565e2011-08-20 14:39:23 +0200973 Py_DECREF(res);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100974 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +0200975 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000976 _bufferedreader_reset_buf(self);
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100977 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
978 LEAVE_BUFFERED(self)
979 if (r == -1) {
980 Py_DECREF(res);
981 return NULL;
982 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983 if (r == -2)
984 r = 0;
985 if (n > r)
Antoine Pitrou56a220a2011-11-16 00:56:10 +0100986 _PyBytes_Resize(&res, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000987 return res;
988}
989
990static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992{
Antoine Pitrou3486a982011-05-12 01:57:53 +0200993 Py_ssize_t n, written = 0, remaining;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000994 PyObject *res = NULL;
995
996 CHECK_INITIALIZED(self)
Antoine Pitrou3486a982011-05-12 01:57:53 +0200997
Antoine Pitrou3486a982011-05-12 01:57:53 +0200998 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
999 if (n > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001000 if (n >= buffer->len) {
1001 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1002 self->pos += buffer->len;
1003 return PyLong_FromSsize_t(buffer->len);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001004 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001005 memcpy(buffer->buf, self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001006 self->pos += n;
1007 written = n;
1008 }
1009
1010 if (!ENTER_BUFFERED(self))
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001011 return NULL;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001012
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001013 if (self->writable) {
Antoine Pitroue8bb1a02011-08-20 14:52:04 +02001014 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001015 if (res == NULL)
1016 goto end;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001017 Py_CLEAR(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001019
1020 _bufferedreader_reset_buf(self);
1021 self->pos = 0;
1022
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001023 for (remaining = buffer->len - written;
Antoine Pitrou3486a982011-05-12 01:57:53 +02001024 remaining > 0;
1025 written += n, remaining -= n) {
1026 /* If remaining bytes is larger than internal buffer size, copy
1027 * directly into caller's buffer. */
1028 if (remaining > self->buffer_size) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001029 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001030 remaining);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001031 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001032
1033 /* In readinto1 mode, we do not want to fill the internal
1034 buffer if we already have some data to return */
1035 else if (!(readinto1 && written)) {
Antoine Pitrou3486a982011-05-12 01:57:53 +02001036 n = _bufferedreader_fill_buffer(self);
1037 if (n > 0) {
1038 if (n > remaining)
1039 n = remaining;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001040 memcpy((char *) buffer->buf + written,
Antoine Pitrou4e19e112011-05-12 02:07:00 +02001041 self->buffer + self->pos, n);
Antoine Pitrou3486a982011-05-12 01:57:53 +02001042 self->pos += n;
1043 continue; /* short circuit */
1044 }
1045 }
Benjamin Petersona96fea02014-06-22 14:17:44 -07001046 else
1047 n = 0;
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001048
Antoine Pitrou3486a982011-05-12 01:57:53 +02001049 if (n == 0 || (n == -2 && written > 0))
1050 break;
1051 if (n < 0) {
1052 if (n == -2) {
1053 Py_INCREF(Py_None);
1054 res = Py_None;
1055 }
1056 goto end;
1057 }
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001058
Benjamin Petersona96fea02014-06-22 14:17:44 -07001059 /* At most one read in readinto1 mode */
1060 if (readinto1) {
1061 written += n;
1062 break;
1063 }
Antoine Pitrou3486a982011-05-12 01:57:53 +02001064 }
1065 res = PyLong_FromSsize_t(written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001066
1067end:
Antoine Pitrou3486a982011-05-12 01:57:53 +02001068 LEAVE_BUFFERED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001069 return res;
1070}
1071
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001072/*[clinic input]
1073_io._Buffered.readinto
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001074 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001075 /
1076[clinic start generated code]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001077
1078static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001079_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001080/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
Benjamin Petersona96fea02014-06-22 14:17:44 -07001081{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001082 return _buffered_readinto_generic(self, buffer, 0);
1083}
1084
1085/*[clinic input]
1086_io._Buffered.readinto1
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001087 buffer: Py_buffer(accept={rwbuffer})
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001088 /
1089[clinic start generated code]*/
1090
1091static PyObject *
1092_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001093/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001094{
1095 return _buffered_readinto_generic(self, buffer, 1);
Benjamin Petersona96fea02014-06-22 14:17:44 -07001096}
1097
1098
1099static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001100_buffered_readline(buffered *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101{
1102 PyObject *res = NULL;
1103 PyObject *chunks = NULL;
1104 Py_ssize_t n, written = 0;
1105 const char *start, *s, *end;
1106
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001107 CHECK_CLOSED(self, "readline of closed file")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001108
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001109 /* First, try to find a line in the buffer. This can run unlocked because
1110 the calls to the C API are simple enough that they can't trigger
1111 any thread switch. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001112 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1113 if (limit >= 0 && n > limit)
1114 n = limit;
1115 start = self->buffer + self->pos;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001116 s = memchr(start, '\n', n);
1117 if (s != NULL) {
1118 res = PyBytes_FromStringAndSize(start, s - start + 1);
1119 if (res != NULL)
1120 self->pos += s - start + 1;
1121 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001122 }
1123 if (n == limit) {
1124 res = PyBytes_FromStringAndSize(start, n);
1125 if (res != NULL)
1126 self->pos += n;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001127 goto end_unlocked;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128 }
1129
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001130 if (!ENTER_BUFFERED(self))
1131 goto end_unlocked;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001132
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001133 /* Now we try to get some more from the raw stream */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001134 chunks = PyList_New(0);
1135 if (chunks == NULL)
1136 goto end;
1137 if (n > 0) {
1138 res = PyBytes_FromStringAndSize(start, n);
1139 if (res == NULL)
1140 goto end;
1141 if (PyList_Append(chunks, res) < 0) {
1142 Py_CLEAR(res);
1143 goto end;
1144 }
1145 Py_CLEAR(res);
1146 written += n;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001147 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001148 if (limit >= 0)
1149 limit -= n;
1150 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001151 if (self->writable) {
1152 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1153 if (r == NULL)
1154 goto end;
1155 Py_DECREF(r);
1156 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001157
1158 for (;;) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001159 _bufferedreader_reset_buf(self);
1160 n = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001161 if (n == -1)
1162 goto end;
1163 if (n <= 0)
1164 break;
1165 if (limit >= 0 && n > limit)
1166 n = limit;
1167 start = self->buffer;
1168 end = start + n;
1169 s = start;
1170 while (s < end) {
1171 if (*s++ == '\n') {
1172 res = PyBytes_FromStringAndSize(start, s - start);
1173 if (res == NULL)
1174 goto end;
1175 self->pos = s - start;
1176 goto found;
1177 }
1178 }
1179 res = PyBytes_FromStringAndSize(start, n);
1180 if (res == NULL)
1181 goto end;
1182 if (n == limit) {
1183 self->pos = n;
1184 break;
1185 }
1186 if (PyList_Append(chunks, res) < 0) {
1187 Py_CLEAR(res);
1188 goto end;
1189 }
1190 Py_CLEAR(res);
1191 written += n;
1192 if (limit >= 0)
1193 limit -= n;
1194 }
1195found:
1196 if (res != NULL && PyList_Append(chunks, res) < 0) {
1197 Py_CLEAR(res);
1198 goto end;
1199 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001200 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201
1202end:
1203 LEAVE_BUFFERED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001204end_unlocked:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001205 Py_XDECREF(chunks);
1206 return res;
1207}
1208
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001209/*[clinic input]
1210_io._Buffered.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001211 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001212 /
1213[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001214
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001215static PyObject *
1216_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001217/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001218{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001219 CHECK_INITIALIZED(self)
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001220 return _buffered_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001221}
1222
1223
1224static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001225buffered_tell(buffered *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001226{
1227 Py_off_t pos;
1228
1229 CHECK_INITIALIZED(self)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001230 pos = _buffered_raw_tell(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001231 if (pos == -1)
1232 return NULL;
1233 pos -= RAW_OFFSET(self);
1234 /* TODO: sanity check (pos >= 0) */
1235 return PyLong_FromOff_t(pos);
1236}
1237
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001238/*[clinic input]
1239_io._Buffered.seek
1240 target as targetobj: object
1241 whence: int = 0
1242 /
1243[clinic start generated code]*/
1244
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001245static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001246_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1247/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001248{
1249 Py_off_t target, n;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001250 PyObject *res = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001251
1252 CHECK_INITIALIZED(self)
Jesus Cea94363612012-06-22 18:32:07 +02001253
1254 /* Do some error checking instead of trusting OS 'seek()'
1255 ** error detection, just in case.
1256 */
1257 if ((whence < 0 || whence >2)
1258#ifdef SEEK_HOLE
1259 && (whence != SEEK_HOLE)
1260#endif
1261#ifdef SEEK_DATA
1262 && (whence != SEEK_DATA)
1263#endif
1264 ) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001265 PyErr_Format(PyExc_ValueError,
Jesus Cea94363612012-06-22 18:32:07 +02001266 "whence value %d unsupported", whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001267 return NULL;
1268 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001269
1270 CHECK_CLOSED(self, "seek of closed file")
1271
Antoine Pitrou1e44fec2011-10-04 12:26:20 +02001272 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1273 return NULL;
1274
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1276 if (target == -1 && PyErr_Occurred())
1277 return NULL;
1278
Jesus Cea94363612012-06-22 18:32:07 +02001279 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1280 buffer. Other whence values must be managed without this optimization.
1281 Some Operating Systems can provide additional values, like
1282 SEEK_HOLE/SEEK_DATA. */
1283 if (((whence == 0) || (whence == 1)) && self->readable) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001284 Py_off_t current, avail;
1285 /* Check if seeking leaves us inside the current buffer,
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001286 so as to return quickly if possible. Also, we needn't take the
1287 lock in this fast path.
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 Don't know how to do that when whence == 2, though. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001289 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1290 state at this point. */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001291 current = RAW_TELL(self);
1292 avail = READAHEAD(self);
1293 if (avail > 0) {
1294 Py_off_t offset;
1295 if (whence == 0)
1296 offset = target - (current - RAW_OFFSET(self));
1297 else
1298 offset = target;
1299 if (offset >= -self->pos && offset <= avail) {
1300 self->pos += offset;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001301 return PyLong_FromOff_t(current - avail + offset);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001302 }
1303 }
1304 }
1305
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001306 if (!ENTER_BUFFERED(self))
1307 return NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001308
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001309 /* Fallback: invoke raw seek() method and clear buffer */
1310 if (self->writable) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001311 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001312 if (res == NULL)
1313 goto end;
1314 Py_CLEAR(res);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001315 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001316 }
1317
1318 /* TODO: align on block boundary and read buffer if needed? */
1319 if (whence == 1)
1320 target -= RAW_OFFSET(self);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001321 n = _buffered_raw_seek(self, target, whence);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001322 if (n == -1)
1323 goto end;
1324 self->raw_pos = -1;
1325 res = PyLong_FromOff_t(n);
1326 if (res != NULL && self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001327 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001328
1329end:
1330 LEAVE_BUFFERED(self)
1331 return res;
1332}
1333
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001334/*[clinic input]
1335_io._Buffered.truncate
1336 pos: object = None
1337 /
1338[clinic start generated code]*/
1339
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001341_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1342/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001344 PyObject *res = NULL;
1345
1346 CHECK_INITIALIZED(self)
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001347 if (!ENTER_BUFFERED(self))
1348 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349
1350 if (self->writable) {
Antoine Pitroue05565e2011-08-20 14:39:23 +02001351 res = buffered_flush_and_rewind_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001352 if (res == NULL)
1353 goto end;
1354 Py_CLEAR(res);
1355 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001356 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1357 if (res == NULL)
1358 goto end;
1359 /* Reset cached position */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001360 if (_buffered_raw_tell(self) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361 PyErr_Clear();
1362
1363end:
1364 LEAVE_BUFFERED(self)
1365 return res;
1366}
1367
1368static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001369buffered_iternext(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001370{
1371 PyObject *line;
1372 PyTypeObject *tp;
1373
1374 CHECK_INITIALIZED(self);
1375
1376 tp = Py_TYPE(self);
1377 if (tp == &PyBufferedReader_Type ||
1378 tp == &PyBufferedRandom_Type) {
1379 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001380 line = _buffered_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381 }
1382 else {
1383 line = PyObject_CallMethodObjArgs((PyObject *)self,
1384 _PyIO_str_readline, NULL);
1385 if (line && !PyBytes_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001386 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001387 "readline() should have returned a bytes object, "
1388 "not '%.200s'", Py_TYPE(line)->tp_name);
1389 Py_DECREF(line);
1390 return NULL;
1391 }
1392 }
1393
1394 if (line == NULL)
1395 return NULL;
1396
1397 if (PyBytes_GET_SIZE(line) == 0) {
1398 /* Reached EOF or would have blocked */
1399 Py_DECREF(line);
1400 return NULL;
1401 }
1402
1403 return line;
1404}
1405
Antoine Pitrou716c4442009-05-23 19:04:03 +00001406static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001407buffered_repr(buffered *self)
Antoine Pitrou716c4442009-05-23 19:04:03 +00001408{
1409 PyObject *nameobj, *res;
1410
Martin v. Löwis767046a2011-10-14 15:35:36 +02001411 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00001412 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001413 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00001414 PyErr_Clear();
1415 else
1416 return NULL;
1417 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1418 }
1419 else {
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02001420 int status = Py_ReprEnter((PyObject *)self);
1421 res = NULL;
1422 if (status == 0) {
1423 res = PyUnicode_FromFormat("<%s name=%R>",
1424 Py_TYPE(self)->tp_name, nameobj);
1425 Py_ReprLeave((PyObject *)self);
1426 }
1427 else if (status > 0) {
1428 PyErr_Format(PyExc_RuntimeError,
1429 "reentrant call inside %s.__repr__",
1430 Py_TYPE(self)->tp_name);
1431 }
Antoine Pitrou716c4442009-05-23 19:04:03 +00001432 Py_DECREF(nameobj);
1433 }
1434 return res;
1435}
1436
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437/*
1438 * class BufferedReader
1439 */
1440
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001441static void _bufferedreader_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001442{
1443 self->read_end = -1;
1444}
1445
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001446/*[clinic input]
1447_io.BufferedReader.__init__
1448 raw: object
1449 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001450
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001451Create a new buffered reader using the given readable raw IO object.
1452[clinic start generated code]*/
1453
1454static int
1455_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1456 Py_ssize_t buffer_size)
1457/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1458{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001459 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001460 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001461
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001462 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001463 return -1;
1464
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001466 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001467 self->buffer_size = buffer_size;
1468 self->readable = 1;
1469 self->writable = 0;
1470
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001471 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001472 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001473 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001474
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001475 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1476 Py_TYPE(raw) == &PyFileIO_Type);
1477
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001478 self->ok = 1;
1479 return 0;
1480}
1481
1482static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001483_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484{
1485 Py_buffer buf;
1486 PyObject *memobj, *res;
1487 Py_ssize_t n;
1488 /* NOTE: the buffer needn't be released as its object is NULL. */
1489 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1490 return -1;
1491 memobj = PyMemoryView_FromBuffer(&buf);
1492 if (memobj == NULL)
1493 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001494 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1495 occurs so we needn't do it ourselves.
1496 We then retry reading, ignoring the signal if no handler has
1497 raised (see issue #10956).
1498 */
1499 do {
1500 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
Gregory P. Smith51359922012-06-23 23:55:39 -07001501 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001502 Py_DECREF(memobj);
1503 if (res == NULL)
1504 return -1;
1505 if (res == Py_None) {
1506 /* Non-blocking stream would have blocked. Special return code! */
1507 Py_DECREF(res);
1508 return -2;
1509 }
1510 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1511 Py_DECREF(res);
1512 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001513 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001514 "raw readinto() returned invalid length %zd "
1515 "(should have been between 0 and %zd)", n, len);
1516 return -1;
1517 }
1518 if (n > 0 && self->abs_pos != -1)
1519 self->abs_pos += n;
1520 return n;
1521}
1522
1523static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001524_bufferedreader_fill_buffer(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001525{
1526 Py_ssize_t start, len, n;
1527 if (VALID_READ_BUFFER(self))
1528 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1529 else
1530 start = 0;
1531 len = self->buffer_size - start;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001532 n = _bufferedreader_raw_read(self, self->buffer + start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001533 if (n <= 0)
1534 return n;
1535 self->read_end = start + n;
1536 self->raw_pos = start + n;
1537 return n;
1538}
1539
1540static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001541_bufferedreader_read_all(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001542{
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001543 Py_ssize_t current_size;
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001544 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001545
1546 /* First copy what we have in the current buffer. */
1547 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1548 if (current_size) {
1549 data = PyBytes_FromStringAndSize(
1550 self->buffer + self->pos, current_size);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001551 if (data == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001552 return NULL;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001553 self->pos += current_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001554 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001555 /* We're going past the buffer's bounds, flush it */
1556 if (self->writable) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001557 tmp = buffered_flush_and_rewind_unlocked(self);
1558 if (tmp == NULL)
1559 goto cleanup;
1560 Py_CLEAR(tmp);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001561 }
Antoine Pitroue05565e2011-08-20 14:39:23 +02001562 _bufferedreader_reset_buf(self);
Victor Stinnerb57f1082011-05-26 00:19:38 +02001563
1564 if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001565 tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1566 if (tmp == NULL)
1567 goto cleanup;
1568 if (tmp != Py_None && !PyBytes_Check(tmp)) {
Victor Stinnerb57f1082011-05-26 00:19:38 +02001569 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001570 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001571 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001572 if (tmp == Py_None) {
1573 if (current_size == 0) {
1574 res = Py_None;
1575 goto cleanup;
1576 } else {
1577 res = data;
1578 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001579 }
1580 }
1581 else if (current_size) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001582 PyBytes_Concat(&data, tmp);
1583 res = data;
1584 goto cleanup;
1585 }
1586 else {
1587 res = tmp;
1588 goto cleanup;
1589 }
Victor Stinnerb57f1082011-05-26 00:19:38 +02001590 }
1591
1592 chunks = PyList_New(0);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001593 if (chunks == NULL)
1594 goto cleanup;
Victor Stinnerb57f1082011-05-26 00:19:38 +02001595
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001596 while (1) {
1597 if (data) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001598 if (PyList_Append(chunks, data) < 0)
1599 goto cleanup;
1600 Py_CLEAR(data);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001601 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001602
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001603 /* Read until EOF or until read() would block. */
1604 data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001605 if (data == NULL)
1606 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001607 if (data != Py_None && !PyBytes_Check(data)) {
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001608 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001609 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001610 }
1611 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1612 if (current_size == 0) {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001613 res = data;
1614 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001615 }
1616 else {
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001617 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1618 res = tmp;
1619 goto cleanup;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001620 }
1621 }
1622 current_size += PyBytes_GET_SIZE(data);
1623 if (self->abs_pos != -1)
1624 self->abs_pos += PyBytes_GET_SIZE(data);
1625 }
Richard Oudkerk9ad51ec2013-07-15 16:05:22 +01001626cleanup:
1627 /* res is either NULL or a borrowed ref */
1628 Py_XINCREF(res);
1629 Py_XDECREF(data);
1630 Py_XDECREF(tmp);
1631 Py_XDECREF(chunks);
1632 return res;
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001633}
1634
1635/* Read n bytes from the buffer if it can, otherwise return None.
1636 This function is simple enough that it can run unlocked. */
1637static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001638_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001639{
1640 Py_ssize_t current_size;
1641
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001642 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1643 if (n <= current_size) {
1644 /* Fast path: the data to read is fully buffered. */
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001645 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1646 if (res != NULL)
1647 self->pos += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001648 return res;
1649 }
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001650 Py_RETURN_NONE;
1651}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001652
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001653/* Generic read function: read from the stream until enough bytes are read,
1654 * or until an EOF occurs or until read() would block.
1655 */
1656static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001657_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001658{
1659 PyObject *res = NULL;
1660 Py_ssize_t current_size, remaining, written;
1661 char *out;
1662
1663 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1664 if (n <= current_size)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001665 return _bufferedreader_read_fast(self, n);
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001666
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001667 res = PyBytes_FromStringAndSize(NULL, n);
1668 if (res == NULL)
1669 goto error;
1670 out = PyBytes_AS_STRING(res);
1671 remaining = n;
1672 written = 0;
1673 if (current_size > 0) {
1674 memcpy(out, self->buffer + self->pos, current_size);
1675 remaining -= current_size;
1676 written += current_size;
Antoine Pitroue05565e2011-08-20 14:39:23 +02001677 self->pos += current_size;
1678 }
1679 /* Flush the write buffer if necessary */
1680 if (self->writable) {
1681 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1682 if (r == NULL)
1683 goto error;
1684 Py_DECREF(r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001686 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001687 while (remaining > 0) {
1688 /* We want to read a whole block at the end into buffer.
1689 If we had readv() we could do this in one pass. */
1690 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1691 if (r == 0)
1692 break;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001693 r = _bufferedreader_raw_read(self, out + written, r);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001694 if (r == -1)
1695 goto error;
1696 if (r == 0 || r == -2) {
1697 /* EOF occurred or read() would block. */
1698 if (r == 0 || written > 0) {
1699 if (_PyBytes_Resize(&res, written))
1700 goto error;
1701 return res;
1702 }
1703 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001704 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001705 }
1706 remaining -= r;
1707 written += r;
1708 }
1709 assert(remaining <= self->buffer_size);
1710 self->pos = 0;
1711 self->raw_pos = 0;
1712 self->read_end = 0;
Antoine Pitrou32cfede2010-08-11 13:31:33 +00001713 /* NOTE: when the read is satisfied, we avoid issuing any additional
1714 reads, which could block indefinitely (e.g. on a socket).
1715 See issue #9550. */
1716 while (remaining > 0 && self->read_end < self->buffer_size) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001717 Py_ssize_t r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001718 if (r == -1)
1719 goto error;
1720 if (r == 0 || r == -2) {
1721 /* EOF occurred or read() would block. */
1722 if (r == 0 || written > 0) {
1723 if (_PyBytes_Resize(&res, written))
1724 goto error;
1725 return res;
1726 }
1727 Py_DECREF(res);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001728 Py_RETURN_NONE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001729 }
1730 if (remaining > r) {
1731 memcpy(out + written, self->buffer + self->pos, r);
1732 written += r;
1733 self->pos += r;
1734 remaining -= r;
1735 }
1736 else if (remaining > 0) {
1737 memcpy(out + written, self->buffer + self->pos, remaining);
1738 written += remaining;
1739 self->pos += remaining;
1740 remaining = 0;
1741 }
1742 if (remaining == 0)
1743 break;
1744 }
1745
1746 return res;
1747
1748error:
1749 Py_XDECREF(res);
1750 return NULL;
1751}
1752
1753static PyObject *
Victor Stinnerbc93a112011-06-01 00:01:24 +02001754_bufferedreader_peek_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001755{
1756 Py_ssize_t have, r;
1757
1758 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1759 /* Constraints:
1760 1. we don't want to advance the file position.
1761 2. we don't want to lose block alignment, so we can't shift the buffer
1762 to make some place.
1763 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1764 */
1765 if (have > 0) {
1766 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1767 }
1768
1769 /* Fill the buffer from the raw stream, and copy it to the result. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001770 _bufferedreader_reset_buf(self);
1771 r = _bufferedreader_fill_buffer(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001772 if (r == -1)
1773 return NULL;
1774 if (r == -2)
1775 r = 0;
1776 self->pos = 0;
1777 return PyBytes_FromStringAndSize(self->buffer, r);
1778}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779
1780
Benjamin Peterson59406a92009-03-26 17:10:29 +00001781
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001782/*
1783 * class BufferedWriter
1784 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001785static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001786_bufferedwriter_reset_buf(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001787{
1788 self->write_pos = 0;
1789 self->write_end = -1;
1790}
1791
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001792/*[clinic input]
1793_io.BufferedWriter.__init__
1794 raw: object
1795 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001796
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001797A buffer for a writeable sequential RawIO object.
1798
1799The constructor creates a BufferedWriter for the given writeable raw
1800stream. If the buffer_size is not given, it defaults to
1801DEFAULT_BUFFER_SIZE.
1802[clinic start generated code]*/
1803
1804static int
1805_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1806 Py_ssize_t buffer_size)
1807/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1808{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001810 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001812 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813 return -1;
1814
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001815 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03001816 Py_XSETREF(self->raw, raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001817 self->readable = 0;
1818 self->writable = 1;
1819
1820 self->buffer_size = buffer_size;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001821 if (_buffered_init(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001822 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001823 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001824 self->pos = 0;
1825
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001826 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1827 Py_TYPE(raw) == &PyFileIO_Type);
1828
Neil Schemenauer0a1ff242017-09-22 10:17:30 -07001829 if (self->next == NULL) {
1830 self->prev = &buffer_list_end;
1831 self->next = buffer_list_end.next;
1832 buffer_list_end.next->prev = self;
1833 buffer_list_end.next = self;
1834 }
1835
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001836 self->ok = 1;
1837 return 0;
1838}
1839
Neil Schemenauer0a1ff242017-09-22 10:17:30 -07001840/*
1841* Ensure all buffered writers are flushed before proceeding with
1842* normal shutdown. Otherwise, if the underlying file objects get
1843* finalized before the buffered writer wrapping it then any buffered
1844* data will be lost.
1845*/
1846void _PyIO_atexit_flush(void)
1847{
1848 while (buffer_list_end.next != &buffer_list_end) {
1849 buffered *buf = buffer_list_end.next;
1850 remove_from_linked_list(buf);
1851 if (buf->ok && !buf->finalizing) {
1852 /* good state and not finalizing */
1853 Py_INCREF(buf);
1854 buffered_flush(buf, NULL);
1855 Py_DECREF(buf);
1856 PyErr_Clear();
1857 }
1858 }
1859}
1860
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001861static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001862_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863{
1864 Py_buffer buf;
1865 PyObject *memobj, *res;
1866 Py_ssize_t n;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001867 int errnum;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001868 /* NOTE: the buffer needn't be released as its object is NULL. */
1869 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1870 return -1;
1871 memobj = PyMemoryView_FromBuffer(&buf);
1872 if (memobj == NULL)
1873 return -1;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001874 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1875 occurs so we needn't do it ourselves.
1876 We then retry writing, ignoring the signal if no handler has
1877 raised (see issue #10956).
1878 */
1879 do {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001880 errno = 0;
Antoine Pitrou707ce822011-02-25 21:24:11 +00001881 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001882 errnum = errno;
Gregory P. Smith51359922012-06-23 23:55:39 -07001883 } while (res == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001884 Py_DECREF(memobj);
1885 if (res == NULL)
1886 return -1;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001887 if (res == Py_None) {
1888 /* Non-blocking stream would have blocked. Special return code!
1889 Being paranoid we reset errno in case it is changed by code
1890 triggered by a decref. errno is used by _set_BlockingIOError(). */
1891 Py_DECREF(res);
1892 errno = errnum;
1893 return -2;
1894 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001895 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1896 Py_DECREF(res);
1897 if (n < 0 || n > len) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001898 PyErr_Format(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001899 "raw write() returned invalid length %zd "
1900 "(should have been between 0 and %zd)", n, len);
1901 return -1;
1902 }
1903 if (n > 0 && self->abs_pos != -1)
1904 self->abs_pos += n;
1905 return n;
1906}
1907
1908/* `restore_pos` is 1 if we need to restore the raw stream position at
1909 the end, 0 otherwise. */
1910static PyObject *
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001911_bufferedwriter_flush_unlocked(buffered *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912{
1913 Py_ssize_t written = 0;
1914 Py_off_t n, rewind;
1915
1916 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1917 goto end;
1918 /* First, rewind */
1919 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1920 if (rewind != 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001921 n = _buffered_raw_seek(self, -rewind, 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001922 if (n < 0) {
1923 goto error;
1924 }
1925 self->raw_pos -= rewind;
1926 }
1927 while (self->write_pos < self->write_end) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001928 n = _bufferedwriter_raw_write(self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001929 self->buffer + self->write_pos,
1930 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1931 Py_off_t, Py_ssize_t));
1932 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01001933 goto error;
1934 }
1935 else if (n == -2) {
1936 _set_BlockingIOError("write could not complete without blocking",
1937 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001938 goto error;
1939 }
1940 self->write_pos += n;
1941 self->raw_pos = self->write_pos;
1942 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
Antoine Pitroub46b9d52010-08-21 19:09:32 +00001943 /* Partial writes can return successfully when interrupted by a
1944 signal (see write(2)). We must run signal handlers before
1945 blocking another time, possibly indefinitely. */
1946 if (PyErr_CheckSignals() < 0)
1947 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948 }
1949
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001950 _bufferedwriter_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951
1952end:
1953 Py_RETURN_NONE;
1954
1955error:
1956 return NULL;
1957}
1958
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001959/*[clinic input]
1960_io.BufferedWriter.write
1961 buffer: Py_buffer
1962 /
1963[clinic start generated code]*/
1964
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001965static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001966_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1967/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001968{
1969 PyObject *res = NULL;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00001970 Py_ssize_t written, avail, remaining;
1971 Py_off_t offset;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001972
1973 CHECK_INITIALIZED(self)
Antoine Pitrou711af3a2009-04-11 15:39:24 +00001974 if (IS_CLOSED(self)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001975 PyErr_SetString(PyExc_ValueError, "write to closed file");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976 return NULL;
1977 }
1978
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001979 if (!ENTER_BUFFERED(self))
Antoine Pitrouf3b68b32010-12-03 18:41:39 +00001980 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981
1982 /* Fast path: the data to write can be fully buffered. */
1983 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1984 self->pos = 0;
1985 self->raw_pos = 0;
1986 }
1987 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001988 if (buffer->len <= avail) {
1989 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
Antoine Pitrou7c404892011-05-13 00:13:33 +02001990 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001991 self->write_pos = self->pos;
1992 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001993 ADJUST_POSITION(self, self->pos + buffer->len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001994 if (self->pos > self->write_end)
1995 self->write_end = self->pos;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001996 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001997 goto end;
1998 }
1999
2000 /* First write the current buffer */
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002001 res = _bufferedwriter_flush_unlocked(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002002 if (res == NULL) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002003 Py_ssize_t *w = _buffered_check_blocking_error();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 if (w == NULL)
2005 goto error;
2006 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002007 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002008 /* Make some place by shifting the buffer. */
2009 assert(VALID_WRITE_BUFFER(self));
2010 memmove(self->buffer, self->buffer + self->write_pos,
2011 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
2012 Py_off_t, Py_ssize_t));
2013 self->write_end -= self->write_pos;
2014 self->raw_pos -= self->write_pos;
2015 self->pos -= self->write_pos;
2016 self->write_pos = 0;
2017 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
2018 Py_off_t, Py_ssize_t);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002019 if (buffer->len <= avail) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002020 /* Everything can be buffered */
2021 PyErr_Clear();
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002022 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
2023 self->write_end += buffer->len;
2024 self->pos += buffer->len;
2025 written = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 goto end;
2027 }
2028 /* Buffer as much as possible. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002029 memcpy(self->buffer + self->write_end, buffer->buf, avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002030 self->write_end += avail;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002031 self->pos += avail;
2032 /* XXX Modifying the existing exception e using the pointer w
2033 will change e.characters_written but not e.args[2].
2034 Therefore we just replace with a new error. */
2035 _set_BlockingIOError("write could not complete without blocking",
2036 avail);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002037 goto error;
2038 }
2039 Py_CLEAR(res);
2040
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002041 /* Adjust the raw stream position if it is away from the logical stream
2042 position. This happens if the read buffer has been filled but not
2043 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2044 the raw stream by itself).
2045 Fixes issue #6629.
2046 */
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002047 offset = RAW_OFFSET(self);
2048 if (offset != 0) {
2049 if (_buffered_raw_seek(self, -offset, 1) < 0)
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002050 goto error;
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002051 self->raw_pos -= offset;
Antoine Pitroua0ceb732009-08-06 20:29:56 +00002052 }
2053
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 /* Then write buf itself. At this point the buffer has been emptied. */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002055 remaining = buffer->len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 written = 0;
2057 while (remaining > self->buffer_size) {
Amaury Forgeot d'Arce1b60d42009-10-05 21:09:00 +00002058 Py_ssize_t n = _bufferedwriter_raw_write(
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002059 self, (char *) buffer->buf + written, buffer->len - written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060 if (n == -1) {
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002061 goto error;
2062 } else if (n == -2) {
2063 /* Write failed because raw file is non-blocking */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064 if (remaining > self->buffer_size) {
2065 /* Can't buffer everything, still buffer as much as possible */
2066 memcpy(self->buffer,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002067 (char *) buffer->buf + written, self->buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068 self->raw_pos = 0;
2069 ADJUST_POSITION(self, self->buffer_size);
2070 self->write_end = self->buffer_size;
Antoine Pitrou58fcf9f2011-11-21 20:16:44 +01002071 written += self->buffer_size;
2072 _set_BlockingIOError("write could not complete without "
2073 "blocking", written);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074 goto error;
2075 }
2076 PyErr_Clear();
2077 break;
2078 }
2079 written += n;
2080 remaining -= n;
Antoine Pitroub46b9d52010-08-21 19:09:32 +00002081 /* Partial writes can return successfully when interrupted by a
2082 signal (see write(2)). We must run signal handlers before
2083 blocking another time, possibly indefinitely. */
2084 if (PyErr_CheckSignals() < 0)
2085 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002086 }
2087 if (self->readable)
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002088 _bufferedreader_reset_buf(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002089 if (remaining > 0) {
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002090 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002091 written += remaining;
2092 }
2093 self->write_pos = 0;
2094 /* TODO: sanity check (remaining >= 0) */
2095 self->write_end = remaining;
2096 ADJUST_POSITION(self, remaining);
2097 self->raw_pos = 0;
2098
2099end:
2100 res = PyLong_FromSsize_t(written);
2101
2102error:
2103 LEAVE_BUFFERED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002104 return res;
2105}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106
2107
2108
2109/*
2110 * BufferedRWPair
2111 */
2112
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002113/* XXX The usefulness of this (compared to having two separate IO objects) is
2114 * questionable.
2115 */
2116
2117typedef struct {
2118 PyObject_HEAD
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002119 buffered *reader;
2120 buffered *writer;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002121 PyObject *dict;
2122 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002123} rwpair;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002125/*[clinic input]
2126_io.BufferedRWPair.__init__
2127 reader: object
2128 writer: object
2129 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2130 /
2131
2132A buffered reader and writer object together.
2133
2134A buffered reader object and buffered writer object put together to
2135form a sequential IO object that can read and write. This is typically
2136used with a socket or two-way pipe.
2137
2138reader and writer are RawIOBase objects that are readable and
2139writeable respectively. If the buffer_size is omitted it defaults to
2140DEFAULT_BUFFER_SIZE.
2141[clinic start generated code]*/
2142
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002144_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2145 PyObject *writer, Py_ssize_t buffer_size)
2146/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002147{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002148 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149 return -1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002150 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002151 return -1;
2152
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002153 self->reader = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002154 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002155 if (self->reader == NULL)
2156 return -1;
2157
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002158 self->writer = (buffered *) PyObject_CallFunction(
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002159 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160 if (self->writer == NULL) {
2161 Py_CLEAR(self->reader);
2162 return -1;
2163 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002164
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165 return 0;
2166}
2167
2168static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002169bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170{
2171 Py_VISIT(self->dict);
2172 return 0;
2173}
2174
2175static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002176bufferedrwpair_clear(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002177{
2178 Py_CLEAR(self->reader);
2179 Py_CLEAR(self->writer);
2180 Py_CLEAR(self->dict);
2181 return 0;
2182}
2183
2184static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002185bufferedrwpair_dealloc(rwpair *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002186{
2187 _PyObject_GC_UNTRACK(self);
Benjamin Petersonbbd0a322014-09-29 22:46:57 -04002188 if (self->weakreflist != NULL)
2189 PyObject_ClearWeakRefs((PyObject *)self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002190 Py_CLEAR(self->reader);
2191 Py_CLEAR(self->writer);
2192 Py_CLEAR(self->dict);
2193 Py_TYPE(self)->tp_free((PyObject *) self);
2194}
2195
2196static PyObject *
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002197_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002198{
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002199 PyObject *func, *ret;
2200 if (self == NULL) {
2201 PyErr_SetString(PyExc_ValueError,
2202 "I/O operation on uninitialized object");
2203 return NULL;
2204 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205
Serhiy Storchaka61e24932014-02-12 10:52:35 +02002206 func = _PyObject_GetAttrId((PyObject *)self, name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002207 if (func == NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002208 PyErr_SetString(PyExc_AttributeError, name->string);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209 return NULL;
2210 }
2211
2212 ret = PyObject_CallObject(func, args);
2213 Py_DECREF(func);
2214 return ret;
2215}
2216
2217static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002218bufferedrwpair_read(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002219{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002220 return _forward_call(self->reader, &PyId_read, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002221}
2222
2223static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224bufferedrwpair_peek(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002226 return _forward_call(self->reader, &PyId_peek, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002227}
2228
2229static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002230bufferedrwpair_read1(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002231{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002232 return _forward_call(self->reader, &PyId_read1, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002233}
2234
2235static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002236bufferedrwpair_readinto(rwpair *self, PyObject *args)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002237{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002238 return _forward_call(self->reader, &PyId_readinto, args);
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002239}
2240
2241static PyObject *
Benjamin Petersona96fea02014-06-22 14:17:44 -07002242bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2243{
2244 return _forward_call(self->reader, &PyId_readinto1, args);
2245}
2246
2247static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002248bufferedrwpair_write(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002250 return _forward_call(self->writer, &PyId_write, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251}
2252
2253static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002254bufferedrwpair_flush(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002256 return _forward_call(self->writer, &PyId_flush, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002257}
2258
2259static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002260bufferedrwpair_readable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002261{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002262 return _forward_call(self->reader, &PyId_readable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263}
2264
2265static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002266bufferedrwpair_writable(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002268 return _forward_call(self->writer, &PyId_writable, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002269}
2270
2271static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002272bufferedrwpair_close(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002273{
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002274 PyObject *exc = NULL, *val, *tb;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002275 PyObject *ret = _forward_call(self->writer, &PyId_close, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276 if (ret == NULL)
Serhiy Storchaka7665be62015-03-24 23:21:57 +02002277 PyErr_Fetch(&exc, &val, &tb);
2278 else
2279 Py_DECREF(ret);
2280 ret = _forward_call(self->reader, &PyId_close, args);
2281 if (exc != NULL) {
2282 _PyErr_ChainExceptions(exc, val, tb);
2283 Py_CLEAR(ret);
2284 }
2285 return ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002286}
2287
2288static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002289bufferedrwpair_isatty(rwpair *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290{
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002291 PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002292
2293 if (ret != Py_False) {
2294 /* either True or exception */
2295 return ret;
2296 }
2297 Py_DECREF(ret);
2298
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002299 return _forward_call(self->reader, &PyId_isatty, args);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300}
2301
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002302static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002303bufferedrwpair_closed_get(rwpair *self, void *context)
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002304{
Charles-François Natali42c28cd2011-10-05 19:53:43 +02002305 if (self->writer == NULL) {
2306 PyErr_SetString(PyExc_RuntimeError,
2307 "the BufferedRWPair object is being garbage-collected");
2308 return NULL;
2309 }
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002310 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2311}
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002312
2313
2314
2315/*
2316 * BufferedRandom
2317 */
2318
2319/*[clinic input]
2320_io.BufferedRandom.__init__
2321 raw: object
2322 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2323
2324A buffered interface to random access streams.
2325
2326The constructor creates a reader and writer for a seekable stream,
2327raw, given in the first argument. If the buffer_size is omitted it
2328defaults to DEFAULT_BUFFER_SIZE.
2329[clinic start generated code]*/
2330
2331static int
2332_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2333 Py_ssize_t buffer_size)
2334/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2335{
2336 self->ok = 0;
2337 self->detached = 0;
2338
2339 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2340 return -1;
2341 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2342 return -1;
2343 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2344 return -1;
2345
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002346 Py_INCREF(raw);
Serhiy Storchaka48842712016-04-06 09:45:48 +03002347 Py_XSETREF(self->raw, raw);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002348 self->buffer_size = buffer_size;
2349 self->readable = 1;
2350 self->writable = 1;
2351
2352 if (_buffered_init(self) < 0)
2353 return -1;
2354 _bufferedreader_reset_buf(self);
2355 _bufferedwriter_reset_buf(self);
2356 self->pos = 0;
2357
2358 self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2359 Py_TYPE(raw) == &PyFileIO_Type);
2360
2361 self->ok = 1;
2362 return 0;
2363}
2364
2365#include "clinic/bufferedio.c.h"
2366
2367
2368static PyMethodDef bufferediobase_methods[] = {
2369 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2370 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2371 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2372 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2373 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2374 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2375 {NULL, NULL}
2376};
2377
2378PyTypeObject PyBufferedIOBase_Type = {
2379 PyVarObject_HEAD_INIT(NULL, 0)
2380 "_io._BufferedIOBase", /*tp_name*/
2381 0, /*tp_basicsize*/
2382 0, /*tp_itemsize*/
2383 0, /*tp_dealloc*/
2384 0, /*tp_print*/
2385 0, /*tp_getattr*/
2386 0, /*tp_setattr*/
2387 0, /*tp_compare */
2388 0, /*tp_repr*/
2389 0, /*tp_as_number*/
2390 0, /*tp_as_sequence*/
2391 0, /*tp_as_mapping*/
2392 0, /*tp_hash */
2393 0, /*tp_call*/
2394 0, /*tp_str*/
2395 0, /*tp_getattro*/
2396 0, /*tp_setattro*/
2397 0, /*tp_as_buffer*/
2398 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2399 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2400 bufferediobase_doc, /* tp_doc */
2401 0, /* tp_traverse */
2402 0, /* tp_clear */
2403 0, /* tp_richcompare */
2404 0, /* tp_weaklistoffset */
2405 0, /* tp_iter */
2406 0, /* tp_iternext */
2407 bufferediobase_methods, /* tp_methods */
2408 0, /* tp_members */
2409 0, /* tp_getset */
2410 &PyIOBase_Type, /* tp_base */
2411 0, /* tp_dict */
2412 0, /* tp_descr_get */
2413 0, /* tp_descr_set */
2414 0, /* tp_dictoffset */
2415 0, /* tp_init */
2416 0, /* tp_alloc */
2417 0, /* tp_new */
2418 0, /* tp_free */
2419 0, /* tp_is_gc */
2420 0, /* tp_bases */
2421 0, /* tp_mro */
2422 0, /* tp_cache */
2423 0, /* tp_subclasses */
2424 0, /* tp_weaklist */
2425 0, /* tp_del */
2426 0, /* tp_version_tag */
2427 0, /* tp_finalize */
2428};
2429
2430
2431static PyMethodDef bufferedreader_methods[] = {
2432 /* BufferedIOMixin methods */
2433 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2434 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2435 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2436 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2437 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002438 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2439 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2440 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2441 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2442
2443 _IO__BUFFERED_READ_METHODDEF
2444 _IO__BUFFERED_PEEK_METHODDEF
2445 _IO__BUFFERED_READ1_METHODDEF
2446 _IO__BUFFERED_READINTO_METHODDEF
2447 _IO__BUFFERED_READINTO1_METHODDEF
2448 _IO__BUFFERED_READLINE_METHODDEF
2449 _IO__BUFFERED_SEEK_METHODDEF
2450 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2451 _IO__BUFFERED_TRUNCATE_METHODDEF
2452 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2453 {NULL, NULL}
2454};
2455
2456static PyMemberDef bufferedreader_members[] = {
2457 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2458 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2459 {NULL}
2460};
2461
2462static PyGetSetDef bufferedreader_getset[] = {
2463 {"closed", (getter)buffered_closed_get, NULL, NULL},
2464 {"name", (getter)buffered_name_get, NULL, NULL},
2465 {"mode", (getter)buffered_mode_get, NULL, NULL},
2466 {NULL}
2467};
2468
2469
2470PyTypeObject PyBufferedReader_Type = {
2471 PyVarObject_HEAD_INIT(NULL, 0)
2472 "_io.BufferedReader", /*tp_name*/
2473 sizeof(buffered), /*tp_basicsize*/
2474 0, /*tp_itemsize*/
2475 (destructor)buffered_dealloc, /*tp_dealloc*/
2476 0, /*tp_print*/
2477 0, /*tp_getattr*/
2478 0, /*tp_setattr*/
2479 0, /*tp_compare */
2480 (reprfunc)buffered_repr, /*tp_repr*/
2481 0, /*tp_as_number*/
2482 0, /*tp_as_sequence*/
2483 0, /*tp_as_mapping*/
2484 0, /*tp_hash */
2485 0, /*tp_call*/
2486 0, /*tp_str*/
2487 0, /*tp_getattro*/
2488 0, /*tp_setattro*/
2489 0, /*tp_as_buffer*/
2490 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2491 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2492 _io_BufferedReader___init____doc__, /* tp_doc */
2493 (traverseproc)buffered_traverse, /* tp_traverse */
2494 (inquiry)buffered_clear, /* tp_clear */
2495 0, /* tp_richcompare */
2496 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2497 0, /* tp_iter */
2498 (iternextfunc)buffered_iternext, /* tp_iternext */
2499 bufferedreader_methods, /* tp_methods */
2500 bufferedreader_members, /* tp_members */
2501 bufferedreader_getset, /* tp_getset */
2502 0, /* tp_base */
2503 0, /* tp_dict */
2504 0, /* tp_descr_get */
2505 0, /* tp_descr_set */
2506 offsetof(buffered, dict), /* tp_dictoffset */
2507 _io_BufferedReader___init__, /* tp_init */
2508 0, /* tp_alloc */
2509 PyType_GenericNew, /* tp_new */
2510 0, /* tp_free */
2511 0, /* tp_is_gc */
2512 0, /* tp_bases */
2513 0, /* tp_mro */
2514 0, /* tp_cache */
2515 0, /* tp_subclasses */
2516 0, /* tp_weaklist */
2517 0, /* tp_del */
2518 0, /* tp_version_tag */
2519 0, /* tp_finalize */
2520};
2521
2522
2523static PyMethodDef bufferedwriter_methods[] = {
2524 /* BufferedIOMixin methods */
2525 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2526 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2527 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002528 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2529 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2530 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2531 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2532 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2533
2534 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2535 _IO__BUFFERED_TRUNCATE_METHODDEF
2536 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2537 _IO__BUFFERED_SEEK_METHODDEF
2538 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2539 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2540 {NULL, NULL}
2541};
2542
2543static PyMemberDef bufferedwriter_members[] = {
2544 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2545 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2546 {NULL}
2547};
2548
2549static PyGetSetDef bufferedwriter_getset[] = {
2550 {"closed", (getter)buffered_closed_get, NULL, NULL},
2551 {"name", (getter)buffered_name_get, NULL, NULL},
2552 {"mode", (getter)buffered_mode_get, NULL, NULL},
2553 {NULL}
2554};
2555
2556
2557PyTypeObject PyBufferedWriter_Type = {
2558 PyVarObject_HEAD_INIT(NULL, 0)
2559 "_io.BufferedWriter", /*tp_name*/
2560 sizeof(buffered), /*tp_basicsize*/
2561 0, /*tp_itemsize*/
2562 (destructor)buffered_dealloc, /*tp_dealloc*/
2563 0, /*tp_print*/
2564 0, /*tp_getattr*/
2565 0, /*tp_setattr*/
2566 0, /*tp_compare */
2567 (reprfunc)buffered_repr, /*tp_repr*/
2568 0, /*tp_as_number*/
2569 0, /*tp_as_sequence*/
2570 0, /*tp_as_mapping*/
2571 0, /*tp_hash */
2572 0, /*tp_call*/
2573 0, /*tp_str*/
2574 0, /*tp_getattro*/
2575 0, /*tp_setattro*/
2576 0, /*tp_as_buffer*/
2577 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2578 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2579 _io_BufferedWriter___init____doc__, /* tp_doc */
2580 (traverseproc)buffered_traverse, /* tp_traverse */
2581 (inquiry)buffered_clear, /* tp_clear */
2582 0, /* tp_richcompare */
2583 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2584 0, /* tp_iter */
2585 0, /* tp_iternext */
2586 bufferedwriter_methods, /* tp_methods */
2587 bufferedwriter_members, /* tp_members */
2588 bufferedwriter_getset, /* tp_getset */
2589 0, /* tp_base */
2590 0, /* tp_dict */
2591 0, /* tp_descr_get */
2592 0, /* tp_descr_set */
2593 offsetof(buffered, dict), /* tp_dictoffset */
2594 _io_BufferedWriter___init__, /* tp_init */
2595 0, /* tp_alloc */
2596 PyType_GenericNew, /* tp_new */
2597 0, /* tp_free */
2598 0, /* tp_is_gc */
2599 0, /* tp_bases */
2600 0, /* tp_mro */
2601 0, /* tp_cache */
2602 0, /* tp_subclasses */
2603 0, /* tp_weaklist */
2604 0, /* tp_del */
2605 0, /* tp_version_tag */
2606 0, /* tp_finalize */
2607};
2608
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002609
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002610static PyMethodDef bufferedrwpair_methods[] = {
2611 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2612 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2613 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2614 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
Benjamin Petersona96fea02014-06-22 14:17:44 -07002615 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002616
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002617 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2618 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002619
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002620 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2621 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002622
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002623 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2624 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002625
Antoine Pitrou243757e2010-11-05 21:15:39 +00002626 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2627
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002628 {NULL, NULL}
2629};
2630
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002631static PyGetSetDef bufferedrwpair_getset[] = {
2632 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002633 {NULL}
Antoine Pitroucf4c7492009-04-19 00:09:36 +00002634};
2635
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636PyTypeObject PyBufferedRWPair_Type = {
2637 PyVarObject_HEAD_INIT(NULL, 0)
2638 "_io.BufferedRWPair", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002639 sizeof(rwpair), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002640 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002641 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002642 0, /*tp_print*/
2643 0, /*tp_getattr*/
2644 0, /*tp_setattr*/
2645 0, /*tp_compare */
2646 0, /*tp_repr*/
2647 0, /*tp_as_number*/
2648 0, /*tp_as_sequence*/
2649 0, /*tp_as_mapping*/
2650 0, /*tp_hash */
2651 0, /*tp_call*/
2652 0, /*tp_str*/
2653 0, /*tp_getattro*/
2654 0, /*tp_setattro*/
2655 0, /*tp_as_buffer*/
2656 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002657 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002658 _io_BufferedRWPair___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002659 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2660 (inquiry)bufferedrwpair_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002661 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002662 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663 0, /* tp_iter */
2664 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002665 bufferedrwpair_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002666 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002667 bufferedrwpair_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002668 0, /* tp_base */
2669 0, /* tp_dict */
2670 0, /* tp_descr_get */
2671 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002672 offsetof(rwpair, dict), /* tp_dictoffset */
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002673 _io_BufferedRWPair___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002674 0, /* tp_alloc */
2675 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002676 0, /* tp_free */
2677 0, /* tp_is_gc */
2678 0, /* tp_bases */
2679 0, /* tp_mro */
2680 0, /* tp_cache */
2681 0, /* tp_subclasses */
2682 0, /* tp_weaklist */
2683 0, /* tp_del */
2684 0, /* tp_version_tag */
2685 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002686};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002687
2688
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002689static PyMethodDef bufferedrandom_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690 /* BufferedIOMixin methods */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002691 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2692 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2693 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2694 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2695 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2696 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2697 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
Antoine Pitroue033e062010-10-29 10:38:18 +00002698 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002699 {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002700
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002701 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002702
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002703 _IO__BUFFERED_SEEK_METHODDEF
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002704 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002705 _IO__BUFFERED_TRUNCATE_METHODDEF
2706 _IO__BUFFERED_READ_METHODDEF
2707 _IO__BUFFERED_READ1_METHODDEF
2708 _IO__BUFFERED_READINTO_METHODDEF
2709 _IO__BUFFERED_READINTO1_METHODDEF
2710 _IO__BUFFERED_READLINE_METHODDEF
2711 _IO__BUFFERED_PEEK_METHODDEF
2712 _IO_BUFFEREDWRITER_WRITE_METHODDEF
Antoine Pitrou10f0c502012-07-29 19:02:46 +02002713 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002714 {NULL, NULL}
2715};
2716
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002717static PyMemberDef bufferedrandom_members[] = {
Antoine Pitrou7f8f4182010-12-21 21:20:59 +00002718 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002719 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002720 {NULL}
2721};
2722
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002723static PyGetSetDef bufferedrandom_getset[] = {
2724 {"closed", (getter)buffered_closed_get, NULL, NULL},
2725 {"name", (getter)buffered_name_get, NULL, NULL},
2726 {"mode", (getter)buffered_mode_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002727 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002728};
2729
2730
2731PyTypeObject PyBufferedRandom_Type = {
2732 PyVarObject_HEAD_INIT(NULL, 0)
2733 "_io.BufferedRandom", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002734 sizeof(buffered), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002735 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002736 (destructor)buffered_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002737 0, /*tp_print*/
2738 0, /*tp_getattr*/
2739 0, /*tp_setattr*/
2740 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002741 (reprfunc)buffered_repr, /*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002742 0, /*tp_as_number*/
2743 0, /*tp_as_sequence*/
2744 0, /*tp_as_mapping*/
2745 0, /*tp_hash */
2746 0, /*tp_call*/
2747 0, /*tp_str*/
2748 0, /*tp_getattro*/
2749 0, /*tp_setattro*/
2750 0, /*tp_as_buffer*/
2751 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002752 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002753 _io_BufferedRandom___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002754 (traverseproc)buffered_traverse, /* tp_traverse */
2755 (inquiry)buffered_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002756 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002757 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002758 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002759 (iternextfunc)buffered_iternext, /* tp_iternext */
2760 bufferedrandom_methods, /* tp_methods */
2761 bufferedrandom_members, /* tp_members */
2762 bufferedrandom_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002763 0, /* tp_base */
2764 0, /*tp_dict*/
2765 0, /* tp_descr_get */
2766 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002767 offsetof(buffered, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002768 _io_BufferedRandom___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002769 0, /* tp_alloc */
2770 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002771 0, /* tp_free */
2772 0, /* tp_is_gc */
2773 0, /* tp_bases */
2774 0, /* tp_mro */
2775 0, /* tp_cache */
2776 0, /* tp_subclasses */
2777 0, /* tp_weaklist */
2778 0, /* tp_del */
2779 0, /* tp_version_tag */
2780 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002781};