OLD | NEW |
1 #include "Python.h" | 1 #include "Python.h" |
| 2 #include "structmember.h" /* for offsetof() */ |
| 3 #include "_iomodule.h" |
2 | 4 |
3 typedef struct { | 5 typedef struct { |
4 PyObject_HEAD | 6 PyObject_HEAD |
5 char *buf; | 7 char *buf; |
6 Py_ssize_t pos; | 8 Py_ssize_t pos; |
7 Py_ssize_t string_size; | 9 Py_ssize_t string_size; |
8 size_t buf_size; | 10 size_t buf_size; |
| 11 PyObject *dict; |
| 12 PyObject *weakreflist; |
9 } BytesIOObject; | 13 } BytesIOObject; |
10 | 14 |
11 #define CHECK_CLOSED(self) \ | 15 #define CHECK_CLOSED(self) \ |
12 if ((self)->buf == NULL) { \ | 16 if ((self)->buf == NULL) { \ |
13 PyErr_SetString(PyExc_ValueError, \ | 17 PyErr_SetString(PyExc_ValueError, \ |
14 "I/O operation on closed file."); \ | 18 "I/O operation on closed file."); \ |
15 return NULL; \ | 19 return NULL; \ |
16 } | 20 } |
17 | 21 |
18 /* Internal routine to get a line from the buffer of a BytesIO | 22 /* Internal routine to get a line from the buffer of a BytesIO |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 if (self->string_size < self->pos) { | 141 if (self->string_size < self->pos) { |
138 self->string_size = self->pos; | 142 self->string_size = self->pos; |
139 } | 143 } |
140 | 144 |
141 return len; | 145 return len; |
142 } | 146 } |
143 | 147 |
144 static PyObject * | 148 static PyObject * |
145 bytesio_get_closed(BytesIOObject *self) | 149 bytesio_get_closed(BytesIOObject *self) |
146 { | 150 { |
147 if (self->buf == NULL) | 151 if (self->buf == NULL) { |
148 Py_RETURN_TRUE; | 152 Py_RETURN_TRUE; |
149 else | 153 } |
| 154 else { |
150 Py_RETURN_FALSE; | 155 Py_RETURN_FALSE; |
| 156 } |
151 } | 157 } |
152 | 158 |
153 /* Generic getter for the writable, readable and seekable properties */ | 159 /* Generic getter for the writable, readable and seekable properties */ |
154 static PyObject * | 160 static PyObject * |
155 return_true(BytesIOObject *self) | 161 return_true(BytesIOObject *self) |
156 { | 162 { |
157 Py_RETURN_TRUE; | 163 Py_RETURN_TRUE; |
158 } | 164 } |
159 | 165 |
160 PyDoc_STRVAR(flush_doc, | 166 PyDoc_STRVAR(flush_doc, |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 531 } |
526 | 532 |
527 PyDoc_STRVAR(write_doc, | 533 PyDoc_STRVAR(write_doc, |
528 "write(bytes) -> int. Write bytes to file.\n" | 534 "write(bytes) -> int. Write bytes to file.\n" |
529 "\n" | 535 "\n" |
530 "Return the number of bytes written."); | 536 "Return the number of bytes written."); |
531 | 537 |
532 static PyObject * | 538 static PyObject * |
533 bytesio_write(BytesIOObject *self, PyObject *obj) | 539 bytesio_write(BytesIOObject *self, PyObject *obj) |
534 { | 540 { |
535 const char *bytes; | |
536 Py_ssize_t size; | |
537 Py_ssize_t n = 0; | 541 Py_ssize_t n = 0; |
| 542 Py_buffer buf; |
| 543 PyObject *result = NULL; |
538 | 544 |
539 CHECK_CLOSED(self); | 545 CHECK_CLOSED(self); |
540 | 546 |
541 if (PyObject_AsReadBuffer(obj, (void *)&bytes, &size) < 0) | 547 if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0) |
542 return NULL; | 548 return NULL; |
543 | 549 |
544 if (size != 0) { | 550 if (buf.len != 0) |
545 n = write_bytes(self, bytes, size); | 551 n = write_bytes(self, buf.buf, buf.len); |
546 if (n < 0) | 552 if (n >= 0) |
547 return NULL; | 553 result = PyLong_FromSsize_t(n); |
548 } | |
549 | 554 |
550 return PyLong_FromSsize_t(n); | 555 PyBuffer_Release(&buf); |
| 556 return result; |
551 } | 557 } |
552 | 558 |
553 PyDoc_STRVAR(writelines_doc, | 559 PyDoc_STRVAR(writelines_doc, |
554 "writelines(sequence_of_strings) -> None. Write strings to the file.\n" | 560 "writelines(sequence_of_strings) -> None. Write strings to the file.\n" |
555 "\n" | 561 "\n" |
556 "Note that newlines are not added. The sequence can be any iterable\n" | 562 "Note that newlines are not added. The sequence can be any iterable\n" |
557 "object producing strings. This is equivalent to calling write() for\n" | 563 "object producing strings. This is equivalent to calling write() for\n" |
558 "each string."); | 564 "each string."); |
559 | 565 |
560 static PyObject * | 566 static PyObject * |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 Py_RETURN_NONE; | 606 Py_RETURN_NONE; |
601 } | 607 } |
602 | 608 |
603 static void | 609 static void |
604 bytesio_dealloc(BytesIOObject *self) | 610 bytesio_dealloc(BytesIOObject *self) |
605 { | 611 { |
606 if (self->buf != NULL) { | 612 if (self->buf != NULL) { |
607 PyMem_Free(self->buf); | 613 PyMem_Free(self->buf); |
608 self->buf = NULL; | 614 self->buf = NULL; |
609 } | 615 } |
| 616 Py_TYPE(self)->tp_clear((PyObject *)self); |
610 Py_TYPE(self)->tp_free(self); | 617 Py_TYPE(self)->tp_free(self); |
611 } | 618 } |
612 | 619 |
613 static PyObject * | 620 static PyObject * |
614 bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 621 bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
615 { | 622 { |
616 BytesIOObject *self; | 623 BytesIOObject *self; |
617 | 624 |
618 assert(type != NULL && type->tp_alloc != NULL); | 625 assert(type != NULL && type->tp_alloc != NULL); |
619 self = (BytesIOObject *)type->tp_alloc(type, 0); | 626 self = (BytesIOObject *)type->tp_alloc(type, 0); |
(...skipping 29 matching lines...) Expand all Loading... |
649 res = bytesio_write(self, initvalue); | 656 res = bytesio_write(self, initvalue); |
650 if (res == NULL) | 657 if (res == NULL) |
651 return -1; | 658 return -1; |
652 Py_DECREF(res); | 659 Py_DECREF(res); |
653 self->pos = 0; | 660 self->pos = 0; |
654 } | 661 } |
655 | 662 |
656 return 0; | 663 return 0; |
657 } | 664 } |
658 | 665 |
| 666 static int |
| 667 bytesio_traverse(BytesIOObject *self, visitproc visit, void *arg) |
| 668 { |
| 669 Py_VISIT(self->dict); |
| 670 Py_VISIT(self->weakreflist); |
| 671 return 0; |
| 672 } |
| 673 |
| 674 static int |
| 675 bytesio_clear(BytesIOObject *self) |
| 676 { |
| 677 Py_CLEAR(self->dict); |
| 678 if (self->weakreflist != NULL) |
| 679 PyObject_ClearWeakRefs((PyObject *)self); |
| 680 return 0; |
| 681 } |
| 682 |
| 683 |
659 static PyGetSetDef bytesio_getsetlist[] = { | 684 static PyGetSetDef bytesio_getsetlist[] = { |
660 {"closed", (getter)bytesio_get_closed, NULL, | 685 {"closed", (getter)bytesio_get_closed, NULL, |
661 "True if the file is closed."}, | 686 "True if the file is closed."}, |
662 {0}, /* sentinel */ | 687 {0}, /* sentinel */ |
663 }; | 688 }; |
664 | 689 |
665 static struct PyMethodDef bytesio_methods[] = { | 690 static struct PyMethodDef bytesio_methods[] = { |
666 {"readable", (PyCFunction)return_true, METH_NOARGS, NULL}, | 691 {"readable", (PyCFunction)return_true, METH_NOARGS, NULL}, |
667 {"seekable", (PyCFunction)return_true, METH_NOARGS, NULL}, | 692 {"seekable", (PyCFunction)return_true, METH_NOARGS, NULL}, |
668 {"writable", (PyCFunction)return_true, METH_NOARGS, NULL}, | 693 {"writable", (PyCFunction)return_true, METH_NOARGS, NULL}, |
(...skipping 13 matching lines...) Expand all Loading... |
682 {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc}, | 707 {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc}, |
683 {NULL, NULL} /* sentinel */ | 708 {NULL, NULL} /* sentinel */ |
684 }; | 709 }; |
685 | 710 |
686 PyDoc_STRVAR(bytesio_doc, | 711 PyDoc_STRVAR(bytesio_doc, |
687 "BytesIO([buffer]) -> object\n" | 712 "BytesIO([buffer]) -> object\n" |
688 "\n" | 713 "\n" |
689 "Create a buffered I/O implementation using an in-memory bytes\n" | 714 "Create a buffered I/O implementation using an in-memory bytes\n" |
690 "buffer, ready for reading and writing."); | 715 "buffer, ready for reading and writing."); |
691 | 716 |
692 static PyTypeObject BytesIO_Type = { | 717 PyTypeObject PyBytesIO_Type = { |
693 PyVarObject_HEAD_INIT(NULL, 0) | 718 PyVarObject_HEAD_INIT(NULL, 0) |
694 "_bytesio._BytesIO", /*tp_name*/ | 719 "_io.BytesIO", /*tp_name*/ |
695 sizeof(BytesIOObject), /*tp_basicsize*/ | 720 sizeof(BytesIOObject), /*tp_basicsize*/ |
696 0, /*tp_itemsize*/ | 721 0, /*tp_itemsize*/ |
697 (destructor)bytesio_dealloc, /*tp_dealloc*/ | 722 (destructor)bytesio_dealloc, /*tp_dealloc*/ |
698 0, /*tp_print*/ | 723 0, /*tp_print*/ |
699 0, /*tp_getattr*/ | 724 0, /*tp_getattr*/ |
700 0, /*tp_setattr*/ | 725 0, /*tp_setattr*/ |
701 0, /*tp_reserved*/ | 726 0, /*tp_reserved*/ |
702 0, /*tp_repr*/ | 727 0, /*tp_repr*/ |
703 0, /*tp_as_number*/ | 728 0, /*tp_as_number*/ |
704 0, /*tp_as_sequence*/ | 729 0, /*tp_as_sequence*/ |
705 0, /*tp_as_mapping*/ | 730 0, /*tp_as_mapping*/ |
706 0, /*tp_hash*/ | 731 0, /*tp_hash*/ |
707 0, /*tp_call*/ | 732 0, /*tp_call*/ |
708 0, /*tp_str*/ | 733 0, /*tp_str*/ |
709 0, /*tp_getattro*/ | 734 0, /*tp_getattro*/ |
710 0, /*tp_setattro*/ | 735 0, /*tp_setattro*/ |
711 0, /*tp_as_buffer*/ | 736 0, /*tp_as_buffer*/ |
712 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | 737 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | |
| 738 Py_TPFLAGS_HAVE_GC, /*tp_flags*/ |
713 bytesio_doc, /*tp_doc*/ | 739 bytesio_doc, /*tp_doc*/ |
714 0, /*tp_traverse*/ | 740 (traverseproc)bytesio_traverse, /*tp_traverse*/ |
715 0, /*tp_clear*/ | 741 (inquiry)bytesio_clear, /*tp_clear*/ |
716 0, /*tp_richcompare*/ | 742 0, /*tp_richcompare*/ |
717 0, /*tp_weaklistoffset*/ | 743 offsetof(BytesIOObject, weakreflist), /*tp_weaklistoffset*/ |
718 PyObject_SelfIter, /*tp_iter*/ | 744 PyObject_SelfIter, /*tp_iter*/ |
719 (iternextfunc)bytesio_iternext, /*tp_iternext*/ | 745 (iternextfunc)bytesio_iternext, /*tp_iternext*/ |
720 bytesio_methods, /*tp_methods*/ | 746 bytesio_methods, /*tp_methods*/ |
721 0, /*tp_members*/ | 747 0, /*tp_members*/ |
722 bytesio_getsetlist, /*tp_getset*/ | 748 bytesio_getsetlist, /*tp_getset*/ |
723 0, /*tp_base*/ | 749 0, /*tp_base*/ |
724 0, /*tp_dict*/ | 750 0, /*tp_dict*/ |
725 0, /*tp_descr_get*/ | 751 0, /*tp_descr_get*/ |
726 0, /*tp_descr_set*/ | 752 0, /*tp_descr_set*/ |
727 0, /*tp_dictoffset*/ | 753 offsetof(BytesIOObject, dict), /*tp_dictoffset*/ |
728 (initproc)bytesio_init, /*tp_init*/ | 754 (initproc)bytesio_init, /*tp_init*/ |
729 0, /*tp_alloc*/ | 755 0, /*tp_alloc*/ |
730 bytesio_new, /*tp_new*/ | 756 bytesio_new, /*tp_new*/ |
731 }; | 757 }; |
732 | |
733 | |
734 static struct PyModuleDef _bytesiomodule = { | |
735 PyModuleDef_HEAD_INIT, | |
736 "_bytesio", | |
737 NULL, | |
738 -1, | |
739 NULL, | |
740 NULL, | |
741 NULL, | |
742 NULL, | |
743 NULL | |
744 }; | |
745 | |
746 PyMODINIT_FUNC | |
747 PyInit__bytesio(void) | |
748 { | |
749 PyObject *m; | |
750 | |
751 if (PyType_Ready(&BytesIO_Type) < 0) | |
752 return NULL; | |
753 m = PyModule_Create(&_bytesiomodule); | |
754 if (m == NULL) | |
755 return NULL; | |
756 Py_INCREF(&BytesIO_Type); | |
757 PyModule_AddObject(m, "_BytesIO", (PyObject *)&BytesIO_Type); | |
758 return m; | |
759 } | |
OLD | NEW |