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