1 #include "Python.h" 2 #include "structmember.h" /* for offsetof() */ 3 #include "_iomodule.h" 4 5 /*[clinic input] 6 module _io 7 class _io.BytesIO "bytesio *" "&PyBytesIO_Type" 8 [clinic start generated code]*/ 9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/ 10 11 typedef struct { 12 PyObject_HEAD 13 PyObject *buf; 14 Py_ssize_t pos; 15 Py_ssize_t string_size; 16 PyObject *dict; 17 PyObject *weakreflist; 18 Py_ssize_t exports; 19 } bytesio; 20 21 typedef struct { 22 PyObject_HEAD 23 bytesio *source; 24 } bytesiobuf; 25 26 /* The bytesio object can be in three states: 27 * Py_REFCNT(buf) == 1, exports == 0. 28 * Py_REFCNT(buf) > 1. exports == 0, 29 first modification or export causes the internal buffer copying. 30 * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden. 31 */ 32 33 #define CHECK_CLOSED(self) \ 34 if ((self)->buf == NULL) { \ 35 PyErr_SetString(PyExc_ValueError, \ 36 "I/O operation on closed file."); \ 37 return NULL; \ 38 } 39 40 #define CHECK_EXPORTS(self) \ 41 if ((self)->exports > 0) { \ 42 PyErr_SetString(PyExc_BufferError, \ 43 "Existing exports of data: object cannot be re-sized"); \ 44 return NULL; \ 45 } 46 47 #define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1) 48 49 50 /* Internal routine to get a line from the buffer of a BytesIO 51 object. Returns the length between the current position to the 52 next newline character. */ 53 static Py_ssize_t 54 scan_eol(bytesio *self, Py_ssize_t len) 55 { 56 const char *start, *n; 57 Py_ssize_t maxlen; 58 59 assert(self->buf != NULL); 60 assert(self->pos >= 0); 61 62 if (self->pos >= self->string_size) 63 return 0; 64 65 /* Move to the end of the line, up to the end of the string, s. */ 66 maxlen = self->string_size - self->pos; 67 if (len < 0 || len > maxlen) 68 len = maxlen; 69 70 if (len) { 71 start = PyBytes_AS_STRING(self->buf) + self->pos; 72 n = memchr(start, '\n', len); 73 if (n) 74 /* Get the length from the current position to the end of 75 the line. */ 76 len = n - start + 1; 77 } 78 assert(len >= 0); 79 assert(self->pos < PY_SSIZE_T_MAX - len); 80 81 return len; 82 } 83 84 /* Internal routine for detaching the shared buffer of BytesIO objects. 85 The caller should ensure that the 'size' argument is non-negative and 86 not lesser than self->string_size. Returns 0 on success, -1 otherwise. */ 87 static int 88 unshare_buffer(bytesio *self, size_t size) 89 { 90 PyObject *new_buf; 91 assert(SHARED_BUF(self)); 92 assert(self->exports == 0); 93 assert(size >= (size_t)self->string_size); 94 new_buf = PyBytes_FromStringAndSize(NULL, size); 95 if (new_buf == NULL) 96 return -1; 97 memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf), 98 self->string_size); 99 Py_SETREF(self->buf, new_buf); 100 return 0; 101 } 102 103 /* Internal routine for changing the size of the buffer of BytesIO objects. 104 The caller should ensure that the 'size' argument is non-negative. Returns 105 0 on success, -1 otherwise. */ 106 static int 107 resize_buffer(bytesio *self, size_t size) 108 { 109 /* Here, unsigned types are used to avoid dealing with signed integer 110 overflow, which is undefined in C. */ 111 size_t alloc = PyBytes_GET_SIZE(self->buf); 112 113 assert(self->buf != NULL); 114 115 /* For simplicity, stay in the range of the signed type. Anyway, Python 116 doesn't allow strings to be longer than this. */ 117 if (size > PY_SSIZE_T_MAX) 118 goto overflow; 119 120 if (size < alloc / 2) { 121 /* Major downsize; resize down to exact size. */ 122 alloc = size + 1; 123 } 124 else if (size < alloc) { 125 /* Within allocated size; quick exit */ 126 return 0; 127 } 128 else if (size <= alloc * 1.125) { 129 /* Moderate upsize; overallocate similar to list_resize() */ 130 alloc = size + (size >> 3) + (size < 9 ? 3 : 6); 131 } 132 else { 133 /* Major upsize; resize up to exact size */ 134 alloc = size + 1; 135 } 136 137 if (alloc > ((size_t)-1) / sizeof(char)) 138 goto overflow; 139 140 if (SHARED_BUF(self)) { 141 if (unshare_buffer(self, alloc) < 0) 142 return -1; 143 } 144 else { 145 if (_PyBytes_Resize(&self->buf, alloc) < 0) 146 return -1; 147 } 148 149 return 0; 150 151 overflow: 152 PyErr_SetString(PyExc_OverflowError, 153 "new buffer size too large"); 154 return -1; 155 } 156 157 /* Internal routine for writing a string of bytes to the buffer of a BytesIO 158 object. Returns the number of bytes written, or -1 on error. */ 159 static Py_ssize_t 160 write_bytes(bytesio *self, const char *bytes, Py_ssize_t len) 161 { 162 size_t endpos; 163 assert(self->buf != NULL); 164 assert(self->pos >= 0); 165 assert(len >= 0); 166 167 endpos = (size_t)self->pos + len; 168 if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) { 169 if (resize_buffer(self, endpos) < 0) 170 return -1; 171 } 172 else if (SHARED_BUF(self)) { 173 if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0) 174 return -1; 175 } 176 177 if (self->pos > self->string_size) { 178 /* In case of overseek, pad with null bytes the buffer region between 179 the end of stream and the current position. 180 181 0 lo string_size hi 182 | |<---used--->|<----------available----------->| 183 | | <--to pad-->|<---to write---> | 184 0 buf position 185 */ 186 memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0', 187 (self->pos - self->string_size) * sizeof(char)); 188 } 189 190 /* Copy the data to the internal buffer, overwriting some of the existing 191 data if self->pos < self->string_size. */ 192 memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len); 193 self->pos = endpos; 194 195 /* Set the new length of the internal string if it has changed. */ 196 if ((size_t)self->string_size < endpos) { 197 self->string_size = endpos; 198 } 199 200 return len; 201 } 202 203 static PyObject * 204 bytesio_get_closed(bytesio *self) 205 { 206 if (self->buf == NULL) { 207 Py_RETURN_TRUE; 208 } 209 else { 210 Py_RETURN_FALSE; 211 } 212 } 213 214 /*[clinic input] 215 _io.BytesIO.readable 216 217 Returns True if the IO object can be read. 218 [clinic start generated code]*/ 219 220 static PyObject * 221 _io_BytesIO_readable_impl(bytesio *self) 222 /*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/ 223 { 224 CHECK_CLOSED(self); 225 Py_RETURN_TRUE; 226 } 227 228 /*[clinic input] 229 _io.BytesIO.writable 230 231 Returns True if the IO object can be written. 232 [clinic start generated code]*/ 233 234 static PyObject * 235 _io_BytesIO_writable_impl(bytesio *self) 236 /*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/ 237 { 238 CHECK_CLOSED(self); 239 Py_RETURN_TRUE; 240 } 241 242 /*[clinic input] 243 _io.BytesIO.seekable 244 245 Returns True if the IO object can be seeked. 246 [clinic start generated code]*/ 247 248 static PyObject * 249 _io_BytesIO_seekable_impl(bytesio *self) 250 /*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/ 251 { 252 CHECK_CLOSED(self); 253 Py_RETURN_TRUE; 254 } 255 256 /*[clinic input] 257 _io.BytesIO.flush 258 259 Does nothing. 260 [clinic start generated code]*/ 261 262 static PyObject * 263 _io_BytesIO_flush_impl(bytesio *self) 264 /*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/ 265 { 266 CHECK_CLOSED(self); 267 Py_RETURN_NONE; 268 } 269 270 /*[clinic input] 271 _io.BytesIO.getbuffer 272 273 Get a read-write view over the contents of the BytesIO object. 274 [clinic start generated code]*/ 275 276 static PyObject * 277 _io_BytesIO_getbuffer_impl(bytesio *self) 278 /*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/ 279 { 280 PyTypeObject *type = &_PyBytesIOBuffer_Type; 281 bytesiobuf *buf; 282 PyObject *view; 283 284 CHECK_CLOSED(self); 285 286 buf = (bytesiobuf *) type->tp_alloc(type, 0); 287 if (buf == NULL) 288 return NULL; 289 Py_INCREF(self); 290 buf->source = self; 291 view = PyMemoryView_FromObject((PyObject *) buf); 292 Py_DECREF(buf); 293 return view; 294 } 295 296 /*[clinic input] 297 _io.BytesIO.getvalue 298 299 Retrieve the entire contents of the BytesIO object. 300 [clinic start generated code]*/ 301 302 static PyObject * 303 _io_BytesIO_getvalue_impl(bytesio *self) 304 /*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/ 305 { 306 CHECK_CLOSED(self); 307 if (self->string_size <= 1 || self->exports > 0) 308 return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf), 309 self->string_size); 310 311 if (self->string_size != PyBytes_GET_SIZE(self->buf)) { 312 if (SHARED_BUF(self)) { 313 if (unshare_buffer(self, self->string_size) < 0) 314 return NULL; 315 } 316 else { 317 if (_PyBytes_Resize(&self->buf, self->string_size) < 0) 318 return NULL; 319 } 320 } 321 Py_INCREF(self->buf); 322 return self->buf; 323 } 324 325 /*[clinic input] 326 _io.BytesIO.isatty 327 328 Always returns False. 329 330 BytesIO objects are not connected to a TTY-like device. 331 [clinic start generated code]*/ 332 333 static PyObject * 334 _io_BytesIO_isatty_impl(bytesio *self) 335 /*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/ 336 { 337 CHECK_CLOSED(self); 338 Py_RETURN_FALSE; 339 } 340 341 /*[clinic input] 342 _io.BytesIO.tell 343 344 Current file position, an integer. 345 [clinic start generated code]*/ 346 347 static PyObject * 348 _io_BytesIO_tell_impl(bytesio *self) 349 /*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/ 350 { 351 CHECK_CLOSED(self); 352 return PyLong_FromSsize_t(self->pos); 353 } 354 355 static PyObject * 356 read_bytes(bytesio *self, Py_ssize_t size) 357 { 358 char *output; 359 360 assert(self->buf != NULL); 361 assert(size <= self->string_size); 362 if (size > 1 && 363 self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && 364 self->exports == 0) { 365 self->pos += size; 366 Py_INCREF(self->buf); 367 return self->buf; 368 } 369 370 output = PyBytes_AS_STRING(self->buf) + self->pos; 371 self->pos += size; 372 return PyBytes_FromStringAndSize(output, size); 373 } 374 375 /*[clinic input] 376 _io.BytesIO.read 377 size as arg: object = None 378 / 379 380 Read at most size bytes, returned as a bytes object. 381 382 If the size argument is negative, read until EOF is reached. 383 Return an empty bytes object at EOF. 384 [clinic start generated code]*/ 385 386 static PyObject * 387 _io_BytesIO_read_impl(bytesio *self, PyObject *arg) 388 /*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/ 389 { 390 Py_ssize_t size, n; 391 392 CHECK_CLOSED(self); 393 394 if (PyLong_Check(arg)) { 395 size = PyLong_AsSsize_t(arg); 396 if (size == -1 && PyErr_Occurred()) 397 return NULL; 398 } 399 else if (arg == Py_None) { 400 /* Read until EOF is reached, by default. */ 401 size = -1; 402 } 403 else { 404 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 405 Py_TYPE(arg)->tp_name); 406 return NULL; 407 } 408 409 /* adjust invalid sizes */ 410 n = self->string_size - self->pos; 411 if (size < 0 || size > n) { 412 size = n; 413 if (size < 0) 414 size = 0; 415 } 416 417 return read_bytes(self, size); 418 } 419 420 421 /*[clinic input] 422 _io.BytesIO.read1 423 size: object 424 / 425 426 Read at most size bytes, returned as a bytes object. 427 428 If the size argument is negative or omitted, read until EOF is reached. 429 Return an empty bytes object at EOF. 430 [clinic start generated code]*/ 431 432 static PyObject * 433 _io_BytesIO_read1(bytesio *self, PyObject *size) 434 /*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/ 435 { 436 return _io_BytesIO_read_impl(self, size); 437 } 438 439 /*[clinic input] 440 _io.BytesIO.readline 441 size as arg: object = None 442 / 443 444 Next line from the file, as a bytes object. 445 446 Retain newline. A non-negative size argument limits the maximum 447 number of bytes to return (an incomplete line may be returned then). 448 Return an empty bytes object at EOF. 449 [clinic start generated code]*/ 450 451 static PyObject * 452 _io_BytesIO_readline_impl(bytesio *self, PyObject *arg) 453 /*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/ 454 { 455 Py_ssize_t size, n; 456 457 CHECK_CLOSED(self); 458 459 if (PyLong_Check(arg)) { 460 size = PyLong_AsSsize_t(arg); 461 if (size == -1 && PyErr_Occurred()) 462 return NULL; 463 } 464 else if (arg == Py_None) { 465 /* No size limit, by default. */ 466 size = -1; 467 } 468 else { 469 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 470 Py_TYPE(arg)->tp_name); 471 return NULL; 472 } 473 474 n = scan_eol(self, size); 475 476 return read_bytes(self, n); 477 } 478 479 /*[clinic input] 480 _io.BytesIO.readlines 481 size as arg: object = None 482 / 483 484 List of bytes objects, each a line from the file. 485 486 Call readline() repeatedly and return a list of the lines so read. 487 The optional size argument, if given, is an approximate bound on the 488 total number of bytes in the lines returned. 489 [clinic start generated code]*/ 490 491 static PyObject * 492 _io_BytesIO_readlines_impl(bytesio *self, PyObject *arg) 493 /*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/ 494 { 495 Py_ssize_t maxsize, size, n; 496 PyObject *result, *line; 497 char *output; 498 499 CHECK_CLOSED(self); 500 501 if (PyLong_Check(arg)) { 502 maxsize = PyLong_AsSsize_t(arg); 503 if (maxsize == -1 && PyErr_Occurred()) 504 return NULL; 505 } 506 else if (arg == Py_None) { 507 /* No size limit, by default. */ 508 maxsize = -1; 509 } 510 else { 511 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 512 Py_TYPE(arg)->tp_name); 513 return NULL; 514 } 515 516 size = 0; 517 result = PyList_New(0); 518 if (!result) 519 return NULL; 520 521 output = PyBytes_AS_STRING(self->buf) + self->pos; 522 while ((n = scan_eol(self, -1)) != 0) { 523 self->pos += n; 524 line = PyBytes_FromStringAndSize(output, n); 525 if (!line) 526 goto on_error; 527 if (PyList_Append(result, line) == -1) { 528 Py_DECREF(line); 529 goto on_error; 530 } 531 Py_DECREF(line); 532 size += n; 533 if (maxsize > 0 && size >= maxsize) 534 break; 535 output += n; 536 } 537 return result; 538 539 on_error: 540 Py_DECREF(result); 541 return NULL; 542 } 543 544 /*[clinic input] 545 _io.BytesIO.readinto 546 buffer: Py_buffer(accept={rwbuffer}) 547 / 548 549 Read bytes into buffer. 550 551 Returns number of bytes read (0 for EOF), or None if the object 552 is set not to block and has no data to read. 553 [clinic start generated code]*/ 554 555 static PyObject * 556 _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer) 557 /*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/ 558 { 559 Py_ssize_t len, n; 560 561 CHECK_CLOSED(self); 562 563 /* adjust invalid sizes */ 564 len = buffer->len; 565 n = self->string_size - self->pos; 566 if (len > n) { 567 len = n; 568 if (len < 0) 569 len = 0; 570 } 571 572 memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len); 573 assert(self->pos + len < PY_SSIZE_T_MAX); 574 assert(len >= 0); 575 self->pos += len; 576 577 return PyLong_FromSsize_t(len); 578 } 579 580 /*[clinic input] 581 _io.BytesIO.truncate 582 size as arg: object = None 583 / 584 585 Truncate the file to at most size bytes. 586 587 Size defaults to the current file position, as returned by tell(). 588 The current file position is unchanged. Returns the new size. 589 [clinic start generated code]*/ 590 591 static PyObject * 592 _io_BytesIO_truncate_impl(bytesio *self, PyObject *arg) 593 /*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/ 594 { 595 Py_ssize_t size; 596 597 CHECK_CLOSED(self); 598 CHECK_EXPORTS(self); 599 600 if (PyLong_Check(arg)) { 601 size = PyLong_AsSsize_t(arg); 602 if (size == -1 && PyErr_Occurred()) 603 return NULL; 604 } 605 else if (arg == Py_None) { 606 /* Truncate to current position if no argument is passed. */ 607 size = self->pos; 608 } 609 else { 610 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 611 Py_TYPE(arg)->tp_name); 612 return NULL; 613 } 614 615 if (size < 0) { 616 PyErr_Format(PyExc_ValueError, 617 "negative size value %zd", size); 618 return NULL; 619 } 620 621 if (size < self->string_size) { 622 self->string_size = size; 623 if (resize_buffer(self, size) < 0) 624 return NULL; 625 } 626 627 return PyLong_FromSsize_t(size); 628 } 629 630 static PyObject * 631 bytesio_iternext(bytesio *self) 632 { 633 Py_ssize_t n; 634 635 CHECK_CLOSED(self); 636 637 n = scan_eol(self, -1); 638 639 if (n == 0) 640 return NULL; 641 642 return read_bytes(self, n); 643 } 644 645 /*[clinic input] 646 _io.BytesIO.seek 647 pos: Py_ssize_t 648 whence: int = 0 649 / 650 651 Change stream position. 652 653 Seek to byte offset pos relative to position indicated by whence: 654 0 Start of stream (the default). pos should be >= 0; 655 1 Current position - pos may be negative; 656 2 End of stream - pos usually negative. 657 Returns the new absolute position. 658 [clinic start generated code]*/ 659 660 static PyObject * 661 _io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence) 662 /*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/ 663 { 664 CHECK_CLOSED(self); 665 666 if (pos < 0 && whence == 0) { 667 PyErr_Format(PyExc_ValueError, 668 "negative seek value %zd", pos); 669 return NULL; 670 } 671 672 /* whence = 0: offset relative to beginning of the string. 673 whence = 1: offset relative to current position. 674 whence = 2: offset relative the end of the string. */ 675 if (whence == 1) { 676 if (pos > PY_SSIZE_T_MAX - self->pos) { 677 PyErr_SetString(PyExc_OverflowError, 678 "new position too large"); 679 return NULL; 680 } 681 pos += self->pos; 682 } 683 else if (whence == 2) { 684 if (pos > PY_SSIZE_T_MAX - self->string_size) { 685 PyErr_SetString(PyExc_OverflowError, 686 "new position too large"); 687 return NULL; 688 } 689 pos += self->string_size; 690 } 691 else if (whence != 0) { 692 PyErr_Format(PyExc_ValueError, 693 "invalid whence (%i, should be 0, 1 or 2)", whence); 694 return NULL; 695 } 696 697 if (pos < 0) 698 pos = 0; 699 self->pos = pos; 700 701 return PyLong_FromSsize_t(self->pos); 702 } 703 704 /*[clinic input] 705 _io.BytesIO.write 706 b: object 707 / 708 709 Write bytes to file. 710 711 Return the number of bytes written. 712 [clinic start generated code]*/ 713 714 static PyObject * 715 _io_BytesIO_write(bytesio *self, PyObject *b) 716 /*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/ 717 { 718 Py_ssize_t n = 0; 719 Py_buffer buf; 720 721 CHECK_CLOSED(self); 722 CHECK_EXPORTS(self); 723 724 if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0) 725 return NULL; 726 727 if (buf.len != 0) 728 n = write_bytes(self, buf.buf, buf.len); 729 730 PyBuffer_Release(&buf); 731 return n >= 0 ? PyLong_FromSsize_t(n) : NULL; 732 } 733 734 /*[clinic input] 735 _io.BytesIO.writelines 736 lines: object 737 / 738 739 Write lines to the file. 740 741 Note that newlines are not added. lines can be any iterable object 742 producing bytes-like objects. This is equivalent to calling write() for 743 each element. 744 [clinic start generated code]*/ 745 746 static PyObject * 747 _io_BytesIO_writelines(bytesio *self, PyObject *lines) 748 /*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/ 749 { 750 PyObject *it, *item; 751 PyObject *ret; 752 753 CHECK_CLOSED(self); 754 755 it = PyObject_GetIter(lines); 756 if (it == NULL) 757 return NULL; 758 759 while ((item = PyIter_Next(it)) != NULL) { 760 ret = _io_BytesIO_write(self, item); 761 Py_DECREF(item); 762 if (ret == NULL) { 763 Py_DECREF(it); 764 return NULL; 765 } 766 Py_DECREF(ret); 767 } 768 Py_DECREF(it); 769 770 /* See if PyIter_Next failed */ 771 if (PyErr_Occurred()) 772 return NULL; 773 774 Py_RETURN_NONE; 775 } 776 777 /*[clinic input] 778 _io.BytesIO.close 779 780 Disable all I/O operations. 781 [clinic start generated code]*/ 782 783 static PyObject * 784 _io_BytesIO_close_impl(bytesio *self) 785 /*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/ 786 { 787 CHECK_EXPORTS(self); 788 Py_CLEAR(self->buf); 789 Py_RETURN_NONE; 790 } 791 792 /* Pickling support. 793 794 Note that only pickle protocol 2 and onward are supported since we use 795 extended __reduce__ API of PEP 307 to make BytesIO instances picklable. 796 797 Providing support for protocol < 2 would require the __reduce_ex__ method 798 which is notably long-winded when defined properly. 799 800 For BytesIO, the implementation would similar to one coded for 801 object.__reduce_ex__, but slightly less general. To be more specific, we 802 could call bytesio_getstate directly and avoid checking for the presence of 803 a fallback __reduce__ method. However, we would still need a __newobj__ 804 function to use the efficient instance representation of PEP 307. 805 */ 806 807 static PyObject * 808 bytesio_getstate(bytesio *self) 809 { 810 PyObject *initvalue = _io_BytesIO_getvalue_impl(self); 811 PyObject *dict; 812 PyObject *state; 813 814 if (initvalue == NULL) 815 return NULL; 816 if (self->dict == NULL) { 817 Py_INCREF(Py_None); 818 dict = Py_None; 819 } 820 else { 821 dict = PyDict_Copy(self->dict); 822 if (dict == NULL) { 823 Py_DECREF(initvalue); 824 return NULL; 825 } 826 } 827 828 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict); 829 Py_DECREF(initvalue); 830 return state; 831 } 832 833 static PyObject * 834 bytesio_setstate(bytesio *self, PyObject *state) 835 { 836 PyObject *result; 837 PyObject *position_obj; 838 PyObject *dict; 839 Py_ssize_t pos; 840 841 assert(state != NULL); 842 843 /* We allow the state tuple to be longer than 3, because we may need 844 someday to extend the object's state without breaking 845 backward-compatibility. */ 846 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) { 847 PyErr_Format(PyExc_TypeError, 848 "%.200s.__setstate__ argument should be 3-tuple, got %.200s", 849 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name); 850 return NULL; 851 } 852 CHECK_EXPORTS(self); 853 /* Reset the object to its default state. This is only needed to handle 854 the case of repeated calls to __setstate__. */ 855 self->string_size = 0; 856 self->pos = 0; 857 858 /* Set the value of the internal buffer. If state[0] does not support the 859 buffer protocol, bytesio_write will raise the appropriate TypeError. */ 860 result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0)); 861 if (result == NULL) 862 return NULL; 863 Py_DECREF(result); 864 865 /* Set carefully the position value. Alternatively, we could use the seek 866 method instead of modifying self->pos directly to better protect the 867 object internal state against errneous (or malicious) inputs. */ 868 position_obj = PyTuple_GET_ITEM(state, 1); 869 if (!PyLong_Check(position_obj)) { 870 PyErr_Format(PyExc_TypeError, 871 "second item of state must be an integer, not %.200s", 872 Py_TYPE(position_obj)->tp_name); 873 return NULL; 874 } 875 pos = PyLong_AsSsize_t(position_obj); 876 if (pos == -1 && PyErr_Occurred()) 877 return NULL; 878 if (pos < 0) { 879 PyErr_SetString(PyExc_ValueError, 880 "position value cannot be negative"); 881 return NULL; 882 } 883 self->pos = pos; 884 885 /* Set the dictionary of the instance variables. */ 886 dict = PyTuple_GET_ITEM(state, 2); 887 if (dict != Py_None) { 888 if (!PyDict_Check(dict)) { 889 PyErr_Format(PyExc_TypeError, 890 "third item of state should be a dict, got a %.200s", 891 Py_TYPE(dict)->tp_name); 892 return NULL; 893 } 894 if (self->dict) { 895 /* Alternatively, we could replace the internal dictionary 896 completely. However, it seems more practical to just update it. */ 897 if (PyDict_Update(self->dict, dict) < 0) 898 return NULL; 899 } 900 else { 901 Py_INCREF(dict); 902 self->dict = dict; 903 } 904 } 905 906 Py_RETURN_NONE; 907 } 908 909 static void 910 bytesio_dealloc(bytesio *self) 911 { 912 _PyObject_GC_UNTRACK(self); 913 if (self->exports > 0) { 914 PyErr_SetString(PyExc_SystemError, 915 "deallocated BytesIO object has exported buffers"); 916 PyErr_Print(); 917 } 918 Py_CLEAR(self->buf); 919 Py_CLEAR(self->dict); 920 if (self->weakreflist != NULL) 921 PyObject_ClearWeakRefs((PyObject *) self); 922 Py_TYPE(self)->tp_free(self); 923 } 924 925 static PyObject * 926 bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 927 { 928 bytesio *self; 929 930 assert(type != NULL && type->tp_alloc != NULL); 931 self = (bytesio *)type->tp_alloc(type, 0); 932 if (self == NULL) 933 return NULL; 934 935 /* tp_alloc initializes all the fields to zero. So we don't have to 936 initialize them here. */ 937 938 self->buf = PyBytes_FromStringAndSize(NULL, 0); 939 if (self->buf == NULL) { 940 Py_DECREF(self); 941 return PyErr_NoMemory(); 942 } 943 944 return (PyObject *)self; 945 } 946 947 /*[clinic input] 948 _io.BytesIO.__init__ 949 initial_bytes as initvalue: object(c_default="NULL") = b'' 950 951 Buffered I/O implementation using an in-memory bytes buffer. 952 [clinic start generated code]*/ 953 954 static int 955 _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) 956 /*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/ 957 { 958 /* In case, __init__ is called multiple times. */ 959 self->string_size = 0; 960 self->pos = 0; 961 962 if (self->exports > 0) { 963 PyErr_SetString(PyExc_BufferError, 964 "Existing exports of data: object cannot be re-sized"); 965 return -1; 966 } 967 if (initvalue && initvalue != Py_None) { 968 if (PyBytes_CheckExact(initvalue)) { 969 Py_INCREF(initvalue); 970 Py_XSETREF(self->buf, initvalue); 971 self->string_size = PyBytes_GET_SIZE(initvalue); 972 } 973 else { 974 PyObject *res; 975 res = _io_BytesIO_write(self, initvalue); 976 if (res == NULL) 977 return -1; 978 Py_DECREF(res); 979 self->pos = 0; 980 } 981 } 982 983 return 0; 984 } 985 986 static PyObject * 987 bytesio_sizeof(bytesio *self, void *unused) 988 { 989 Py_ssize_t res; 990 991 res = _PyObject_SIZE(Py_TYPE(self)); 992 if (self->buf && !SHARED_BUF(self)) 993 res += _PySys_GetSizeOf(self->buf); 994 return PyLong_FromSsize_t(res); 995 } 996 997 static int 998 bytesio_traverse(bytesio *self, visitproc visit, void *arg) 999 { 1000 Py_VISIT(self->dict); 1001 return 0; 1002 } 1003 1004 static int 1005 bytesio_clear(bytesio *self) 1006 { 1007 Py_CLEAR(self->dict); 1008 return 0; 1009 } 1010 1011 1012 #include "clinic/bytesio.c.h" 1013 1014 static PyGetSetDef bytesio_getsetlist[] = { 1015 {"closed", (getter)bytesio_get_closed, NULL, 1016 "True if the file is closed."}, 1017 {NULL}, /* sentinel */ 1018 }; 1019 1020 static struct PyMethodDef bytesio_methods[] = { 1021 _IO_BYTESIO_READABLE_METHODDEF 1022 _IO_BYTESIO_SEEKABLE_METHODDEF 1023 _IO_BYTESIO_WRITABLE_METHODDEF 1024 _IO_BYTESIO_CLOSE_METHODDEF 1025 _IO_BYTESIO_FLUSH_METHODDEF 1026 _IO_BYTESIO_ISATTY_METHODDEF 1027 _IO_BYTESIO_TELL_METHODDEF 1028 _IO_BYTESIO_WRITE_METHODDEF 1029 _IO_BYTESIO_WRITELINES_METHODDEF 1030 _IO_BYTESIO_READ1_METHODDEF 1031 _IO_BYTESIO_READINTO_METHODDEF 1032 _IO_BYTESIO_READLINE_METHODDEF 1033 _IO_BYTESIO_READLINES_METHODDEF 1034 _IO_BYTESIO_READ_METHODDEF 1035 _IO_BYTESIO_GETBUFFER_METHODDEF 1036 _IO_BYTESIO_GETVALUE_METHODDEF 1037 _IO_BYTESIO_SEEK_METHODDEF 1038 _IO_BYTESIO_TRUNCATE_METHODDEF 1039 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL}, 1040 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL}, 1041 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL}, 1042 {NULL, NULL} /* sentinel */ 1043 }; 1044 1045 PyTypeObject PyBytesIO_Type = { 1046 PyVarObject_HEAD_INIT(NULL, 0) 1047 "_io.BytesIO", /*tp_name*/ 1048 sizeof(bytesio), /*tp_basicsize*/ 1049 0, /*tp_itemsize*/ 1050 (destructor)bytesio_dealloc, /*tp_dealloc*/ 1051 0, /*tp_print*/ 1052 0, /*tp_getattr*/ 1053 0, /*tp_setattr*/ 1054 0, /*tp_reserved*/ 1055 0, /*tp_repr*/ 1056 0, /*tp_as_number*/ 1057 0, /*tp_as_sequence*/ 1058 0, /*tp_as_mapping*/ 1059 0, /*tp_hash*/ 1060 0, /*tp_call*/ 1061 0, /*tp_str*/ 1062 0, /*tp_getattro*/ 1063 0, /*tp_setattro*/ 1064 0, /*tp_as_buffer*/ 1065 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 1066 Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 1067 _io_BytesIO___init____doc__, /*tp_doc*/ 1068 (traverseproc)bytesio_traverse, /*tp_traverse*/ 1069 (inquiry)bytesio_clear, /*tp_clear*/ 1070 0, /*tp_richcompare*/ 1071 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/ 1072 PyObject_SelfIter, /*tp_iter*/ 1073 (iternextfunc)bytesio_iternext, /*tp_iternext*/ 1074 bytesio_methods, /*tp_methods*/ 1075 0, /*tp_members*/ 1076 bytesio_getsetlist, /*tp_getset*/ 1077 0, /*tp_base*/ 1078 0, /*tp_dict*/ 1079 0, /*tp_descr_get*/ 1080 0, /*tp_descr_set*/ 1081 offsetof(bytesio, dict), /*tp_dictoffset*/ 1082 _io_BytesIO___init__, /*tp_init*/ 1083 0, /*tp_alloc*/ 1084 bytesio_new, /*tp_new*/ 1085 }; 1086 1087 1088 /* 1089 * Implementation of the small intermediate object used by getbuffer(). 1090 * getbuffer() returns a memoryview over this object, which should make it 1091 * invisible from Python code. 1092 */ 1093 1094 static int 1095 bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags) 1096 { 1097 bytesio *b = (bytesio *) obj->source; 1098 1099 if (view == NULL) { 1100 PyErr_SetString(PyExc_BufferError, 1101 "bytesiobuf_getbuffer: view==NULL argument is obsolete"); 1102 return -1; 1103 } 1104 if (SHARED_BUF(b)) { 1105 if (unshare_buffer(b, b->string_size) < 0) 1106 return -1; 1107 } 1108 1109 /* cannot fail if view != NULL and readonly == 0 */ 1110 (void)PyBuffer_FillInfo(view, (PyObject*)obj, 1111 PyBytes_AS_STRING(b->buf), b->string_size, 1112 0, flags); 1113 b->exports++; 1114 return 0; 1115 } 1116 1117 static void 1118 bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view) 1119 { 1120 bytesio *b = (bytesio *) obj->source; 1121 b->exports--; 1122 } 1123 1124 static int 1125 bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg) 1126 { 1127 Py_VISIT(self->source); 1128 return 0; 1129 } 1130 1131 static void 1132 bytesiobuf_dealloc(bytesiobuf *self) 1133 { 1134 Py_CLEAR(self->source); 1135 Py_TYPE(self)->tp_free(self); 1136 } 1137 1138 static PyBufferProcs bytesiobuf_as_buffer = { 1139 (getbufferproc) bytesiobuf_getbuffer, 1140 (releasebufferproc) bytesiobuf_releasebuffer, 1141 }; 1142 1143 PyTypeObject _PyBytesIOBuffer_Type = { 1144 PyVarObject_HEAD_INIT(NULL, 0) 1145 "_io._BytesIOBuffer", /*tp_name*/ 1146 sizeof(bytesiobuf), /*tp_basicsize*/ 1147 0, /*tp_itemsize*/ 1148 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/ 1149 0, /*tp_print*/ 1150 0, /*tp_getattr*/ 1151 0, /*tp_setattr*/ 1152 0, /*tp_reserved*/ 1153 0, /*tp_repr*/ 1154 0, /*tp_as_number*/ 1155 0, /*tp_as_sequence*/ 1156 0, /*tp_as_mapping*/ 1157 0, /*tp_hash*/ 1158 0, /*tp_call*/ 1159 0, /*tp_str*/ 1160 0, /*tp_getattro*/ 1161 0, /*tp_setattro*/ 1162 &bytesiobuf_as_buffer, /*tp_as_buffer*/ 1163 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 1164 0, /*tp_doc*/ 1165 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/ 1166 0, /*tp_clear*/ 1167 0, /*tp_richcompare*/ 1168 0, /*tp_weaklistoffset*/ 1169 0, /*tp_iter*/ 1170 0, /*tp_iternext*/ 1171 0, /*tp_methods*/ 1172 0, /*tp_members*/ 1173 0, /*tp_getset*/ 1174 0, /*tp_base*/ 1175 0, /*tp_dict*/ 1176 0, /*tp_descr_get*/ 1177 0, /*tp_descr_set*/ 1178 0, /*tp_dictoffset*/ 1179 0, /*tp_init*/ 1180 0, /*tp_alloc*/ 1181 0, /*tp_new*/ 1182 }; 1183