17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PY_SSIZE_T_CLEAN 27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h" 37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "structmember.h" 47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "_iomodule.h" 57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Implementation note: the buffer is always at least one character longer 77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel than the enclosed string, for proper functioning of _PyIO_find_line_ending. 87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/ 97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct { 117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_HEAD 127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *buf; 137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t pos; 147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t string_size; 157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size_t buf_size; 167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char ok; /* initialized? */ 187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char closed; 197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char readuniversal; 207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char readtranslate; 217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *decoder; 227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *readnl; 237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *writenl; 247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *dict; 267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *weakreflist; 277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} stringio; 287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CHECK_INITIALIZED(self) \ 307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->ok <= 0) { \ 317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, \ 327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "I/O operation on uninitialized object"); \ 337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; \ 347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CHECK_CLOSED(self) \ 377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->closed) { \ 387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, \ 397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "I/O operation on closed file"); \ 407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; \ 417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_doc, 447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Text I/O implementation using an in-memory buffer.\n" 457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "The initial_value argument sets the value of object. The newline\n" 477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "argument is like the one of TextIOWrapper's constructor."); 487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Internal routine for changing the size, in terms of characters, of the 517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buffer of StringIO objects. The caller should ensure that the 'size' 527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel argument is non-negative. Returns 0 on success, -1 otherwise. */ 537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielresize_buffer(stringio *self, size_t size) 557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Here, unsigned types are used to avoid dealing with signed integer 577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel overflow, which is undefined in C. */ 587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size_t alloc = self->buf_size; 597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *new_buf = NULL; 607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(self->buf != NULL); 627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Reserve one more char for line ending detection. */ 647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = size + 1; 657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* For simplicity, stay in the range of the signed type. Anyway, Python 667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel doesn't allow strings to be longer than this. */ 677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size > PY_SSIZE_T_MAX) 687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto overflow; 697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size < alloc / 2) { 717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Major downsize; resize down to exact size. */ 727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel alloc = size + 1; 737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (size < alloc) { 757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Within allocated size; quick exit */ 767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (size <= alloc * 1.125) { 797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Moderate upsize; overallocate similar to list_resize() */ 807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel alloc = size + (size >> 3) + (size < 9 ? 3 : 6); 817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Major upsize; resize up to exact size */ 847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel alloc = size + 1; 857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (alloc > ((size_t)-1) / sizeof(Py_UNICODE)) 887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto overflow; 897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel new_buf = (Py_UNICODE *)PyMem_Realloc(self->buf, 907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel alloc * sizeof(Py_UNICODE)); 917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (new_buf == NULL) { 927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_NoMemory(); 937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->buf_size = alloc; 967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->buf = new_buf; 977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel overflow: 1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_OverflowError, 1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "new buffer size too large"); 1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Internal routine for writing a whole PyUnicode object to the buffer of a 1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel StringIO object. Returns 0 on success, or -1 on error. */ 1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic Py_ssize_t 1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielwrite_str(stringio *self, PyObject *obj) 1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *str; 1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t len; 1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *decoded = NULL; 1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(self->buf != NULL); 1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(self->pos >= 0); 1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->decoder != NULL) { 1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel decoded = _PyIncrementalNewlineDecoder_decode( 1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->decoder, obj, 1 /* always final */); 1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel decoded = obj; 1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(decoded); 1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->writenl) { 1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *translated = PyUnicode_Replace( 1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel decoded, _PyIO_str_nl, self->writenl, -1); 1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(decoded); 1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel decoded = translated; 1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (decoded == NULL) 1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyUnicode_Check(decoded)); 1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel str = PyUnicode_AS_UNICODE(decoded); 1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = PyUnicode_GET_SIZE(decoded); 1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(len >= 0); 1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* This overflow check is not strictly necessary. However, it avoids us to 1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel deal with funky things like comparing an unsigned and a signed 1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel integer. */ 1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->pos > PY_SSIZE_T_MAX - len) { 1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_OverflowError, 1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "new position too large"); 1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto fail; 1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->pos + len > self->string_size) { 1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (resize_buffer(self, self->pos + len) < 0) 1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto fail; 1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->pos > self->string_size) { 1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* In case of overseek, pad with null bytes the buffer region between 1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the end of stream and the current position. 1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0 lo string_size hi 1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel | |<---used--->|<----------available----------->| 1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel | | <--to pad-->|<---to write---> | 1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0 buf position 1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel memset(self->buf + self->string_size, '\0', 1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (self->pos - self->string_size) * sizeof(Py_UNICODE)); 1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Copy the data to the internal buffer, overwriting some of the 1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel existing data if self->pos < self->string_size. */ 1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel memcpy(self->buf + self->pos, str, len * sizeof(Py_UNICODE)); 1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos += len; 1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Set the new length of the internal string if it has changed. */ 1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->string_size < self->pos) { 1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->string_size = self->pos; 1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(decoded); 1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielfail: 1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(decoded); 1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_getvalue_doc, 1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Retrieve the entire contents of the object."); 1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_getvalue(stringio *self) 1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyUnicode_FromUnicode(self->buf, self->string_size); 1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_tell_doc, 1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Tell the current file position."); 1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_tell(stringio *self) 2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyLong_FromSsize_t(self->pos); 2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_read_doc, 2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Read at most n characters, returned as a string.\n" 2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "If the argument is negative or omitted, read until EOF\n" 2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "is reached. Return an empty string at EOF.\n"); 2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_read(stringio *self, PyObject *args) 2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t size, n; 2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *output; 2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *arg = Py_None; 2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTuple(args, "|O:read", &arg)) 2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyNumber_Check(arg)) { 2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); 2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size == -1 && PyErr_Occurred()) 2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (arg == Py_None) { 2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read until EOF is reached, by default. */ 2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = -1; 2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(arg)->tp_name); 2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* adjust invalid sizes */ 2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel n = self->string_size - self->pos; 2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size < 0 || size > n) { 2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = n; 2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size < 0) 2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = 0; 2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output = self->buf + self->pos; 2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos += size; 2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyUnicode_FromUnicode(output, size); 2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Internal helper, used by stringio_readline and stringio_iternext */ 2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_stringio_readline(stringio *self, Py_ssize_t limit) 2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *start, *end, old_char; 2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t len, consumed; 2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* In case of overseek, return the empty string */ 2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->pos >= self->string_size) 2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyUnicode_FromString(""); 2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel start = self->buf + self->pos; 2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (limit < 0 || limit > self->string_size - self->pos) 2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel limit = self->string_size - self->pos; 2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = start + limit; 2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel old_char = *end; 2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *end = '\0'; 2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = _PyIO_find_line_ending( 2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->readtranslate, self->readuniversal, self->readnl, 2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel start, end, &consumed); 2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *end = old_char; 2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* If we haven't found any line ending, we just return everything 2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (`consumed` is ignored). */ 2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (len < 0) 2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = limit; 2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos += len; 2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyUnicode_FromUnicode(start, len); 2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_readline_doc, 2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Read until newline or EOF.\n" 2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Returns an empty string if EOF is hit immediately.\n"); 2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_readline(stringio *self, PyObject *args) 2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *arg = Py_None; 2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t limit = -1; 2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTuple(args, "|O:readline", &arg)) 2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyNumber_Check(arg)) { 3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError); 3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (limit == -1 && PyErr_Occurred()) 3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (arg != Py_None) { 3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(arg)->tp_name); 3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _stringio_readline(self, limit); 3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_iternext(stringio *self) 3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *line; 3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_TYPE(self) == &PyStringIO_Type) { 3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Skip method call overhead for speed */ 3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel line = _stringio_readline(self, -1); 3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* XXX is subclassing StringIO really supported? */ 3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel line = PyObject_CallMethodObjArgs((PyObject *)self, 3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel _PyIO_str_readline, NULL); 3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (line && !PyUnicode_Check(line)) { 3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_IOError, 3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "readline() should have returned an str object, " 3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "not '%.200s'", Py_TYPE(line)->tp_name); 3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(line); 3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (line == NULL) 3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyUnicode_GET_SIZE(line) == 0) { 3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Reached EOF */ 3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(line); 3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return line; 3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_truncate_doc, 3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Truncate size to pos.\n" 3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "The pos argument defaults to the current file position, as\n" 3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "returned by tell(). The current file position is unchanged.\n" 3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Returns the new absolute position.\n"); 3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_truncate(stringio *self, PyObject *args) 3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t size; 3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *arg = Py_None; 3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) 3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyNumber_Check(arg)) { 3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); 3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size == -1 && PyErr_Occurred()) 3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (arg == Py_None) { 3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Truncate to current position if no argument is passed. */ 3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = self->pos; 3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", 3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(arg)->tp_name); 3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size < 0) { 3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_ValueError, 3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Negative size value %zd", size); 3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size < self->string_size) { 3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (resize_buffer(self, size) < 0) 3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->string_size = size; 3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyLong_FromSsize_t(size); 3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_seek_doc, 3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Change stream position.\n" 3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Seek to character offset pos relative to position indicated by whence:\n" 4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel " 0 Start of stream (the default). pos should be >= 0;\n" 4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel " 1 Current position - pos must be 0;\n" 4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel " 2 End of stream - pos must be 0.\n" 4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Returns the new absolute position.\n"); 4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_seek(stringio *self, PyObject *args) 4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *posobj; 4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t pos; 4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int mode = 0; 4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTuple(args, "O|i:seek", &posobj, &mode)) 4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pos = PyNumber_AsSsize_t(posobj, PyExc_OverflowError); 4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pos == -1 && PyErr_Occurred()) 4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (mode != 0 && mode != 1 && mode != 2) { 4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_ValueError, 4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Invalid whence (%i, should be 0, 1 or 2)", mode); 4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (pos < 0 && mode == 0) { 4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_ValueError, 4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Negative seek position %zd", pos); 4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (mode != 0 && pos != 0) { 4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_IOError, 4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Can't do nonzero cur-relative seeks"); 4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* mode 0: offset relative to beginning of the string. 4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel mode 1: no change to current position. 4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel mode 2: change position to end of file. */ 4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (mode == 1) { 4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pos = self->pos; 4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (mode == 2) { 4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pos = self->string_size; 4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos = pos; 4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyLong_FromSsize_t(self->pos); 4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_write_doc, 4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Write string to file.\n" 4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Returns the number of characters written, which is always equal to\n" 4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "the length of the string.\n"); 4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_write(stringio *self, PyObject *obj) 4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t size; 4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyUnicode_Check(obj)) { 4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, "unicode argument expected, got '%s'", 4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(obj)->tp_name); 4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = PyUnicode_GET_SIZE(obj); 4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (size > 0 && write_str(self, obj) < 0) 4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyLong_FromSsize_t(size); 4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_close_doc, 4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Close the IO object. Attempting any further operation after the\n" 4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "object is closed will raise a ValueError.\n" 4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "This method has no effect if the file is already closed.\n"); 4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_close(stringio *self) 4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->closed = 1; 4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Free up some memory */ 4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (resize_buffer(self, 0) < 0) 4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->readnl); 4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->writenl); 4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->decoder); 4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_NONE; 4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_traverse(stringio *self, visitproc visit, void *arg) 5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(self->dict); 5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_clear(stringio *self) 5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->dict); 5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_dealloc(stringio *self) 5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel _PyObject_GC_UNTRACK(self); 5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->ok = 0; 5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->buf) { 5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyMem_Free(self->buf); 5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->buf = NULL; 5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->readnl); 5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->writenl); 5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->decoder); 5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->dict); 5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->weakreflist != NULL) 5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_ClearWeakRefs((PyObject *) self); 5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(self)->tp_free(self); 5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stringio *self; 5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(type != NULL && type->tp_alloc != NULL); 5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self = (stringio *)type->tp_alloc(type, 0); 5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self == NULL) 5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* tp_alloc initializes all the fields to zero. So we don't have to 5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel initialize them here. */ 5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->buf = (Py_UNICODE *)PyMem_Malloc(0); 5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->buf == NULL) { 5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(self); 5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyErr_NoMemory(); 5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return (PyObject *)self; 5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_init(stringio *self, PyObject *args, PyObject *kwds) 5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *kwlist[] = {"initial_value", "newline", NULL}; 5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *value = NULL; 5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *newline = "\n"; 5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz:__init__", kwlist, 5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &value, &newline)) 5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (newline && newline[0] != '\0' 5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel && !(newline[0] == '\n' && newline[1] == '\0') 5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel && !(newline[0] == '\r' && newline[1] == '\0') 5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { 5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_ValueError, 5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "illegal newline value: %s", newline); 5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (value && value != Py_None && !PyUnicode_Check(value)) { 5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "initial_value must be unicode or None, not %.200s", 5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(value)->tp_name); 5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->ok = 0; 5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->readnl); 5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->writenl); 5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(self->decoder); 5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (newline) { 5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->readnl = PyString_FromString(newline); 5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->readnl == NULL) 5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->readuniversal = (newline == NULL || newline[0] == '\0'); 5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->readtranslate = (newline == NULL); 5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* If newline == "", we don't translate anything. 5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel If newline == "\n" or newline == None, we translate to "\n", which is 5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel a no-op. 5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (for newline == None, TextIOWrapper translates to os.sepline, but it 5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is pointless for StringIO) 5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (newline != NULL && newline[0] == '\r') { 5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->writenl = PyUnicode_FromString(newline); 6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->readuniversal) { 6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->decoder = PyObject_CallFunction( 6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (PyObject *)&PyIncrementalNewlineDecoder_Type, 6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Oi", Py_None, (int) self->readtranslate); 6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->decoder == NULL) 6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Now everything is set up, resize buffer to size of initial value, 6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel and copy it */ 6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->string_size = 0; 6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (value && value != Py_None) { 6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t len = PyUnicode_GetSize(value); 6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* This is a heuristic, for newline translation might change 6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the string length. */ 6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (resize_buffer(self, len) < 0) 6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos = 0; 6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (write_str(self, value) < 0) 6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (resize_buffer(self, 0) < 0) 6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos = 0; 6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->closed = 0; 6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->ok = 1; 6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Properties and pseudo-properties */ 6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_readable_doc, 6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"readable() -> bool. Returns True if the IO object can be read."); 6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_writable_doc, 6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"writable() -> bool. Returns True if the IO object can be written."); 6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(stringio_seekable_doc, 6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"seekable() -> bool. Returns True if the IO object can be seeked."); 6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_seekable(stringio *self, PyObject *args) 6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_TRUE; 6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_readable(stringio *self, PyObject *args) 6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_TRUE; 6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_writable(stringio *self, PyObject *args) 6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_TRUE; 6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Pickling support. 6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel The implementation of __getstate__ is similar to the one for BytesIO, 6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel except that we also save the newline parameter. For __setstate__ and unlike 6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel BytesIO, we call __init__ to restore the object's state. Doing so allows us 6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel to avoid decoding the complex newline state while keeping the object 6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel representation compact. 6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel See comment in bytesio.c regarding why only pickle protocols and onward are 6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel supported. 6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/ 6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_getstate(stringio *self) 6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *initvalue = stringio_getvalue(self); 6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *dict; 6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *state; 6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (initvalue == NULL) 6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->dict == NULL) { 6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_None); 6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dict = Py_None; 6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dict = PyDict_Copy(self->dict); 6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (dict == NULL) 6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = Py_BuildValue("(OOnN)", initvalue, 7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->readnl ? self->readnl : Py_None, 7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos, dict); 7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(initvalue); 7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return state; 7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_setstate(stringio *self, PyObject *state) 7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *initarg; 7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *position_obj; 7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *dict; 7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t pos; 7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(state != NULL); 7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* We allow the state tuple to be longer than 4, because we may need 7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel someday to extend the object's state without breaking 7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel backward-compatibility. */ 7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyTuple_Check(state) || Py_SIZE(state) < 4) { 7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "%.200s.__setstate__ argument should be 4-tuple, got %.200s", 7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name); 7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Initialize the object's state. */ 7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel initarg = PyTuple_GetSlice(state, 0, 2); 7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (initarg == NULL) 7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (stringio_init(self, initarg, NULL) < 0) { 7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(initarg); 7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(initarg); 7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Restore the buffer state. Even if __init__ did initialize the buffer, 7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel we have to initialize it again since __init__ may translates the 7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel newlines in the inital_value string. We clearly do not want that 7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel because the string value in the state tuple has already been translated 7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel once by __init__. So we do not take any chance and replace object's 7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buffer completely. */ 7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel { 7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *buf = PyUnicode_AS_UNICODE(PyTuple_GET_ITEM(state, 0)); 7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t bufsize = PyUnicode_GET_SIZE(PyTuple_GET_ITEM(state, 0)); 7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (resize_buffer(self, bufsize) < 0) 7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel memcpy(self->buf, buf, bufsize * sizeof(Py_UNICODE)); 7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->string_size = bufsize; 7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Set carefully the position value. Alternatively, we could use the seek 7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel method instead of modifying self->pos directly to better protect the 7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel object internal state against errneous (or malicious) inputs. */ 7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel position_obj = PyTuple_GET_ITEM(state, 2); 7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyIndex_Check(position_obj)) { 7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "third item of state must be an integer, got %.200s", 7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(position_obj)->tp_name); 7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pos = PyNumber_AsSsize_t(position_obj, PyExc_OverflowError); 7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pos == -1 && PyErr_Occurred()) 7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pos < 0) { 7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, 7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "position value cannot be negative"); 7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->pos = pos; 7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Set the dictionary of the instance variables. */ 7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dict = PyTuple_GET_ITEM(state, 3); 7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (dict != Py_None) { 7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyDict_Check(dict)) { 7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "fourth item of state should be a dict, got a %.200s", 7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(dict)->tp_name); 7807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->dict) { 7837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Alternatively, we could replace the internal dictionary 7847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel completely. However, it seems more practical to just update it. */ 7857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_Update(self->dict, dict) < 0) 7867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 7897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(dict); 7907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel self->dict = dict; 7917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_NONE; 7957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 7967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 7997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_closed(stringio *self, void *context) 8007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 8027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyBool_FromLong(self->closed); 8037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 8067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_line_buffering(stringio *self, void *context) 8077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 8097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 8107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_FALSE; 8117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 8147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstringio_newlines(stringio *self, void *context) 8157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_INITIALIZED(self); 8177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CHECK_CLOSED(self); 8187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (self->decoder == NULL) 8197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_RETURN_NONE; 8207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); 8217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef stringio_methods[] = { 8247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc}, 8257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc}, 8267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc}, 8277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc}, 8287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc}, 8297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc}, 8307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc}, 8317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc}, 8327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS, stringio_seekable_doc}, 8347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"readable", (PyCFunction)stringio_readable, METH_NOARGS, stringio_readable_doc}, 8357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"writable", (PyCFunction)stringio_writable, METH_NOARGS, stringio_writable_doc}, 8367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS}, 8387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"__setstate__", (PyCFunction)stringio_setstate, METH_O}, 8397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {NULL, NULL} /* sentinel */ 8407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 8417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyGetSetDef stringio_getset[] = { 8437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"closed", (getter)stringio_closed, NULL, NULL}, 8447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"newlines", (getter)stringio_newlines, NULL, NULL}, 8457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* (following comments straight off of the original Python wrapper:) 8467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel XXX Cruft to support the TextIOWrapper API. This would only 8477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel be meaningful if StringIO supported the buffer attribute. 8487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Hopefully, a better solution, than adding these pseudo-attributes, 8497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel will be found. 8507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 8517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, 8527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {NULL} 8537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 8547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyTypeObject PyStringIO_Type = { 8567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyVarObject_HEAD_INIT(NULL, 0) 8577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "_io.StringIO", /*tp_name*/ 8587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel sizeof(stringio), /*tp_basicsize*/ 8597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_itemsize*/ 8607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (destructor)stringio_dealloc, /*tp_dealloc*/ 8617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_print*/ 8627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_getattr*/ 8637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_setattr*/ 8647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_reserved*/ 8657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_repr*/ 8667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_as_number*/ 8677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_as_sequence*/ 8687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_as_mapping*/ 8697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_hash*/ 8707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_call*/ 8717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_str*/ 8727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_getattro*/ 8737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_setattro*/ 8747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_as_buffer*/ 8757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE 8767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 8777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stringio_doc, /*tp_doc*/ 8787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (traverseproc)stringio_traverse, /*tp_traverse*/ 8797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (inquiry)stringio_clear, /*tp_clear*/ 8807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_richcompare*/ 8817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel offsetof(stringio, weakreflist), /*tp_weaklistoffset*/ 8827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_iter*/ 8837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (iternextfunc)stringio_iternext, /*tp_iternext*/ 8847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stringio_methods, /*tp_methods*/ 8857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_members*/ 8867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stringio_getset, /*tp_getset*/ 8877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_base*/ 8887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_dict*/ 8897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_descr_get*/ 8907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_descr_set*/ 8917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel offsetof(stringio, dict), /*tp_dictoffset*/ 8927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (initproc)stringio_init, /*tp_init*/ 8937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /*tp_alloc*/ 8947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stringio_new, /*tp_new*/ 8957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 896