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 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. */ 87static int 88unshare_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. */ 106static int 107resize_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. */ 159static Py_ssize_t 160write_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 203static PyObject * 204bytesio_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 217Returns True if the IO object can be read. 218[clinic start generated code]*/ 219 220static 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 231Returns True if the IO object can be written. 232[clinic start generated code]*/ 233 234static 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 245Returns True if the IO object can be seeked. 246[clinic start generated code]*/ 247 248static 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 259Does nothing. 260[clinic start generated code]*/ 261 262static 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 273Get a read-write view over the contents of the BytesIO object. 274[clinic start generated code]*/ 275 276static 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 299Retrieve the entire contents of the BytesIO object. 300[clinic start generated code]*/ 301 302static 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 328Always returns False. 329 330BytesIO objects are not connected to a TTY-like device. 331[clinic start generated code]*/ 332 333static 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 344Current file position, an integer. 345[clinic start generated code]*/ 346 347static 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 355static PyObject * 356read_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 380Read at most size bytes, returned as a bytes object. 381 382If the size argument is negative, read until EOF is reached. 383Return an empty bytes object at EOF. 384[clinic start generated code]*/ 385 386static 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 426Read at most size bytes, returned as a bytes object. 427 428If the size argument is negative or omitted, read until EOF is reached. 429Return an empty bytes object at EOF. 430[clinic start generated code]*/ 431 432static 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 444Next line from the file, as a bytes object. 445 446Retain newline. A non-negative size argument limits the maximum 447number of bytes to return (an incomplete line may be returned then). 448Return an empty bytes object at EOF. 449[clinic start generated code]*/ 450 451static 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 484List of bytes objects, each a line from the file. 485 486Call readline() repeatedly and return a list of the lines so read. 487The optional size argument, if given, is an approximate bound on the 488total number of bytes in the lines returned. 489[clinic start generated code]*/ 490 491static 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 549Read bytes into buffer. 550 551Returns number of bytes read (0 for EOF), or None if the object 552is set not to block and has no data to read. 553[clinic start generated code]*/ 554 555static 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 585Truncate the file to at most size bytes. 586 587Size defaults to the current file position, as returned by tell(). 588The current file position is unchanged. Returns the new size. 589[clinic start generated code]*/ 590 591static 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 630static PyObject * 631bytesio_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 651Change stream position. 652 653Seek 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. 657Returns the new absolute position. 658[clinic start generated code]*/ 659 660static 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 709Write bytes to file. 710 711Return the number of bytes written. 712[clinic start generated code]*/ 713 714static 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 739Write lines to the file. 740 741Note that newlines are not added. lines can be any iterable object 742producing bytes-like objects. This is equivalent to calling write() for 743each element. 744[clinic start generated code]*/ 745 746static 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 780Disable all I/O operations. 781[clinic start generated code]*/ 782 783static 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 807static PyObject * 808bytesio_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 833static PyObject * 834bytesio_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 909static void 910bytesio_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 925static PyObject * 926bytesio_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 951Buffered I/O implementation using an in-memory bytes buffer. 952[clinic start generated code]*/ 953 954static 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 986static PyObject * 987bytesio_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 997static int 998bytesio_traverse(bytesio *self, visitproc visit, void *arg) 999{ 1000 Py_VISIT(self->dict); 1001 return 0; 1002} 1003 1004static int 1005bytesio_clear(bytesio *self) 1006{ 1007 Py_CLEAR(self->dict); 1008 return 0; 1009} 1010 1011 1012#include "clinic/bytesio.c.h" 1013 1014static PyGetSetDef bytesio_getsetlist[] = { 1015 {"closed", (getter)bytesio_get_closed, NULL, 1016 "True if the file is closed."}, 1017 {NULL}, /* sentinel */ 1018}; 1019 1020static 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 1045PyTypeObject 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 1094static int 1095bytesiobuf_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 1117static void 1118bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view) 1119{ 1120 bytesio *b = (bytesio *) obj->source; 1121 b->exports--; 1122} 1123 1124static int 1125bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg) 1126{ 1127 Py_VISIT(self->source); 1128 return 0; 1129} 1130 1131static void 1132bytesiobuf_dealloc(bytesiobuf *self) 1133{ 1134 Py_CLEAR(self->source); 1135 Py_TYPE(self)->tp_free(self); 1136} 1137 1138static PyBufferProcs bytesiobuf_as_buffer = { 1139 (getbufferproc) bytesiobuf_getbuffer, 1140 (releasebufferproc) bytesiobuf_releasebuffer, 1141}; 1142 1143PyTypeObject _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