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