1 /*
2 An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
3
4 Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5 BufferedRandom.
6
7 Written by Amaury Forgeot d'Arc and Antoine Pitrou
8 */
9
10 #define PY_SSIZE_T_CLEAN
11 #include "Python.h"
12 #include "pycore_object.h"
13 #include "structmember.h" // PyMemberDef
14 #include "_iomodule.h"
15
16 /*[clinic input]
17 module _io
18 class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19 class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20 class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21 class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22 class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23 class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24 [clinic start generated code]*/
25 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26
27 _Py_IDENTIFIER(close);
28 _Py_IDENTIFIER(_dealloc_warn);
29 _Py_IDENTIFIER(flush);
30 _Py_IDENTIFIER(isatty);
31 _Py_IDENTIFIER(mode);
32 _Py_IDENTIFIER(name);
33 _Py_IDENTIFIER(peek);
34 _Py_IDENTIFIER(read);
35 _Py_IDENTIFIER(read1);
36 _Py_IDENTIFIER(readable);
37 _Py_IDENTIFIER(readinto);
38 _Py_IDENTIFIER(readinto1);
39 _Py_IDENTIFIER(writable);
40 _Py_IDENTIFIER(write);
41
42 /*
43 * BufferedIOBase class, inherits from IOBase.
44 */
45 PyDoc_STRVAR(bufferediobase_doc,
46 "Base class for buffered IO objects.\n"
47 "\n"
48 "The main difference with RawIOBase is that the read() method\n"
49 "supports omitting the size argument, and does not have a default\n"
50 "implementation that defers to readinto().\n"
51 "\n"
52 "In addition, read(), readinto() and write() may raise\n"
53 "BlockingIOError if the underlying raw stream is in non-blocking\n"
54 "mode and not ready; unlike their raw counterparts, they will never\n"
55 "return None.\n"
56 "\n"
57 "A typical implementation should not inherit from a RawIOBase\n"
58 "implementation, but wrap one.\n"
59 );
60
61 static PyObject *
_bufferediobase_readinto_generic(PyObject * self,Py_buffer * buffer,char readinto1)62 _bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
63 {
64 Py_ssize_t len;
65 PyObject *data;
66
67 data = _PyObject_CallMethodId(self,
68 readinto1 ? &PyId_read1 : &PyId_read,
69 "n", buffer->len);
70 if (data == NULL)
71 return NULL;
72
73 if (!PyBytes_Check(data)) {
74 Py_DECREF(data);
75 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
76 return NULL;
77 }
78
79 len = PyBytes_GET_SIZE(data);
80 if (len > buffer->len) {
81 PyErr_Format(PyExc_ValueError,
82 "read() returned too much data: "
83 "%zd bytes requested, %zd returned",
84 buffer->len, len);
85 Py_DECREF(data);
86 return NULL;
87 }
88 memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
89
90 Py_DECREF(data);
91
92 return PyLong_FromSsize_t(len);
93 }
94
95 /*[clinic input]
96 _io._BufferedIOBase.readinto
97 buffer: Py_buffer(accept={rwbuffer})
98 /
99 [clinic start generated code]*/
100
101 static PyObject *
_io__BufferedIOBase_readinto_impl(PyObject * self,Py_buffer * buffer)102 _io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
103 /*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
104 {
105 return _bufferediobase_readinto_generic(self, buffer, 0);
106 }
107
108 /*[clinic input]
109 _io._BufferedIOBase.readinto1
110 buffer: Py_buffer(accept={rwbuffer})
111 /
112 [clinic start generated code]*/
113
114 static PyObject *
_io__BufferedIOBase_readinto1_impl(PyObject * self,Py_buffer * buffer)115 _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
116 /*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
117 {
118 return _bufferediobase_readinto_generic(self, buffer, 1);
119 }
120
121 static PyObject *
bufferediobase_unsupported(const char * message)122 bufferediobase_unsupported(const char *message)
123 {
124 _PyIO_State *state = IO_STATE();
125 if (state != NULL)
126 PyErr_SetString(state->unsupported_operation, message);
127 return NULL;
128 }
129
130 /*[clinic input]
131 _io._BufferedIOBase.detach
132
133 Disconnect this buffer from its underlying raw stream and return it.
134
135 After the raw stream has been detached, the buffer is in an unusable
136 state.
137 [clinic start generated code]*/
138
139 static PyObject *
_io__BufferedIOBase_detach_impl(PyObject * self)140 _io__BufferedIOBase_detach_impl(PyObject *self)
141 /*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
142 {
143 return bufferediobase_unsupported("detach");
144 }
145
146 PyDoc_STRVAR(bufferediobase_read_doc,
147 "Read and return up to n bytes.\n"
148 "\n"
149 "If the argument is omitted, None, or negative, reads and\n"
150 "returns all data until EOF.\n"
151 "\n"
152 "If the argument is positive, and the underlying raw stream is\n"
153 "not 'interactive', multiple raw reads may be issued to satisfy\n"
154 "the byte count (unless EOF is reached first). But for\n"
155 "interactive raw streams (as well as sockets and pipes), at most\n"
156 "one raw read will be issued, and a short result does not imply\n"
157 "that EOF is imminent.\n"
158 "\n"
159 "Returns an empty bytes object on EOF.\n"
160 "\n"
161 "Returns None if the underlying raw stream was open in non-blocking\n"
162 "mode and no data is available at the moment.\n");
163
164 static PyObject *
bufferediobase_read(PyObject * self,PyObject * args)165 bufferediobase_read(PyObject *self, PyObject *args)
166 {
167 return bufferediobase_unsupported("read");
168 }
169
170 PyDoc_STRVAR(bufferediobase_read1_doc,
171 "Read and return up to n bytes, with at most one read() call\n"
172 "to the underlying raw stream. A short result does not imply\n"
173 "that EOF is imminent.\n"
174 "\n"
175 "Returns an empty bytes object on EOF.\n");
176
177 static PyObject *
bufferediobase_read1(PyObject * self,PyObject * args)178 bufferediobase_read1(PyObject *self, PyObject *args)
179 {
180 return bufferediobase_unsupported("read1");
181 }
182
183 PyDoc_STRVAR(bufferediobase_write_doc,
184 "Write the given buffer to the IO stream.\n"
185 "\n"
186 "Returns the number of bytes written, which is always the length of b\n"
187 "in bytes.\n"
188 "\n"
189 "Raises BlockingIOError if the buffer is full and the\n"
190 "underlying raw stream cannot accept more data at the moment.\n");
191
192 static PyObject *
bufferediobase_write(PyObject * self,PyObject * args)193 bufferediobase_write(PyObject *self, PyObject *args)
194 {
195 return bufferediobase_unsupported("write");
196 }
197
198
199 typedef struct {
200 PyObject_HEAD
201
202 PyObject *raw;
203 int ok; /* Initialized? */
204 int detached;
205 int readable;
206 int writable;
207 char finalizing;
208
209 /* True if this is a vanilla Buffered object (rather than a user derived
210 class) *and* the raw stream is a vanilla FileIO object. */
211 int fast_closed_checks;
212
213 /* Absolute position inside the raw stream (-1 if unknown). */
214 Py_off_t abs_pos;
215
216 /* A static buffer of size `buffer_size` */
217 char *buffer;
218 /* Current logical position in the buffer. */
219 Py_off_t pos;
220 /* Position of the raw stream in the buffer. */
221 Py_off_t raw_pos;
222
223 /* Just after the last buffered byte in the buffer, or -1 if the buffer
224 isn't ready for reading. */
225 Py_off_t read_end;
226
227 /* Just after the last byte actually written */
228 Py_off_t write_pos;
229 /* Just after the last byte waiting to be written, or -1 if the buffer
230 isn't ready for writing. */
231 Py_off_t write_end;
232
233 PyThread_type_lock lock;
234 volatile unsigned long owner;
235
236 Py_ssize_t buffer_size;
237 Py_ssize_t buffer_mask;
238
239 PyObject *dict;
240 PyObject *weakreflist;
241 } buffered;
242
243 /*
244 Implementation notes:
245
246 * BufferedReader, BufferedWriter and BufferedRandom try to share most
247 methods (this is helped by the members `readable` and `writable`, which
248 are initialized in the respective constructors)
249 * They also share a single buffer for reading and writing. This enables
250 interleaved reads and writes without flushing. It also makes the logic
251 a bit trickier to get right.
252 * The absolute position of the raw stream is cached, if possible, in the
253 `abs_pos` member. It must be updated every time an operation is done
254 on the raw stream. If not sure, it can be reinitialized by calling
255 _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
256 also does it). To read it, use RAW_TELL().
257 * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
258 _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
259
260 NOTE: we should try to maintain block alignment of reads and writes to the
261 raw stream (according to the buffer size), but for now it is only done
262 in read() and friends.
263
264 */
265
266 /* These macros protect the buffered object against concurrent operations. */
267
268 static int
_enter_buffered_busy(buffered * self)269 _enter_buffered_busy(buffered *self)
270 {
271 int relax_locking;
272 PyLockStatus st;
273 if (self->owner == PyThread_get_thread_ident()) {
274 PyErr_Format(PyExc_RuntimeError,
275 "reentrant call inside %R", self);
276 return 0;
277 }
278 relax_locking = _Py_IsFinalizing();
279 Py_BEGIN_ALLOW_THREADS
280 if (!relax_locking)
281 st = PyThread_acquire_lock(self->lock, 1);
282 else {
283 /* When finalizing, we don't want a deadlock to happen with daemon
284 * threads abruptly shut down while they owned the lock.
285 * Therefore, only wait for a grace period (1 s.).
286 * Note that non-daemon threads have already exited here, so this
287 * shouldn't affect carefully written threaded I/O code.
288 */
289 st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
290 }
291 Py_END_ALLOW_THREADS
292 if (relax_locking && st != PY_LOCK_ACQUIRED) {
293 PyObject *ascii = PyObject_ASCII((PyObject*)self);
294 _Py_FatalErrorFormat(__func__,
295 "could not acquire lock for %s at interpreter "
296 "shutdown, possibly due to daemon threads",
297 ascii ? PyUnicode_AsUTF8(ascii) : "<ascii(self) failed>");
298 }
299 return 1;
300 }
301
302 #define ENTER_BUFFERED(self) \
303 ( (PyThread_acquire_lock(self->lock, 0) ? \
304 1 : _enter_buffered_busy(self)) \
305 && (self->owner = PyThread_get_thread_ident(), 1) )
306
307 #define LEAVE_BUFFERED(self) \
308 do { \
309 self->owner = 0; \
310 PyThread_release_lock(self->lock); \
311 } while(0);
312
313 #define CHECK_INITIALIZED(self) \
314 if (self->ok <= 0) { \
315 if (self->detached) { \
316 PyErr_SetString(PyExc_ValueError, \
317 "raw stream has been detached"); \
318 } else { \
319 PyErr_SetString(PyExc_ValueError, \
320 "I/O operation on uninitialized object"); \
321 } \
322 return NULL; \
323 }
324
325 #define CHECK_INITIALIZED_INT(self) \
326 if (self->ok <= 0) { \
327 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 } \
334 return -1; \
335 }
336
337 #define IS_CLOSED(self) \
338 (!self->buffer || \
339 (self->fast_closed_checks \
340 ? _PyFileIO_closed(self->raw) \
341 : buffered_closed(self)))
342
343 #define CHECK_CLOSED(self, error_msg) \
344 if (IS_CLOSED(self)) { \
345 PyErr_SetString(PyExc_ValueError, error_msg); \
346 return NULL; \
347 }
348
349
350 #define VALID_READ_BUFFER(self) \
351 (self->readable && self->read_end != -1)
352
353 #define VALID_WRITE_BUFFER(self) \
354 (self->writable && self->write_end != -1)
355
356 #define ADJUST_POSITION(self, _new_pos) \
357 do { \
358 self->pos = _new_pos; \
359 if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
360 self->read_end = self->pos; \
361 } while(0)
362
363 #define READAHEAD(self) \
364 ((self->readable && VALID_READ_BUFFER(self)) \
365 ? (self->read_end - self->pos) : 0)
366
367 #define RAW_OFFSET(self) \
368 (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
369 && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
370
371 #define RAW_TELL(self) \
372 (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
373
374 #define MINUS_LAST_BLOCK(self, size) \
375 (self->buffer_mask ? \
376 (size & ~self->buffer_mask) : \
377 (self->buffer_size * (size / self->buffer_size)))
378
379
380 static void
buffered_dealloc(buffered * self)381 buffered_dealloc(buffered *self)
382 {
383 self->finalizing = 1;
384 if (_PyIOBase_finalize((PyObject *) self) < 0)
385 return;
386 _PyObject_GC_UNTRACK(self);
387 self->ok = 0;
388 if (self->weakreflist != NULL)
389 PyObject_ClearWeakRefs((PyObject *)self);
390 Py_CLEAR(self->raw);
391 if (self->buffer) {
392 PyMem_Free(self->buffer);
393 self->buffer = NULL;
394 }
395 if (self->lock) {
396 PyThread_free_lock(self->lock);
397 self->lock = NULL;
398 }
399 Py_CLEAR(self->dict);
400 Py_TYPE(self)->tp_free((PyObject *)self);
401 }
402
403 static PyObject *
buffered_sizeof(buffered * self,PyObject * Py_UNUSED (ignored))404 buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
405 {
406 Py_ssize_t res;
407
408 res = _PyObject_SIZE(Py_TYPE(self));
409 if (self->buffer)
410 res += self->buffer_size;
411 return PyLong_FromSsize_t(res);
412 }
413
414 static int
buffered_traverse(buffered * self,visitproc visit,void * arg)415 buffered_traverse(buffered *self, visitproc visit, void *arg)
416 {
417 Py_VISIT(self->raw);
418 Py_VISIT(self->dict);
419 return 0;
420 }
421
422 static int
buffered_clear(buffered * self)423 buffered_clear(buffered *self)
424 {
425 self->ok = 0;
426 Py_CLEAR(self->raw);
427 Py_CLEAR(self->dict);
428 return 0;
429 }
430
431 /* Because this can call arbitrary code, it shouldn't be called when
432 the refcount is 0 (that is, not directly from tp_dealloc unless
433 the refcount has been temporarily re-incremented). */
434 static PyObject *
buffered_dealloc_warn(buffered * self,PyObject * source)435 buffered_dealloc_warn(buffered *self, PyObject *source)
436 {
437 if (self->ok && self->raw) {
438 PyObject *r;
439 r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn,
440 source);
441 if (r)
442 Py_DECREF(r);
443 else
444 PyErr_Clear();
445 }
446 Py_RETURN_NONE;
447 }
448
449 /*
450 * _BufferedIOMixin methods
451 * This is not a class, just a collection of methods that will be reused
452 * by BufferedReader and BufferedWriter
453 */
454
455 /* Flush and close */
456
457 static PyObject *
buffered_simple_flush(buffered * self,PyObject * args)458 buffered_simple_flush(buffered *self, PyObject *args)
459 {
460 CHECK_INITIALIZED(self)
461 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush);
462 }
463
464 static int
buffered_closed(buffered * self)465 buffered_closed(buffered *self)
466 {
467 int closed;
468 PyObject *res;
469 CHECK_INITIALIZED_INT(self)
470 res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
471 if (res == NULL)
472 return -1;
473 closed = PyObject_IsTrue(res);
474 Py_DECREF(res);
475 return closed;
476 }
477
478 static PyObject *
buffered_closed_get(buffered * self,void * context)479 buffered_closed_get(buffered *self, void *context)
480 {
481 CHECK_INITIALIZED(self)
482 return PyObject_GetAttr(self->raw, _PyIO_str_closed);
483 }
484
485 static PyObject *
buffered_close(buffered * self,PyObject * args)486 buffered_close(buffered *self, PyObject *args)
487 {
488 PyObject *res = NULL, *exc = NULL, *val, *tb;
489 int r;
490
491 CHECK_INITIALIZED(self)
492 if (!ENTER_BUFFERED(self))
493 return NULL;
494
495 r = buffered_closed(self);
496 if (r < 0)
497 goto end;
498 if (r > 0) {
499 res = Py_None;
500 Py_INCREF(res);
501 goto end;
502 }
503
504 if (self->finalizing) {
505 PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
506 if (r)
507 Py_DECREF(r);
508 else
509 PyErr_Clear();
510 }
511 /* flush() will most probably re-take the lock, so drop it first */
512 LEAVE_BUFFERED(self)
513 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
514 if (!ENTER_BUFFERED(self))
515 return NULL;
516 if (res == NULL)
517 PyErr_Fetch(&exc, &val, &tb);
518 else
519 Py_DECREF(res);
520
521 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close);
522
523 if (self->buffer) {
524 PyMem_Free(self->buffer);
525 self->buffer = NULL;
526 }
527
528 if (exc != NULL) {
529 _PyErr_ChainExceptions(exc, val, tb);
530 Py_CLEAR(res);
531 }
532
533 end:
534 LEAVE_BUFFERED(self)
535 return res;
536 }
537
538 /* detach */
539
540 static PyObject *
buffered_detach(buffered * self,PyObject * Py_UNUSED (ignored))541 buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
542 {
543 PyObject *raw, *res;
544 CHECK_INITIALIZED(self)
545 res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
546 if (res == NULL)
547 return NULL;
548 Py_DECREF(res);
549 raw = self->raw;
550 self->raw = NULL;
551 self->detached = 1;
552 self->ok = 0;
553 return raw;
554 }
555
556 /* Inquiries */
557
558 static PyObject *
buffered_seekable(buffered * self,PyObject * Py_UNUSED (ignored))559 buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
560 {
561 CHECK_INITIALIZED(self)
562 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable);
563 }
564
565 static PyObject *
buffered_readable(buffered * self,PyObject * Py_UNUSED (ignored))566 buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
567 {
568 CHECK_INITIALIZED(self)
569 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable);
570 }
571
572 static PyObject *
buffered_writable(buffered * self,PyObject * Py_UNUSED (ignored))573 buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
574 {
575 CHECK_INITIALIZED(self)
576 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable);
577 }
578
579 static PyObject *
buffered_name_get(buffered * self,void * context)580 buffered_name_get(buffered *self, void *context)
581 {
582 CHECK_INITIALIZED(self)
583 return _PyObject_GetAttrId(self->raw, &PyId_name);
584 }
585
586 static PyObject *
buffered_mode_get(buffered * self,void * context)587 buffered_mode_get(buffered *self, void *context)
588 {
589 CHECK_INITIALIZED(self)
590 return _PyObject_GetAttrId(self->raw, &PyId_mode);
591 }
592
593 /* Lower-level APIs */
594
595 static PyObject *
buffered_fileno(buffered * self,PyObject * Py_UNUSED (ignored))596 buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
597 {
598 CHECK_INITIALIZED(self)
599 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno);
600 }
601
602 static PyObject *
buffered_isatty(buffered * self,PyObject * Py_UNUSED (ignored))603 buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
604 {
605 CHECK_INITIALIZED(self)
606 return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty);
607 }
608
609 /* Forward decls */
610 static PyObject *
611 _bufferedwriter_flush_unlocked(buffered *);
612 static Py_ssize_t
613 _bufferedreader_fill_buffer(buffered *self);
614 static void
615 _bufferedreader_reset_buf(buffered *self);
616 static void
617 _bufferedwriter_reset_buf(buffered *self);
618 static PyObject *
619 _bufferedreader_peek_unlocked(buffered *self);
620 static PyObject *
621 _bufferedreader_read_all(buffered *self);
622 static PyObject *
623 _bufferedreader_read_fast(buffered *self, Py_ssize_t);
624 static PyObject *
625 _bufferedreader_read_generic(buffered *self, Py_ssize_t);
626 static Py_ssize_t
627 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
628
629 /*
630 * Helpers
631 */
632
633 /* Sets the current error to BlockingIOError */
634 static void
_set_BlockingIOError(const char * msg,Py_ssize_t written)635 _set_BlockingIOError(const char *msg, Py_ssize_t written)
636 {
637 PyObject *err;
638 PyErr_Clear();
639 err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
640 errno, msg, written);
641 if (err)
642 PyErr_SetObject(PyExc_BlockingIOError, err);
643 Py_XDECREF(err);
644 }
645
646 /* Returns the address of the `written` member if a BlockingIOError was
647 raised, NULL otherwise. The error is always re-raised. */
648 static Py_ssize_t *
_buffered_check_blocking_error(void)649 _buffered_check_blocking_error(void)
650 {
651 PyObject *t, *v, *tb;
652 PyOSErrorObject *err;
653
654 PyErr_Fetch(&t, &v, &tb);
655 if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
656 PyErr_Restore(t, v, tb);
657 return NULL;
658 }
659 err = (PyOSErrorObject *) v;
660 /* TODO: sanity check (err->written >= 0) */
661 PyErr_Restore(t, v, tb);
662 return &err->written;
663 }
664
665 static Py_off_t
_buffered_raw_tell(buffered * self)666 _buffered_raw_tell(buffered *self)
667 {
668 Py_off_t n;
669 PyObject *res;
670 res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell);
671 if (res == NULL)
672 return -1;
673 n = PyNumber_AsOff_t(res, PyExc_ValueError);
674 Py_DECREF(res);
675 if (n < 0) {
676 if (!PyErr_Occurred())
677 PyErr_Format(PyExc_OSError,
678 "Raw stream returned invalid position %" PY_PRIdOFF,
679 (PY_OFF_T_COMPAT)n);
680 return -1;
681 }
682 self->abs_pos = n;
683 return n;
684 }
685
686 static Py_off_t
_buffered_raw_seek(buffered * self,Py_off_t target,int whence)687 _buffered_raw_seek(buffered *self, Py_off_t target, int whence)
688 {
689 PyObject *res, *posobj, *whenceobj;
690 Py_off_t n;
691
692 posobj = PyLong_FromOff_t(target);
693 if (posobj == NULL)
694 return -1;
695 whenceobj = PyLong_FromLong(whence);
696 if (whenceobj == NULL) {
697 Py_DECREF(posobj);
698 return -1;
699 }
700 res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
701 posobj, whenceobj, NULL);
702 Py_DECREF(posobj);
703 Py_DECREF(whenceobj);
704 if (res == NULL)
705 return -1;
706 n = PyNumber_AsOff_t(res, PyExc_ValueError);
707 Py_DECREF(res);
708 if (n < 0) {
709 if (!PyErr_Occurred())
710 PyErr_Format(PyExc_OSError,
711 "Raw stream returned invalid position %" PY_PRIdOFF,
712 (PY_OFF_T_COMPAT)n);
713 return -1;
714 }
715 self->abs_pos = n;
716 return n;
717 }
718
719 static int
_buffered_init(buffered * self)720 _buffered_init(buffered *self)
721 {
722 Py_ssize_t n;
723 if (self->buffer_size <= 0) {
724 PyErr_SetString(PyExc_ValueError,
725 "buffer size must be strictly positive");
726 return -1;
727 }
728 if (self->buffer)
729 PyMem_Free(self->buffer);
730 self->buffer = PyMem_Malloc(self->buffer_size);
731 if (self->buffer == NULL) {
732 PyErr_NoMemory();
733 return -1;
734 }
735 if (self->lock)
736 PyThread_free_lock(self->lock);
737 self->lock = PyThread_allocate_lock();
738 if (self->lock == NULL) {
739 PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
740 return -1;
741 }
742 self->owner = 0;
743 /* Find out whether buffer_size is a power of 2 */
744 /* XXX is this optimization useful? */
745 for (n = self->buffer_size - 1; n & 1; n >>= 1)
746 ;
747 if (n == 0)
748 self->buffer_mask = self->buffer_size - 1;
749 else
750 self->buffer_mask = 0;
751 if (_buffered_raw_tell(self) == -1)
752 PyErr_Clear();
753 return 0;
754 }
755
756 /* Return 1 if an OSError with errno == EINTR is set (and then
757 clears the error indicator), 0 otherwise.
758 Should only be called when PyErr_Occurred() is true.
759 */
760 int
_PyIO_trap_eintr(void)761 _PyIO_trap_eintr(void)
762 {
763 static PyObject *eintr_int = NULL;
764 PyObject *typ, *val, *tb;
765 PyOSErrorObject *env_err;
766
767 if (eintr_int == NULL) {
768 eintr_int = PyLong_FromLong(EINTR);
769 assert(eintr_int != NULL);
770 }
771 if (!PyErr_ExceptionMatches(PyExc_OSError))
772 return 0;
773 PyErr_Fetch(&typ, &val, &tb);
774 PyErr_NormalizeException(&typ, &val, &tb);
775 env_err = (PyOSErrorObject *) val;
776 assert(env_err != NULL);
777 if (env_err->myerrno != NULL &&
778 PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
779 Py_DECREF(typ);
780 Py_DECREF(val);
781 Py_XDECREF(tb);
782 return 1;
783 }
784 /* This silences any error set by PyObject_RichCompareBool() */
785 PyErr_Restore(typ, val, tb);
786 return 0;
787 }
788
789 /*
790 * Shared methods and wrappers
791 */
792
793 static PyObject *
buffered_flush_and_rewind_unlocked(buffered * self)794 buffered_flush_and_rewind_unlocked(buffered *self)
795 {
796 PyObject *res;
797
798 res = _bufferedwriter_flush_unlocked(self);
799 if (res == NULL)
800 return NULL;
801 Py_DECREF(res);
802
803 if (self->readable) {
804 /* Rewind the raw stream so that its position corresponds to
805 the current logical position. */
806 Py_off_t n;
807 n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
808 _bufferedreader_reset_buf(self);
809 if (n == -1)
810 return NULL;
811 }
812 Py_RETURN_NONE;
813 }
814
815 static PyObject *
buffered_flush(buffered * self,PyObject * args)816 buffered_flush(buffered *self, PyObject *args)
817 {
818 PyObject *res;
819
820 CHECK_INITIALIZED(self)
821 CHECK_CLOSED(self, "flush of closed file")
822
823 if (!ENTER_BUFFERED(self))
824 return NULL;
825 res = buffered_flush_and_rewind_unlocked(self);
826 LEAVE_BUFFERED(self)
827
828 return res;
829 }
830
831 /*[clinic input]
832 _io._Buffered.peek
833 size: Py_ssize_t = 0
834 /
835
836 [clinic start generated code]*/
837
838 static PyObject *
_io__Buffered_peek_impl(buffered * self,Py_ssize_t size)839 _io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
840 /*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
841 {
842 PyObject *res = NULL;
843
844 CHECK_INITIALIZED(self)
845 CHECK_CLOSED(self, "peek of closed file")
846
847 if (!ENTER_BUFFERED(self))
848 return NULL;
849
850 if (self->writable) {
851 res = buffered_flush_and_rewind_unlocked(self);
852 if (res == NULL)
853 goto end;
854 Py_CLEAR(res);
855 }
856 res = _bufferedreader_peek_unlocked(self);
857
858 end:
859 LEAVE_BUFFERED(self)
860 return res;
861 }
862
863 /*[clinic input]
864 _io._Buffered.read
865 size as n: Py_ssize_t(accept={int, NoneType}) = -1
866 /
867 [clinic start generated code]*/
868
869 static PyObject *
_io__Buffered_read_impl(buffered * self,Py_ssize_t n)870 _io__Buffered_read_impl(buffered *self, Py_ssize_t n)
871 /*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
872 {
873 PyObject *res;
874
875 CHECK_INITIALIZED(self)
876 if (n < -1) {
877 PyErr_SetString(PyExc_ValueError,
878 "read length must be non-negative or -1");
879 return NULL;
880 }
881
882 CHECK_CLOSED(self, "read of closed file")
883
884 if (n == -1) {
885 /* The number of bytes is unspecified, read until the end of stream */
886 if (!ENTER_BUFFERED(self))
887 return NULL;
888 res = _bufferedreader_read_all(self);
889 }
890 else {
891 res = _bufferedreader_read_fast(self, n);
892 if (res != Py_None)
893 return res;
894 Py_DECREF(res);
895 if (!ENTER_BUFFERED(self))
896 return NULL;
897 res = _bufferedreader_read_generic(self, n);
898 }
899
900 LEAVE_BUFFERED(self)
901 return res;
902 }
903
904 /*[clinic input]
905 _io._Buffered.read1
906 size as n: Py_ssize_t = -1
907 /
908 [clinic start generated code]*/
909
910 static PyObject *
_io__Buffered_read1_impl(buffered * self,Py_ssize_t n)911 _io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
912 /*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
913 {
914 Py_ssize_t have, r;
915 PyObject *res = NULL;
916
917 CHECK_INITIALIZED(self)
918 if (n < 0) {
919 n = self->buffer_size;
920 }
921
922 CHECK_CLOSED(self, "read of closed file")
923
924 if (n == 0)
925 return PyBytes_FromStringAndSize(NULL, 0);
926
927 /* Return up to n bytes. If at least one byte is buffered, we
928 only return buffered bytes. Otherwise, we do one raw read. */
929
930 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
931 if (have > 0) {
932 n = Py_MIN(have, n);
933 res = _bufferedreader_read_fast(self, n);
934 assert(res != Py_None);
935 return res;
936 }
937 res = PyBytes_FromStringAndSize(NULL, n);
938 if (res == NULL)
939 return NULL;
940 if (!ENTER_BUFFERED(self)) {
941 Py_DECREF(res);
942 return NULL;
943 }
944 _bufferedreader_reset_buf(self);
945 r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
946 LEAVE_BUFFERED(self)
947 if (r == -1) {
948 Py_DECREF(res);
949 return NULL;
950 }
951 if (r == -2)
952 r = 0;
953 if (n > r)
954 _PyBytes_Resize(&res, r);
955 return res;
956 }
957
958 static PyObject *
_buffered_readinto_generic(buffered * self,Py_buffer * buffer,char readinto1)959 _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
960 {
961 Py_ssize_t n, written = 0, remaining;
962 PyObject *res = NULL;
963
964 CHECK_INITIALIZED(self)
965 CHECK_CLOSED(self, "readinto of closed file")
966
967 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
968 if (n > 0) {
969 if (n >= buffer->len) {
970 memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
971 self->pos += buffer->len;
972 return PyLong_FromSsize_t(buffer->len);
973 }
974 memcpy(buffer->buf, self->buffer + self->pos, n);
975 self->pos += n;
976 written = n;
977 }
978
979 if (!ENTER_BUFFERED(self))
980 return NULL;
981
982 if (self->writable) {
983 res = buffered_flush_and_rewind_unlocked(self);
984 if (res == NULL)
985 goto end;
986 Py_CLEAR(res);
987 }
988
989 _bufferedreader_reset_buf(self);
990 self->pos = 0;
991
992 for (remaining = buffer->len - written;
993 remaining > 0;
994 written += n, remaining -= n) {
995 /* If remaining bytes is larger than internal buffer size, copy
996 * directly into caller's buffer. */
997 if (remaining > self->buffer_size) {
998 n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
999 remaining);
1000 }
1001
1002 /* In readinto1 mode, we do not want to fill the internal
1003 buffer if we already have some data to return */
1004 else if (!(readinto1 && written)) {
1005 n = _bufferedreader_fill_buffer(self);
1006 if (n > 0) {
1007 if (n > remaining)
1008 n = remaining;
1009 memcpy((char *) buffer->buf + written,
1010 self->buffer + self->pos, n);
1011 self->pos += n;
1012 continue; /* short circuit */
1013 }
1014 }
1015 else
1016 n = 0;
1017
1018 if (n == 0 || (n == -2 && written > 0))
1019 break;
1020 if (n < 0) {
1021 if (n == -2) {
1022 Py_INCREF(Py_None);
1023 res = Py_None;
1024 }
1025 goto end;
1026 }
1027
1028 /* At most one read in readinto1 mode */
1029 if (readinto1) {
1030 written += n;
1031 break;
1032 }
1033 }
1034 res = PyLong_FromSsize_t(written);
1035
1036 end:
1037 LEAVE_BUFFERED(self);
1038 return res;
1039 }
1040
1041 /*[clinic input]
1042 _io._Buffered.readinto
1043 buffer: Py_buffer(accept={rwbuffer})
1044 /
1045 [clinic start generated code]*/
1046
1047 static PyObject *
_io__Buffered_readinto_impl(buffered * self,Py_buffer * buffer)1048 _io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
1049 /*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
1050 {
1051 return _buffered_readinto_generic(self, buffer, 0);
1052 }
1053
1054 /*[clinic input]
1055 _io._Buffered.readinto1
1056 buffer: Py_buffer(accept={rwbuffer})
1057 /
1058 [clinic start generated code]*/
1059
1060 static PyObject *
_io__Buffered_readinto1_impl(buffered * self,Py_buffer * buffer)1061 _io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
1062 /*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
1063 {
1064 return _buffered_readinto_generic(self, buffer, 1);
1065 }
1066
1067
1068 static PyObject *
_buffered_readline(buffered * self,Py_ssize_t limit)1069 _buffered_readline(buffered *self, Py_ssize_t limit)
1070 {
1071 PyObject *res = NULL;
1072 PyObject *chunks = NULL;
1073 Py_ssize_t n, written = 0;
1074 const char *start, *s, *end;
1075
1076 CHECK_CLOSED(self, "readline of closed file")
1077
1078 /* First, try to find a line in the buffer. This can run unlocked because
1079 the calls to the C API are simple enough that they can't trigger
1080 any thread switch. */
1081 n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1082 if (limit >= 0 && n > limit)
1083 n = limit;
1084 start = self->buffer + self->pos;
1085 s = memchr(start, '\n', n);
1086 if (s != NULL) {
1087 res = PyBytes_FromStringAndSize(start, s - start + 1);
1088 if (res != NULL)
1089 self->pos += s - start + 1;
1090 goto end_unlocked;
1091 }
1092 if (n == limit) {
1093 res = PyBytes_FromStringAndSize(start, n);
1094 if (res != NULL)
1095 self->pos += n;
1096 goto end_unlocked;
1097 }
1098
1099 if (!ENTER_BUFFERED(self))
1100 goto end_unlocked;
1101
1102 /* Now we try to get some more from the raw stream */
1103 chunks = PyList_New(0);
1104 if (chunks == NULL)
1105 goto end;
1106 if (n > 0) {
1107 res = PyBytes_FromStringAndSize(start, n);
1108 if (res == NULL)
1109 goto end;
1110 if (PyList_Append(chunks, res) < 0) {
1111 Py_CLEAR(res);
1112 goto end;
1113 }
1114 Py_CLEAR(res);
1115 written += n;
1116 self->pos += n;
1117 if (limit >= 0)
1118 limit -= n;
1119 }
1120 if (self->writable) {
1121 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1122 if (r == NULL)
1123 goto end;
1124 Py_DECREF(r);
1125 }
1126
1127 for (;;) {
1128 _bufferedreader_reset_buf(self);
1129 n = _bufferedreader_fill_buffer(self);
1130 if (n == -1)
1131 goto end;
1132 if (n <= 0)
1133 break;
1134 if (limit >= 0 && n > limit)
1135 n = limit;
1136 start = self->buffer;
1137 end = start + n;
1138 s = start;
1139 while (s < end) {
1140 if (*s++ == '\n') {
1141 res = PyBytes_FromStringAndSize(start, s - start);
1142 if (res == NULL)
1143 goto end;
1144 self->pos = s - start;
1145 goto found;
1146 }
1147 }
1148 res = PyBytes_FromStringAndSize(start, n);
1149 if (res == NULL)
1150 goto end;
1151 if (n == limit) {
1152 self->pos = n;
1153 break;
1154 }
1155 if (PyList_Append(chunks, res) < 0) {
1156 Py_CLEAR(res);
1157 goto end;
1158 }
1159 Py_CLEAR(res);
1160 written += n;
1161 if (limit >= 0)
1162 limit -= n;
1163 }
1164 found:
1165 if (res != NULL && PyList_Append(chunks, res) < 0) {
1166 Py_CLEAR(res);
1167 goto end;
1168 }
1169 Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
1170
1171 end:
1172 LEAVE_BUFFERED(self)
1173 end_unlocked:
1174 Py_XDECREF(chunks);
1175 return res;
1176 }
1177
1178 /*[clinic input]
1179 _io._Buffered.readline
1180 size: Py_ssize_t(accept={int, NoneType}) = -1
1181 /
1182 [clinic start generated code]*/
1183
1184 static PyObject *
_io__Buffered_readline_impl(buffered * self,Py_ssize_t size)1185 _io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
1186 /*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
1187 {
1188 CHECK_INITIALIZED(self)
1189 return _buffered_readline(self, size);
1190 }
1191
1192
1193 static PyObject *
buffered_tell(buffered * self,PyObject * Py_UNUSED (ignored))1194 buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored))
1195 {
1196 Py_off_t pos;
1197
1198 CHECK_INITIALIZED(self)
1199 pos = _buffered_raw_tell(self);
1200 if (pos == -1)
1201 return NULL;
1202 pos -= RAW_OFFSET(self);
1203 /* TODO: sanity check (pos >= 0) */
1204 return PyLong_FromOff_t(pos);
1205 }
1206
1207 /*[clinic input]
1208 _io._Buffered.seek
1209 target as targetobj: object
1210 whence: int = 0
1211 /
1212 [clinic start generated code]*/
1213
1214 static PyObject *
_io__Buffered_seek_impl(buffered * self,PyObject * targetobj,int whence)1215 _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1216 /*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
1217 {
1218 Py_off_t target, n;
1219 PyObject *res = NULL;
1220
1221 CHECK_INITIALIZED(self)
1222
1223 /* Do some error checking instead of trusting OS 'seek()'
1224 ** error detection, just in case.
1225 */
1226 if ((whence < 0 || whence >2)
1227 #ifdef SEEK_HOLE
1228 && (whence != SEEK_HOLE)
1229 #endif
1230 #ifdef SEEK_DATA
1231 && (whence != SEEK_DATA)
1232 #endif
1233 ) {
1234 PyErr_Format(PyExc_ValueError,
1235 "whence value %d unsupported", whence);
1236 return NULL;
1237 }
1238
1239 CHECK_CLOSED(self, "seek of closed file")
1240
1241 if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1242 return NULL;
1243
1244 target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1245 if (target == -1 && PyErr_Occurred())
1246 return NULL;
1247
1248 /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1249 buffer. Other whence values must be managed without this optimization.
1250 Some Operating Systems can provide additional values, like
1251 SEEK_HOLE/SEEK_DATA. */
1252 if (((whence == 0) || (whence == 1)) && self->readable) {
1253 Py_off_t current, avail;
1254 /* Check if seeking leaves us inside the current buffer,
1255 so as to return quickly if possible. Also, we needn't take the
1256 lock in this fast path.
1257 Don't know how to do that when whence == 2, though. */
1258 /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1259 state at this point. */
1260 current = RAW_TELL(self);
1261 avail = READAHEAD(self);
1262 if (avail > 0) {
1263 Py_off_t offset;
1264 if (whence == 0)
1265 offset = target - (current - RAW_OFFSET(self));
1266 else
1267 offset = target;
1268 if (offset >= -self->pos && offset <= avail) {
1269 self->pos += offset;
1270 return PyLong_FromOff_t(current - avail + offset);
1271 }
1272 }
1273 }
1274
1275 if (!ENTER_BUFFERED(self))
1276 return NULL;
1277
1278 /* Fallback: invoke raw seek() method and clear buffer */
1279 if (self->writable) {
1280 res = _bufferedwriter_flush_unlocked(self);
1281 if (res == NULL)
1282 goto end;
1283 Py_CLEAR(res);
1284 }
1285
1286 /* TODO: align on block boundary and read buffer if needed? */
1287 if (whence == 1)
1288 target -= RAW_OFFSET(self);
1289 n = _buffered_raw_seek(self, target, whence);
1290 if (n == -1)
1291 goto end;
1292 self->raw_pos = -1;
1293 res = PyLong_FromOff_t(n);
1294 if (res != NULL && self->readable)
1295 _bufferedreader_reset_buf(self);
1296
1297 end:
1298 LEAVE_BUFFERED(self)
1299 return res;
1300 }
1301
1302 /*[clinic input]
1303 _io._Buffered.truncate
1304 pos: object = None
1305 /
1306 [clinic start generated code]*/
1307
1308 static PyObject *
_io__Buffered_truncate_impl(buffered * self,PyObject * pos)1309 _io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1310 /*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
1311 {
1312 PyObject *res = NULL;
1313
1314 CHECK_INITIALIZED(self)
1315 CHECK_CLOSED(self, "truncate of closed file")
1316 if (!self->writable) {
1317 return bufferediobase_unsupported("truncate");
1318 }
1319 if (!ENTER_BUFFERED(self))
1320 return NULL;
1321
1322 res = buffered_flush_and_rewind_unlocked(self);
1323 if (res == NULL) {
1324 goto end;
1325 }
1326 Py_CLEAR(res);
1327
1328 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos);
1329 if (res == NULL)
1330 goto end;
1331 /* Reset cached position */
1332 if (_buffered_raw_tell(self) == -1)
1333 PyErr_Clear();
1334
1335 end:
1336 LEAVE_BUFFERED(self)
1337 return res;
1338 }
1339
1340 static PyObject *
buffered_iternext(buffered * self)1341 buffered_iternext(buffered *self)
1342 {
1343 PyObject *line;
1344 PyTypeObject *tp;
1345
1346 CHECK_INITIALIZED(self);
1347
1348 tp = Py_TYPE(self);
1349 if (tp == &PyBufferedReader_Type ||
1350 tp == &PyBufferedRandom_Type) {
1351 /* Skip method call overhead for speed */
1352 line = _buffered_readline(self, -1);
1353 }
1354 else {
1355 line = PyObject_CallMethodNoArgs((PyObject *)self,
1356 _PyIO_str_readline);
1357 if (line && !PyBytes_Check(line)) {
1358 PyErr_Format(PyExc_OSError,
1359 "readline() should have returned a bytes object, "
1360 "not '%.200s'", Py_TYPE(line)->tp_name);
1361 Py_DECREF(line);
1362 return NULL;
1363 }
1364 }
1365
1366 if (line == NULL)
1367 return NULL;
1368
1369 if (PyBytes_GET_SIZE(line) == 0) {
1370 /* Reached EOF or would have blocked */
1371 Py_DECREF(line);
1372 return NULL;
1373 }
1374
1375 return line;
1376 }
1377
1378 static PyObject *
buffered_repr(buffered * self)1379 buffered_repr(buffered *self)
1380 {
1381 PyObject *nameobj, *res;
1382
1383 if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
1384 if (!PyErr_ExceptionMatches(PyExc_ValueError)) {
1385 return NULL;
1386 }
1387 /* Ignore ValueError raised if the underlying stream was detached */
1388 PyErr_Clear();
1389 }
1390 if (nameobj == NULL) {
1391 res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1392 }
1393 else {
1394 int status = Py_ReprEnter((PyObject *)self);
1395 res = NULL;
1396 if (status == 0) {
1397 res = PyUnicode_FromFormat("<%s name=%R>",
1398 Py_TYPE(self)->tp_name, nameobj);
1399 Py_ReprLeave((PyObject *)self);
1400 }
1401 else if (status > 0) {
1402 PyErr_Format(PyExc_RuntimeError,
1403 "reentrant call inside %s.__repr__",
1404 Py_TYPE(self)->tp_name);
1405 }
1406 Py_DECREF(nameobj);
1407 }
1408 return res;
1409 }
1410
1411 /*
1412 * class BufferedReader
1413 */
1414
_bufferedreader_reset_buf(buffered * self)1415 static void _bufferedreader_reset_buf(buffered *self)
1416 {
1417 self->read_end = -1;
1418 }
1419
1420 /*[clinic input]
1421 _io.BufferedReader.__init__
1422 raw: object
1423 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
1424
1425 Create a new buffered reader using the given readable raw IO object.
1426 [clinic start generated code]*/
1427
1428 static int
_io_BufferedReader___init___impl(buffered * self,PyObject * raw,Py_ssize_t buffer_size)1429 _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1430 Py_ssize_t buffer_size)
1431 /*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1432 {
1433 self->ok = 0;
1434 self->detached = 0;
1435
1436 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
1437 return -1;
1438
1439 Py_INCREF(raw);
1440 Py_XSETREF(self->raw, raw);
1441 self->buffer_size = buffer_size;
1442 self->readable = 1;
1443 self->writable = 0;
1444
1445 if (_buffered_init(self) < 0)
1446 return -1;
1447 _bufferedreader_reset_buf(self);
1448
1449 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
1450 Py_IS_TYPE(raw, &PyFileIO_Type));
1451
1452 self->ok = 1;
1453 return 0;
1454 }
1455
1456 static Py_ssize_t
_bufferedreader_raw_read(buffered * self,char * start,Py_ssize_t len)1457 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
1458 {
1459 Py_buffer buf;
1460 PyObject *memobj, *res;
1461 Py_ssize_t n;
1462 /* NOTE: the buffer needn't be released as its object is NULL. */
1463 if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1464 return -1;
1465 memobj = PyMemoryView_FromBuffer(&buf);
1466 if (memobj == NULL)
1467 return -1;
1468 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1469 occurs so we needn't do it ourselves.
1470 We then retry reading, ignoring the signal if no handler has
1471 raised (see issue #10956).
1472 */
1473 do {
1474 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj);
1475 } while (res == NULL && _PyIO_trap_eintr());
1476 Py_DECREF(memobj);
1477 if (res == NULL)
1478 return -1;
1479 if (res == Py_None) {
1480 /* Non-blocking stream would have blocked. Special return code! */
1481 Py_DECREF(res);
1482 return -2;
1483 }
1484 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1485 Py_DECREF(res);
1486 if (n < 0 || n > len) {
1487 PyErr_Format(PyExc_OSError,
1488 "raw readinto() returned invalid length %zd "
1489 "(should have been between 0 and %zd)", n, len);
1490 return -1;
1491 }
1492 if (n > 0 && self->abs_pos != -1)
1493 self->abs_pos += n;
1494 return n;
1495 }
1496
1497 static Py_ssize_t
_bufferedreader_fill_buffer(buffered * self)1498 _bufferedreader_fill_buffer(buffered *self)
1499 {
1500 Py_ssize_t start, len, n;
1501 if (VALID_READ_BUFFER(self))
1502 start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1503 else
1504 start = 0;
1505 len = self->buffer_size - start;
1506 n = _bufferedreader_raw_read(self, self->buffer + start, len);
1507 if (n <= 0)
1508 return n;
1509 self->read_end = start + n;
1510 self->raw_pos = start + n;
1511 return n;
1512 }
1513
1514 static PyObject *
_bufferedreader_read_all(buffered * self)1515 _bufferedreader_read_all(buffered *self)
1516 {
1517 Py_ssize_t current_size;
1518 PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL, *readall;
1519
1520 /* First copy what we have in the current buffer. */
1521 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1522 if (current_size) {
1523 data = PyBytes_FromStringAndSize(
1524 self->buffer + self->pos, current_size);
1525 if (data == NULL)
1526 return NULL;
1527 self->pos += current_size;
1528 }
1529 /* We're going past the buffer's bounds, flush it */
1530 if (self->writable) {
1531 tmp = buffered_flush_and_rewind_unlocked(self);
1532 if (tmp == NULL)
1533 goto cleanup;
1534 Py_CLEAR(tmp);
1535 }
1536 _bufferedreader_reset_buf(self);
1537
1538 if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
1539 goto cleanup;
1540 }
1541 if (readall) {
1542 tmp = _PyObject_CallNoArg(readall);
1543 Py_DECREF(readall);
1544 if (tmp == NULL)
1545 goto cleanup;
1546 if (tmp != Py_None && !PyBytes_Check(tmp)) {
1547 PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1548 goto cleanup;
1549 }
1550 if (current_size == 0) {
1551 res = tmp;
1552 } else {
1553 if (tmp != Py_None) {
1554 PyBytes_Concat(&data, tmp);
1555 }
1556 res = data;
1557 }
1558 goto cleanup;
1559 }
1560
1561 chunks = PyList_New(0);
1562 if (chunks == NULL)
1563 goto cleanup;
1564
1565 while (1) {
1566 if (data) {
1567 if (PyList_Append(chunks, data) < 0)
1568 goto cleanup;
1569 Py_CLEAR(data);
1570 }
1571
1572 /* Read until EOF or until read() would block. */
1573 data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read);
1574 if (data == NULL)
1575 goto cleanup;
1576 if (data != Py_None && !PyBytes_Check(data)) {
1577 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1578 goto cleanup;
1579 }
1580 if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1581 if (current_size == 0) {
1582 res = data;
1583 goto cleanup;
1584 }
1585 else {
1586 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1587 res = tmp;
1588 goto cleanup;
1589 }
1590 }
1591 current_size += PyBytes_GET_SIZE(data);
1592 if (self->abs_pos != -1)
1593 self->abs_pos += PyBytes_GET_SIZE(data);
1594 }
1595 cleanup:
1596 /* res is either NULL or a borrowed ref */
1597 Py_XINCREF(res);
1598 Py_XDECREF(data);
1599 Py_XDECREF(tmp);
1600 Py_XDECREF(chunks);
1601 return res;
1602 }
1603
1604 /* Read n bytes from the buffer if it can, otherwise return None.
1605 This function is simple enough that it can run unlocked. */
1606 static PyObject *
_bufferedreader_read_fast(buffered * self,Py_ssize_t n)1607 _bufferedreader_read_fast(buffered *self, Py_ssize_t n)
1608 {
1609 Py_ssize_t current_size;
1610
1611 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1612 if (n <= current_size) {
1613 /* Fast path: the data to read is fully buffered. */
1614 PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1615 if (res != NULL)
1616 self->pos += n;
1617 return res;
1618 }
1619 Py_RETURN_NONE;
1620 }
1621
1622 /* Generic read function: read from the stream until enough bytes are read,
1623 * or until an EOF occurs or until read() would block.
1624 */
1625 static PyObject *
_bufferedreader_read_generic(buffered * self,Py_ssize_t n)1626 _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
1627 {
1628 PyObject *res = NULL;
1629 Py_ssize_t current_size, remaining, written;
1630 char *out;
1631
1632 current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1633 if (n <= current_size)
1634 return _bufferedreader_read_fast(self, n);
1635
1636 res = PyBytes_FromStringAndSize(NULL, n);
1637 if (res == NULL)
1638 goto error;
1639 out = PyBytes_AS_STRING(res);
1640 remaining = n;
1641 written = 0;
1642 if (current_size > 0) {
1643 memcpy(out, self->buffer + self->pos, current_size);
1644 remaining -= current_size;
1645 written += current_size;
1646 self->pos += current_size;
1647 }
1648 /* Flush the write buffer if necessary */
1649 if (self->writable) {
1650 PyObject *r = buffered_flush_and_rewind_unlocked(self);
1651 if (r == NULL)
1652 goto error;
1653 Py_DECREF(r);
1654 }
1655 _bufferedreader_reset_buf(self);
1656 while (remaining > 0) {
1657 /* We want to read a whole block at the end into buffer.
1658 If we had readv() we could do this in one pass. */
1659 Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1660 if (r == 0)
1661 break;
1662 r = _bufferedreader_raw_read(self, out + written, r);
1663 if (r == -1)
1664 goto error;
1665 if (r == 0 || r == -2) {
1666 /* EOF occurred or read() would block. */
1667 if (r == 0 || written > 0) {
1668 if (_PyBytes_Resize(&res, written))
1669 goto error;
1670 return res;
1671 }
1672 Py_DECREF(res);
1673 Py_RETURN_NONE;
1674 }
1675 remaining -= r;
1676 written += r;
1677 }
1678 assert(remaining <= self->buffer_size);
1679 self->pos = 0;
1680 self->raw_pos = 0;
1681 self->read_end = 0;
1682 /* NOTE: when the read is satisfied, we avoid issuing any additional
1683 reads, which could block indefinitely (e.g. on a socket).
1684 See issue #9550. */
1685 while (remaining > 0 && self->read_end < self->buffer_size) {
1686 Py_ssize_t r = _bufferedreader_fill_buffer(self);
1687 if (r == -1)
1688 goto error;
1689 if (r == 0 || r == -2) {
1690 /* EOF occurred or read() would block. */
1691 if (r == 0 || written > 0) {
1692 if (_PyBytes_Resize(&res, written))
1693 goto error;
1694 return res;
1695 }
1696 Py_DECREF(res);
1697 Py_RETURN_NONE;
1698 }
1699 if (remaining > r) {
1700 memcpy(out + written, self->buffer + self->pos, r);
1701 written += r;
1702 self->pos += r;
1703 remaining -= r;
1704 }
1705 else if (remaining > 0) {
1706 memcpy(out + written, self->buffer + self->pos, remaining);
1707 written += remaining;
1708 self->pos += remaining;
1709 remaining = 0;
1710 }
1711 if (remaining == 0)
1712 break;
1713 }
1714
1715 return res;
1716
1717 error:
1718 Py_XDECREF(res);
1719 return NULL;
1720 }
1721
1722 static PyObject *
_bufferedreader_peek_unlocked(buffered * self)1723 _bufferedreader_peek_unlocked(buffered *self)
1724 {
1725 Py_ssize_t have, r;
1726
1727 have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1728 /* Constraints:
1729 1. we don't want to advance the file position.
1730 2. we don't want to lose block alignment, so we can't shift the buffer
1731 to make some place.
1732 Therefore, we either return `have` bytes (if > 0), or a full buffer.
1733 */
1734 if (have > 0) {
1735 return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1736 }
1737
1738 /* Fill the buffer from the raw stream, and copy it to the result. */
1739 _bufferedreader_reset_buf(self);
1740 r = _bufferedreader_fill_buffer(self);
1741 if (r == -1)
1742 return NULL;
1743 if (r == -2)
1744 r = 0;
1745 self->pos = 0;
1746 return PyBytes_FromStringAndSize(self->buffer, r);
1747 }
1748
1749
1750
1751 /*
1752 * class BufferedWriter
1753 */
1754 static void
_bufferedwriter_reset_buf(buffered * self)1755 _bufferedwriter_reset_buf(buffered *self)
1756 {
1757 self->write_pos = 0;
1758 self->write_end = -1;
1759 }
1760
1761 /*[clinic input]
1762 _io.BufferedWriter.__init__
1763 raw: object
1764 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
1765
1766 A buffer for a writeable sequential RawIO object.
1767
1768 The constructor creates a BufferedWriter for the given writeable raw
1769 stream. If the buffer_size is not given, it defaults to
1770 DEFAULT_BUFFER_SIZE.
1771 [clinic start generated code]*/
1772
1773 static int
_io_BufferedWriter___init___impl(buffered * self,PyObject * raw,Py_ssize_t buffer_size)1774 _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1775 Py_ssize_t buffer_size)
1776 /*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1777 {
1778 self->ok = 0;
1779 self->detached = 0;
1780
1781 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
1782 return -1;
1783
1784 Py_INCREF(raw);
1785 Py_XSETREF(self->raw, raw);
1786 self->readable = 0;
1787 self->writable = 1;
1788
1789 self->buffer_size = buffer_size;
1790 if (_buffered_init(self) < 0)
1791 return -1;
1792 _bufferedwriter_reset_buf(self);
1793 self->pos = 0;
1794
1795 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
1796 Py_IS_TYPE(raw, &PyFileIO_Type));
1797
1798 self->ok = 1;
1799 return 0;
1800 }
1801
1802 static Py_ssize_t
_bufferedwriter_raw_write(buffered * self,char * start,Py_ssize_t len)1803 _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
1804 {
1805 Py_buffer buf;
1806 PyObject *memobj, *res;
1807 Py_ssize_t n;
1808 int errnum;
1809 /* NOTE: the buffer needn't be released as its object is NULL. */
1810 if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1811 return -1;
1812 memobj = PyMemoryView_FromBuffer(&buf);
1813 if (memobj == NULL)
1814 return -1;
1815 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1816 occurs so we needn't do it ourselves.
1817 We then retry writing, ignoring the signal if no handler has
1818 raised (see issue #10956).
1819 */
1820 do {
1821 errno = 0;
1822 res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj);
1823 errnum = errno;
1824 } while (res == NULL && _PyIO_trap_eintr());
1825 Py_DECREF(memobj);
1826 if (res == NULL)
1827 return -1;
1828 if (res == Py_None) {
1829 /* Non-blocking stream would have blocked. Special return code!
1830 Being paranoid we reset errno in case it is changed by code
1831 triggered by a decref. errno is used by _set_BlockingIOError(). */
1832 Py_DECREF(res);
1833 errno = errnum;
1834 return -2;
1835 }
1836 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1837 Py_DECREF(res);
1838 if (n < 0 || n > len) {
1839 PyErr_Format(PyExc_OSError,
1840 "raw write() returned invalid length %zd "
1841 "(should have been between 0 and %zd)", n, len);
1842 return -1;
1843 }
1844 if (n > 0 && self->abs_pos != -1)
1845 self->abs_pos += n;
1846 return n;
1847 }
1848
1849 static PyObject *
_bufferedwriter_flush_unlocked(buffered * self)1850 _bufferedwriter_flush_unlocked(buffered *self)
1851 {
1852 Py_ssize_t written = 0;
1853 Py_off_t n, rewind;
1854
1855 if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1856 goto end;
1857 /* First, rewind */
1858 rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1859 if (rewind != 0) {
1860 n = _buffered_raw_seek(self, -rewind, 1);
1861 if (n < 0) {
1862 goto error;
1863 }
1864 self->raw_pos -= rewind;
1865 }
1866 while (self->write_pos < self->write_end) {
1867 n = _bufferedwriter_raw_write(self,
1868 self->buffer + self->write_pos,
1869 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1870 Py_off_t, Py_ssize_t));
1871 if (n == -1) {
1872 goto error;
1873 }
1874 else if (n == -2) {
1875 _set_BlockingIOError("write could not complete without blocking",
1876 0);
1877 goto error;
1878 }
1879 self->write_pos += n;
1880 self->raw_pos = self->write_pos;
1881 written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
1882 /* Partial writes can return successfully when interrupted by a
1883 signal (see write(2)). We must run signal handlers before
1884 blocking another time, possibly indefinitely. */
1885 if (PyErr_CheckSignals() < 0)
1886 goto error;
1887 }
1888
1889
1890 end:
1891 /* This ensures that after return from this function,
1892 VALID_WRITE_BUFFER(self) returns false.
1893
1894 This is a required condition because when a tell() is called
1895 after flushing and if VALID_READ_BUFFER(self) is false, we need
1896 VALID_WRITE_BUFFER(self) to be false to have
1897 RAW_OFFSET(self) == 0.
1898
1899 Issue: https://bugs.python.org/issue32228 */
1900 _bufferedwriter_reset_buf(self);
1901 Py_RETURN_NONE;
1902
1903 error:
1904 return NULL;
1905 }
1906
1907 /*[clinic input]
1908 _io.BufferedWriter.write
1909 buffer: Py_buffer
1910 /
1911 [clinic start generated code]*/
1912
1913 static PyObject *
_io_BufferedWriter_write_impl(buffered * self,Py_buffer * buffer)1914 _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1915 /*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
1916 {
1917 PyObject *res = NULL;
1918 Py_ssize_t written, avail, remaining;
1919 Py_off_t offset;
1920
1921 CHECK_INITIALIZED(self)
1922
1923 if (!ENTER_BUFFERED(self))
1924 return NULL;
1925
1926 /* Issue #31976: Check for closed file after acquiring the lock. Another
1927 thread could be holding the lock while closing the file. */
1928 if (IS_CLOSED(self)) {
1929 PyErr_SetString(PyExc_ValueError, "write to closed file");
1930 goto error;
1931 }
1932
1933 /* Fast path: the data to write can be fully buffered. */
1934 if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1935 self->pos = 0;
1936 self->raw_pos = 0;
1937 }
1938 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1939 if (buffer->len <= avail) {
1940 memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
1941 if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
1942 self->write_pos = self->pos;
1943 }
1944 ADJUST_POSITION(self, self->pos + buffer->len);
1945 if (self->pos > self->write_end)
1946 self->write_end = self->pos;
1947 written = buffer->len;
1948 goto end;
1949 }
1950
1951 /* First write the current buffer */
1952 res = _bufferedwriter_flush_unlocked(self);
1953 if (res == NULL) {
1954 Py_ssize_t *w = _buffered_check_blocking_error();
1955 if (w == NULL)
1956 goto error;
1957 if (self->readable)
1958 _bufferedreader_reset_buf(self);
1959 /* Make some place by shifting the buffer. */
1960 assert(VALID_WRITE_BUFFER(self));
1961 memmove(self->buffer, self->buffer + self->write_pos,
1962 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1963 Py_off_t, Py_ssize_t));
1964 self->write_end -= self->write_pos;
1965 self->raw_pos -= self->write_pos;
1966 self->pos -= self->write_pos;
1967 self->write_pos = 0;
1968 avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1969 Py_off_t, Py_ssize_t);
1970 if (buffer->len <= avail) {
1971 /* Everything can be buffered */
1972 PyErr_Clear();
1973 memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1974 self->write_end += buffer->len;
1975 self->pos += buffer->len;
1976 written = buffer->len;
1977 goto end;
1978 }
1979 /* Buffer as much as possible. */
1980 memcpy(self->buffer + self->write_end, buffer->buf, avail);
1981 self->write_end += avail;
1982 self->pos += avail;
1983 /* XXX Modifying the existing exception e using the pointer w
1984 will change e.characters_written but not e.args[2].
1985 Therefore we just replace with a new error. */
1986 _set_BlockingIOError("write could not complete without blocking",
1987 avail);
1988 goto error;
1989 }
1990 Py_CLEAR(res);
1991
1992 /* Adjust the raw stream position if it is away from the logical stream
1993 position. This happens if the read buffer has been filled but not
1994 modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
1995 the raw stream by itself).
1996 Fixes issue #6629.
1997 */
1998 offset = RAW_OFFSET(self);
1999 if (offset != 0) {
2000 if (_buffered_raw_seek(self, -offset, 1) < 0)
2001 goto error;
2002 self->raw_pos -= offset;
2003 }
2004
2005 /* Then write buf itself. At this point the buffer has been emptied. */
2006 remaining = buffer->len;
2007 written = 0;
2008 while (remaining > self->buffer_size) {
2009 Py_ssize_t n = _bufferedwriter_raw_write(
2010 self, (char *) buffer->buf + written, buffer->len - written);
2011 if (n == -1) {
2012 goto error;
2013 } else if (n == -2) {
2014 /* Write failed because raw file is non-blocking */
2015 if (remaining > self->buffer_size) {
2016 /* Can't buffer everything, still buffer as much as possible */
2017 memcpy(self->buffer,
2018 (char *) buffer->buf + written, self->buffer_size);
2019 self->raw_pos = 0;
2020 ADJUST_POSITION(self, self->buffer_size);
2021 self->write_end = self->buffer_size;
2022 written += self->buffer_size;
2023 _set_BlockingIOError("write could not complete without "
2024 "blocking", written);
2025 goto error;
2026 }
2027 PyErr_Clear();
2028 break;
2029 }
2030 written += n;
2031 remaining -= n;
2032 /* Partial writes can return successfully when interrupted by a
2033 signal (see write(2)). We must run signal handlers before
2034 blocking another time, possibly indefinitely. */
2035 if (PyErr_CheckSignals() < 0)
2036 goto error;
2037 }
2038 if (self->readable)
2039 _bufferedreader_reset_buf(self);
2040 if (remaining > 0) {
2041 memcpy(self->buffer, (char *) buffer->buf + written, remaining);
2042 written += remaining;
2043 }
2044 self->write_pos = 0;
2045 /* TODO: sanity check (remaining >= 0) */
2046 self->write_end = remaining;
2047 ADJUST_POSITION(self, remaining);
2048 self->raw_pos = 0;
2049
2050 end:
2051 res = PyLong_FromSsize_t(written);
2052
2053 error:
2054 LEAVE_BUFFERED(self)
2055 return res;
2056 }
2057
2058
2059
2060 /*
2061 * BufferedRWPair
2062 */
2063
2064 /* XXX The usefulness of this (compared to having two separate IO objects) is
2065 * questionable.
2066 */
2067
2068 typedef struct {
2069 PyObject_HEAD
2070 buffered *reader;
2071 buffered *writer;
2072 PyObject *dict;
2073 PyObject *weakreflist;
2074 } rwpair;
2075
2076 /*[clinic input]
2077 _io.BufferedRWPair.__init__
2078 reader: object
2079 writer: object
2080 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2081 /
2082
2083 A buffered reader and writer object together.
2084
2085 A buffered reader object and buffered writer object put together to
2086 form a sequential IO object that can read and write. This is typically
2087 used with a socket or two-way pipe.
2088
2089 reader and writer are RawIOBase objects that are readable and
2090 writeable respectively. If the buffer_size is omitted it defaults to
2091 DEFAULT_BUFFER_SIZE.
2092 [clinic start generated code]*/
2093
2094 static int
_io_BufferedRWPair___init___impl(rwpair * self,PyObject * reader,PyObject * writer,Py_ssize_t buffer_size)2095 _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2096 PyObject *writer, Py_ssize_t buffer_size)
2097 /*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
2098 {
2099 if (_PyIOBase_check_readable(reader, Py_True) == NULL)
2100 return -1;
2101 if (_PyIOBase_check_writable(writer, Py_True) == NULL)
2102 return -1;
2103
2104 self->reader = (buffered *) PyObject_CallFunction(
2105 (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
2106 if (self->reader == NULL)
2107 return -1;
2108
2109 self->writer = (buffered *) PyObject_CallFunction(
2110 (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
2111 if (self->writer == NULL) {
2112 Py_CLEAR(self->reader);
2113 return -1;
2114 }
2115
2116 return 0;
2117 }
2118
2119 static int
bufferedrwpair_traverse(rwpair * self,visitproc visit,void * arg)2120 bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
2121 {
2122 Py_VISIT(self->dict);
2123 return 0;
2124 }
2125
2126 static int
bufferedrwpair_clear(rwpair * self)2127 bufferedrwpair_clear(rwpair *self)
2128 {
2129 Py_CLEAR(self->reader);
2130 Py_CLEAR(self->writer);
2131 Py_CLEAR(self->dict);
2132 return 0;
2133 }
2134
2135 static void
bufferedrwpair_dealloc(rwpair * self)2136 bufferedrwpair_dealloc(rwpair *self)
2137 {
2138 _PyObject_GC_UNTRACK(self);
2139 if (self->weakreflist != NULL)
2140 PyObject_ClearWeakRefs((PyObject *)self);
2141 Py_CLEAR(self->reader);
2142 Py_CLEAR(self->writer);
2143 Py_CLEAR(self->dict);
2144 Py_TYPE(self)->tp_free((PyObject *) self);
2145 }
2146
2147 static PyObject *
_forward_call(buffered * self,_Py_Identifier * name,PyObject * args)2148 _forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
2149 {
2150 PyObject *func, *ret;
2151 if (self == NULL) {
2152 PyErr_SetString(PyExc_ValueError,
2153 "I/O operation on uninitialized object");
2154 return NULL;
2155 }
2156
2157 func = _PyObject_GetAttrId((PyObject *)self, name);
2158 if (func == NULL) {
2159 PyErr_SetString(PyExc_AttributeError, name->string);
2160 return NULL;
2161 }
2162
2163 ret = PyObject_CallObject(func, args);
2164 Py_DECREF(func);
2165 return ret;
2166 }
2167
2168 static PyObject *
bufferedrwpair_read(rwpair * self,PyObject * args)2169 bufferedrwpair_read(rwpair *self, PyObject *args)
2170 {
2171 return _forward_call(self->reader, &PyId_read, args);
2172 }
2173
2174 static PyObject *
bufferedrwpair_peek(rwpair * self,PyObject * args)2175 bufferedrwpair_peek(rwpair *self, PyObject *args)
2176 {
2177 return _forward_call(self->reader, &PyId_peek, args);
2178 }
2179
2180 static PyObject *
bufferedrwpair_read1(rwpair * self,PyObject * args)2181 bufferedrwpair_read1(rwpair *self, PyObject *args)
2182 {
2183 return _forward_call(self->reader, &PyId_read1, args);
2184 }
2185
2186 static PyObject *
bufferedrwpair_readinto(rwpair * self,PyObject * args)2187 bufferedrwpair_readinto(rwpair *self, PyObject *args)
2188 {
2189 return _forward_call(self->reader, &PyId_readinto, args);
2190 }
2191
2192 static PyObject *
bufferedrwpair_readinto1(rwpair * self,PyObject * args)2193 bufferedrwpair_readinto1(rwpair *self, PyObject *args)
2194 {
2195 return _forward_call(self->reader, &PyId_readinto1, args);
2196 }
2197
2198 static PyObject *
bufferedrwpair_write(rwpair * self,PyObject * args)2199 bufferedrwpair_write(rwpair *self, PyObject *args)
2200 {
2201 return _forward_call(self->writer, &PyId_write, args);
2202 }
2203
2204 static PyObject *
bufferedrwpair_flush(rwpair * self,PyObject * Py_UNUSED (ignored))2205 bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored))
2206 {
2207 return _forward_call(self->writer, &PyId_flush, NULL);
2208 }
2209
2210 static PyObject *
bufferedrwpair_readable(rwpair * self,PyObject * Py_UNUSED (ignored))2211 bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored))
2212 {
2213 return _forward_call(self->reader, &PyId_readable, NULL);
2214 }
2215
2216 static PyObject *
bufferedrwpair_writable(rwpair * self,PyObject * Py_UNUSED (ignored))2217 bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
2218 {
2219 return _forward_call(self->writer, &PyId_writable, NULL);
2220 }
2221
2222 static PyObject *
bufferedrwpair_close(rwpair * self,PyObject * Py_UNUSED (ignored))2223 bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
2224 {
2225 PyObject *exc = NULL, *val, *tb;
2226 PyObject *ret = _forward_call(self->writer, &PyId_close, NULL);
2227 if (ret == NULL)
2228 PyErr_Fetch(&exc, &val, &tb);
2229 else
2230 Py_DECREF(ret);
2231 ret = _forward_call(self->reader, &PyId_close, NULL);
2232 if (exc != NULL) {
2233 _PyErr_ChainExceptions(exc, val, tb);
2234 Py_CLEAR(ret);
2235 }
2236 return ret;
2237 }
2238
2239 static PyObject *
bufferedrwpair_isatty(rwpair * self,PyObject * Py_UNUSED (ignored))2240 bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored))
2241 {
2242 PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL);
2243
2244 if (ret != Py_False) {
2245 /* either True or exception */
2246 return ret;
2247 }
2248 Py_DECREF(ret);
2249
2250 return _forward_call(self->reader, &PyId_isatty, NULL);
2251 }
2252
2253 static PyObject *
bufferedrwpair_closed_get(rwpair * self,void * context)2254 bufferedrwpair_closed_get(rwpair *self, void *context)
2255 {
2256 if (self->writer == NULL) {
2257 PyErr_SetString(PyExc_RuntimeError,
2258 "the BufferedRWPair object is being garbage-collected");
2259 return NULL;
2260 }
2261 return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2262 }
2263
2264
2265
2266 /*
2267 * BufferedRandom
2268 */
2269
2270 /*[clinic input]
2271 _io.BufferedRandom.__init__
2272 raw: object
2273 buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2274
2275 A buffered interface to random access streams.
2276
2277 The constructor creates a reader and writer for a seekable stream,
2278 raw, given in the first argument. If the buffer_size is omitted it
2279 defaults to DEFAULT_BUFFER_SIZE.
2280 [clinic start generated code]*/
2281
2282 static int
_io_BufferedRandom___init___impl(buffered * self,PyObject * raw,Py_ssize_t buffer_size)2283 _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2284 Py_ssize_t buffer_size)
2285 /*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2286 {
2287 self->ok = 0;
2288 self->detached = 0;
2289
2290 if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2291 return -1;
2292 if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2293 return -1;
2294 if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2295 return -1;
2296
2297 Py_INCREF(raw);
2298 Py_XSETREF(self->raw, raw);
2299 self->buffer_size = buffer_size;
2300 self->readable = 1;
2301 self->writable = 1;
2302
2303 if (_buffered_init(self) < 0)
2304 return -1;
2305 _bufferedreader_reset_buf(self);
2306 _bufferedwriter_reset_buf(self);
2307 self->pos = 0;
2308
2309 self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
2310 Py_IS_TYPE(raw, &PyFileIO_Type));
2311
2312 self->ok = 1;
2313 return 0;
2314 }
2315
2316 #include "clinic/bufferedio.c.h"
2317
2318
2319 static PyMethodDef bufferediobase_methods[] = {
2320 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2321 {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2322 {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2323 _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2324 _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2325 {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2326 {NULL, NULL}
2327 };
2328
2329 PyTypeObject PyBufferedIOBase_Type = {
2330 PyVarObject_HEAD_INIT(NULL, 0)
2331 "_io._BufferedIOBase", /*tp_name*/
2332 0, /*tp_basicsize*/
2333 0, /*tp_itemsize*/
2334 0, /*tp_dealloc*/
2335 0, /*tp_vectorcall_offset*/
2336 0, /*tp_getattr*/
2337 0, /*tp_setattr*/
2338 0, /*tp_as_async*/
2339 0, /*tp_repr*/
2340 0, /*tp_as_number*/
2341 0, /*tp_as_sequence*/
2342 0, /*tp_as_mapping*/
2343 0, /*tp_hash */
2344 0, /*tp_call*/
2345 0, /*tp_str*/
2346 0, /*tp_getattro*/
2347 0, /*tp_setattro*/
2348 0, /*tp_as_buffer*/
2349 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
2350 bufferediobase_doc, /* tp_doc */
2351 0, /* tp_traverse */
2352 0, /* tp_clear */
2353 0, /* tp_richcompare */
2354 0, /* tp_weaklistoffset */
2355 0, /* tp_iter */
2356 0, /* tp_iternext */
2357 bufferediobase_methods, /* tp_methods */
2358 0, /* tp_members */
2359 0, /* tp_getset */
2360 &PyIOBase_Type, /* tp_base */
2361 0, /* tp_dict */
2362 0, /* tp_descr_get */
2363 0, /* tp_descr_set */
2364 0, /* tp_dictoffset */
2365 0, /* tp_init */
2366 0, /* tp_alloc */
2367 0, /* tp_new */
2368 0, /* tp_free */
2369 0, /* tp_is_gc */
2370 0, /* tp_bases */
2371 0, /* tp_mro */
2372 0, /* tp_cache */
2373 0, /* tp_subclasses */
2374 0, /* tp_weaklist */
2375 0, /* tp_del */
2376 0, /* tp_version_tag */
2377 0, /* tp_finalize */
2378 };
2379
2380
2381 static PyMethodDef bufferedreader_methods[] = {
2382 /* BufferedIOMixin methods */
2383 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2384 {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2385 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2386 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2387 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2388 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2389 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2390 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2391
2392 _IO__BUFFERED_READ_METHODDEF
2393 _IO__BUFFERED_PEEK_METHODDEF
2394 _IO__BUFFERED_READ1_METHODDEF
2395 _IO__BUFFERED_READINTO_METHODDEF
2396 _IO__BUFFERED_READINTO1_METHODDEF
2397 _IO__BUFFERED_READLINE_METHODDEF
2398 _IO__BUFFERED_SEEK_METHODDEF
2399 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2400 _IO__BUFFERED_TRUNCATE_METHODDEF
2401 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2402 {NULL, NULL}
2403 };
2404
2405 static PyMemberDef bufferedreader_members[] = {
2406 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2407 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2408 {NULL}
2409 };
2410
2411 static PyGetSetDef bufferedreader_getset[] = {
2412 {"closed", (getter)buffered_closed_get, NULL, NULL},
2413 {"name", (getter)buffered_name_get, NULL, NULL},
2414 {"mode", (getter)buffered_mode_get, NULL, NULL},
2415 {NULL}
2416 };
2417
2418
2419 PyTypeObject PyBufferedReader_Type = {
2420 PyVarObject_HEAD_INIT(NULL, 0)
2421 "_io.BufferedReader", /*tp_name*/
2422 sizeof(buffered), /*tp_basicsize*/
2423 0, /*tp_itemsize*/
2424 (destructor)buffered_dealloc, /*tp_dealloc*/
2425 0, /*tp_vectorcall_offset*/
2426 0, /*tp_getattr*/
2427 0, /*tp_setattr*/
2428 0, /*tp_as_async*/
2429 (reprfunc)buffered_repr, /*tp_repr*/
2430 0, /*tp_as_number*/
2431 0, /*tp_as_sequence*/
2432 0, /*tp_as_mapping*/
2433 0, /*tp_hash */
2434 0, /*tp_call*/
2435 0, /*tp_str*/
2436 0, /*tp_getattro*/
2437 0, /*tp_setattro*/
2438 0, /*tp_as_buffer*/
2439 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2440 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2441 _io_BufferedReader___init____doc__, /* tp_doc */
2442 (traverseproc)buffered_traverse, /* tp_traverse */
2443 (inquiry)buffered_clear, /* tp_clear */
2444 0, /* tp_richcompare */
2445 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2446 0, /* tp_iter */
2447 (iternextfunc)buffered_iternext, /* tp_iternext */
2448 bufferedreader_methods, /* tp_methods */
2449 bufferedreader_members, /* tp_members */
2450 bufferedreader_getset, /* tp_getset */
2451 0, /* tp_base */
2452 0, /* tp_dict */
2453 0, /* tp_descr_get */
2454 0, /* tp_descr_set */
2455 offsetof(buffered, dict), /* tp_dictoffset */
2456 _io_BufferedReader___init__, /* tp_init */
2457 0, /* tp_alloc */
2458 PyType_GenericNew, /* tp_new */
2459 0, /* tp_free */
2460 0, /* tp_is_gc */
2461 0, /* tp_bases */
2462 0, /* tp_mro */
2463 0, /* tp_cache */
2464 0, /* tp_subclasses */
2465 0, /* tp_weaklist */
2466 0, /* tp_del */
2467 0, /* tp_version_tag */
2468 0, /* tp_finalize */
2469 };
2470
2471
2472 static PyMethodDef bufferedwriter_methods[] = {
2473 /* BufferedIOMixin methods */
2474 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2475 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2476 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2477 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2478 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2479 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2480 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2481
2482 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2483 _IO__BUFFERED_TRUNCATE_METHODDEF
2484 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2485 _IO__BUFFERED_SEEK_METHODDEF
2486 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2487 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2488 {NULL, NULL}
2489 };
2490
2491 static PyMemberDef bufferedwriter_members[] = {
2492 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2493 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2494 {NULL}
2495 };
2496
2497 static PyGetSetDef bufferedwriter_getset[] = {
2498 {"closed", (getter)buffered_closed_get, NULL, NULL},
2499 {"name", (getter)buffered_name_get, NULL, NULL},
2500 {"mode", (getter)buffered_mode_get, NULL, NULL},
2501 {NULL}
2502 };
2503
2504
2505 PyTypeObject PyBufferedWriter_Type = {
2506 PyVarObject_HEAD_INIT(NULL, 0)
2507 "_io.BufferedWriter", /*tp_name*/
2508 sizeof(buffered), /*tp_basicsize*/
2509 0, /*tp_itemsize*/
2510 (destructor)buffered_dealloc, /*tp_dealloc*/
2511 0, /*tp_vectorcall_offset*/
2512 0, /*tp_getattr*/
2513 0, /*tp_setattr*/
2514 0, /*tp_as_async*/
2515 (reprfunc)buffered_repr, /*tp_repr*/
2516 0, /*tp_as_number*/
2517 0, /*tp_as_sequence*/
2518 0, /*tp_as_mapping*/
2519 0, /*tp_hash */
2520 0, /*tp_call*/
2521 0, /*tp_str*/
2522 0, /*tp_getattro*/
2523 0, /*tp_setattro*/
2524 0, /*tp_as_buffer*/
2525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2526 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2527 _io_BufferedWriter___init____doc__, /* tp_doc */
2528 (traverseproc)buffered_traverse, /* tp_traverse */
2529 (inquiry)buffered_clear, /* tp_clear */
2530 0, /* tp_richcompare */
2531 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2532 0, /* tp_iter */
2533 0, /* tp_iternext */
2534 bufferedwriter_methods, /* tp_methods */
2535 bufferedwriter_members, /* tp_members */
2536 bufferedwriter_getset, /* tp_getset */
2537 0, /* tp_base */
2538 0, /* tp_dict */
2539 0, /* tp_descr_get */
2540 0, /* tp_descr_set */
2541 offsetof(buffered, dict), /* tp_dictoffset */
2542 _io_BufferedWriter___init__, /* tp_init */
2543 0, /* tp_alloc */
2544 PyType_GenericNew, /* tp_new */
2545 0, /* tp_free */
2546 0, /* tp_is_gc */
2547 0, /* tp_bases */
2548 0, /* tp_mro */
2549 0, /* tp_cache */
2550 0, /* tp_subclasses */
2551 0, /* tp_weaklist */
2552 0, /* tp_del */
2553 0, /* tp_version_tag */
2554 0, /* tp_finalize */
2555 };
2556
2557
2558 static PyMethodDef bufferedrwpair_methods[] = {
2559 {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2560 {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2561 {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2562 {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
2563 {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
2564
2565 {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2566 {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
2567
2568 {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2569 {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
2570
2571 {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2572 {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
2573
2574 {NULL, NULL}
2575 };
2576
2577 static PyGetSetDef bufferedrwpair_getset[] = {
2578 {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
2579 {NULL}
2580 };
2581
2582 PyTypeObject PyBufferedRWPair_Type = {
2583 PyVarObject_HEAD_INIT(NULL, 0)
2584 "_io.BufferedRWPair", /*tp_name*/
2585 sizeof(rwpair), /*tp_basicsize*/
2586 0, /*tp_itemsize*/
2587 (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
2588 0, /*tp_vectorcall_offset*/
2589 0, /*tp_getattr*/
2590 0, /*tp_setattr*/
2591 0, /*tp_as_async*/
2592 0, /*tp_repr*/
2593 0, /*tp_as_number*/
2594 0, /*tp_as_sequence*/
2595 0, /*tp_as_mapping*/
2596 0, /*tp_hash */
2597 0, /*tp_call*/
2598 0, /*tp_str*/
2599 0, /*tp_getattro*/
2600 0, /*tp_setattro*/
2601 0, /*tp_as_buffer*/
2602 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2603 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2604 _io_BufferedRWPair___init____doc__, /* tp_doc */
2605 (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2606 (inquiry)bufferedrwpair_clear, /* tp_clear */
2607 0, /* tp_richcompare */
2608 offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
2609 0, /* tp_iter */
2610 0, /* tp_iternext */
2611 bufferedrwpair_methods, /* tp_methods */
2612 0, /* tp_members */
2613 bufferedrwpair_getset, /* tp_getset */
2614 0, /* tp_base */
2615 0, /* tp_dict */
2616 0, /* tp_descr_get */
2617 0, /* tp_descr_set */
2618 offsetof(rwpair, dict), /* tp_dictoffset */
2619 _io_BufferedRWPair___init__, /* tp_init */
2620 0, /* tp_alloc */
2621 PyType_GenericNew, /* tp_new */
2622 0, /* tp_free */
2623 0, /* tp_is_gc */
2624 0, /* tp_bases */
2625 0, /* tp_mro */
2626 0, /* tp_cache */
2627 0, /* tp_subclasses */
2628 0, /* tp_weaklist */
2629 0, /* tp_del */
2630 0, /* tp_version_tag */
2631 0, /* tp_finalize */
2632 };
2633
2634
2635 static PyMethodDef bufferedrandom_methods[] = {
2636 /* BufferedIOMixin methods */
2637 {"close", (PyCFunction)buffered_close, METH_NOARGS},
2638 {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2639 {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2640 {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2641 {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2642 {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2643 {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2644 {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2645
2646 {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2647
2648 _IO__BUFFERED_SEEK_METHODDEF
2649 {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2650 _IO__BUFFERED_TRUNCATE_METHODDEF
2651 _IO__BUFFERED_READ_METHODDEF
2652 _IO__BUFFERED_READ1_METHODDEF
2653 _IO__BUFFERED_READINTO_METHODDEF
2654 _IO__BUFFERED_READINTO1_METHODDEF
2655 _IO__BUFFERED_READLINE_METHODDEF
2656 _IO__BUFFERED_PEEK_METHODDEF
2657 _IO_BUFFEREDWRITER_WRITE_METHODDEF
2658 {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2659 {NULL, NULL}
2660 };
2661
2662 static PyMemberDef bufferedrandom_members[] = {
2663 {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2664 {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2665 {NULL}
2666 };
2667
2668 static PyGetSetDef bufferedrandom_getset[] = {
2669 {"closed", (getter)buffered_closed_get, NULL, NULL},
2670 {"name", (getter)buffered_name_get, NULL, NULL},
2671 {"mode", (getter)buffered_mode_get, NULL, NULL},
2672 {NULL}
2673 };
2674
2675
2676 PyTypeObject PyBufferedRandom_Type = {
2677 PyVarObject_HEAD_INIT(NULL, 0)
2678 "_io.BufferedRandom", /*tp_name*/
2679 sizeof(buffered), /*tp_basicsize*/
2680 0, /*tp_itemsize*/
2681 (destructor)buffered_dealloc, /*tp_dealloc*/
2682 0, /*tp_vectorcall_offset*/
2683 0, /*tp_getattr*/
2684 0, /*tp_setattr*/
2685 0, /*tp_as_async*/
2686 (reprfunc)buffered_repr, /*tp_repr*/
2687 0, /*tp_as_number*/
2688 0, /*tp_as_sequence*/
2689 0, /*tp_as_mapping*/
2690 0, /*tp_hash */
2691 0, /*tp_call*/
2692 0, /*tp_str*/
2693 0, /*tp_getattro*/
2694 0, /*tp_setattro*/
2695 0, /*tp_as_buffer*/
2696 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2697 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2698 _io_BufferedRandom___init____doc__, /* tp_doc */
2699 (traverseproc)buffered_traverse, /* tp_traverse */
2700 (inquiry)buffered_clear, /* tp_clear */
2701 0, /* tp_richcompare */
2702 offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2703 0, /* tp_iter */
2704 (iternextfunc)buffered_iternext, /* tp_iternext */
2705 bufferedrandom_methods, /* tp_methods */
2706 bufferedrandom_members, /* tp_members */
2707 bufferedrandom_getset, /* tp_getset */
2708 0, /* tp_base */
2709 0, /*tp_dict*/
2710 0, /* tp_descr_get */
2711 0, /* tp_descr_set */
2712 offsetof(buffered, dict), /*tp_dictoffset*/
2713 _io_BufferedRandom___init__, /* tp_init */
2714 0, /* tp_alloc */
2715 PyType_GenericNew, /* tp_new */
2716 0, /* tp_free */
2717 0, /* tp_is_gc */
2718 0, /* tp_bases */
2719 0, /* tp_mro */
2720 0, /* tp_cache */
2721 0, /* tp_subclasses */
2722 0, /* tp_weaklist */
2723 0, /* tp_del */
2724 0, /* tp_version_tag */
2725 0, /* tp_finalize */
2726 };
2727