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