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