Manual py3k backport: [svn r74158] Issue #6218: Make io.BytesIO and io.StringIO pickl...
[python.git] / Modules / _io / stringio.c
blob0fc8078951c446e9e11a2be7c7b2a4c00fd53242
1 #define PY_SSIZE_T_CLEAN
2 #include "Python.h"
3 #include "structmember.h"
4 #include "_iomodule.h"
6 /* Implementation note: the buffer is always at least one character longer
7 than the enclosed string, for proper functioning of _PyIO_find_line_ending.
8 */
10 typedef struct {
11 PyObject_HEAD
12 Py_UNICODE *buf;
13 Py_ssize_t pos;
14 Py_ssize_t string_size;
15 size_t buf_size;
17 char ok; /* initialized? */
18 char closed;
19 char readuniversal;
20 char readtranslate;
21 PyObject *decoder;
22 PyObject *readnl;
23 PyObject *writenl;
25 PyObject *dict;
26 PyObject *weakreflist;
27 } stringio;
29 #define CHECK_INITIALIZED(self) \
30 if (self->ok <= 0) { \
31 PyErr_SetString(PyExc_ValueError, \
32 "I/O operation on uninitialized object"); \
33 return NULL; \
36 #define CHECK_CLOSED(self) \
37 if (self->closed) { \
38 PyErr_SetString(PyExc_ValueError, \
39 "I/O operation on closed file"); \
40 return NULL; \
43 PyDoc_STRVAR(stringio_doc,
44 "Text I/O implementation using an in-memory buffer.\n"
45 "\n"
46 "The initial_value argument sets the value of object. The newline\n"
47 "argument is like the one of TextIOWrapper's constructor.");
50 /* Internal routine for changing the size, in terms of characters, of the
51 buffer of StringIO objects. The caller should ensure that the 'size'
52 argument is non-negative. Returns 0 on success, -1 otherwise. */
53 static int
54 resize_buffer(stringio *self, size_t size)
56 /* Here, unsigned types are used to avoid dealing with signed integer
57 overflow, which is undefined in C. */
58 size_t alloc = self->buf_size;
59 Py_UNICODE *new_buf = NULL;
61 assert(self->buf != NULL);
63 /* Reserve one more char for line ending detection. */
64 size = size + 1;
65 /* For simplicity, stay in the range of the signed type. Anyway, Python
66 doesn't allow strings to be longer than this. */
67 if (size > PY_SSIZE_T_MAX)
68 goto overflow;
70 if (size < alloc / 2) {
71 /* Major downsize; resize down to exact size. */
72 alloc = size + 1;
74 else if (size < alloc) {
75 /* Within allocated size; quick exit */
76 return 0;
78 else if (size <= alloc * 1.125) {
79 /* Moderate upsize; overallocate similar to list_resize() */
80 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
82 else {
83 /* Major upsize; resize up to exact size */
84 alloc = size + 1;
87 if (alloc > ((size_t)-1) / sizeof(Py_UNICODE))
88 goto overflow;
89 new_buf = (Py_UNICODE *)PyMem_Realloc(self->buf,
90 alloc * sizeof(Py_UNICODE));
91 if (new_buf == NULL) {
92 PyErr_NoMemory();
93 return -1;
95 self->buf_size = alloc;
96 self->buf = new_buf;
98 return 0;
100 overflow:
101 PyErr_SetString(PyExc_OverflowError,
102 "new buffer size too large");
103 return -1;
106 /* Internal routine for writing a whole PyUnicode object to the buffer of a
107 StringIO object. Returns 0 on success, or -1 on error. */
108 static Py_ssize_t
109 write_str(stringio *self, PyObject *obj)
111 Py_UNICODE *str;
112 Py_ssize_t len;
113 PyObject *decoded = NULL;
114 assert(self->buf != NULL);
115 assert(self->pos >= 0);
117 if (self->decoder != NULL) {
118 decoded = _PyIncrementalNewlineDecoder_decode(
119 self->decoder, obj, 1 /* always final */);
121 else {
122 decoded = obj;
123 Py_INCREF(decoded);
125 if (self->writenl) {
126 PyObject *translated = PyUnicode_Replace(
127 decoded, _PyIO_str_nl, self->writenl, -1);
128 Py_DECREF(decoded);
129 decoded = translated;
131 if (decoded == NULL)
132 return -1;
134 assert(PyUnicode_Check(decoded));
135 str = PyUnicode_AS_UNICODE(decoded);
136 len = PyUnicode_GET_SIZE(decoded);
138 assert(len >= 0);
140 /* This overflow check is not strictly necessary. However, it avoids us to
141 deal with funky things like comparing an unsigned and a signed
142 integer. */
143 if (self->pos > PY_SSIZE_T_MAX - len) {
144 PyErr_SetString(PyExc_OverflowError,
145 "new position too large");
146 goto fail;
148 if (self->pos + len > self->string_size) {
149 if (resize_buffer(self, self->pos + len) < 0)
150 goto fail;
153 if (self->pos > self->string_size) {
154 /* In case of overseek, pad with null bytes the buffer region between
155 the end of stream and the current position.
157 0 lo string_size hi
158 | |<---used--->|<----------available----------->|
159 | | <--to pad-->|<---to write---> |
160 0 buf positon
163 memset(self->buf + self->string_size, '\0',
164 (self->pos - self->string_size) * sizeof(Py_UNICODE));
167 /* Copy the data to the internal buffer, overwriting some of the
168 existing data if self->pos < self->string_size. */
169 memcpy(self->buf + self->pos, str, len * sizeof(Py_UNICODE));
170 self->pos += len;
172 /* Set the new length of the internal string if it has changed. */
173 if (self->string_size < self->pos) {
174 self->string_size = self->pos;
177 Py_DECREF(decoded);
178 return 0;
180 fail:
181 Py_XDECREF(decoded);
182 return -1;
185 PyDoc_STRVAR(stringio_getvalue_doc,
186 "Retrieve the entire contents of the object.");
188 static PyObject *
189 stringio_getvalue(stringio *self)
191 CHECK_INITIALIZED(self);
192 CHECK_CLOSED(self);
193 return PyUnicode_FromUnicode(self->buf, self->string_size);
196 PyDoc_STRVAR(stringio_tell_doc,
197 "Tell the current file position.");
199 static PyObject *
200 stringio_tell(stringio *self)
202 CHECK_INITIALIZED(self);
203 CHECK_CLOSED(self);
204 return PyLong_FromSsize_t(self->pos);
207 PyDoc_STRVAR(stringio_read_doc,
208 "Read at most n characters, returned as a string.\n"
209 "\n"
210 "If the argument is negative or omitted, read until EOF\n"
211 "is reached. Return an empty string at EOF.\n");
213 static PyObject *
214 stringio_read(stringio *self, PyObject *args)
216 Py_ssize_t size, n;
217 Py_UNICODE *output;
218 PyObject *arg = Py_None;
220 CHECK_INITIALIZED(self);
221 if (!PyArg_ParseTuple(args, "|O:read", &arg))
222 return NULL;
223 CHECK_CLOSED(self);
225 if (PyNumber_Check(arg)) {
226 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
227 if (size == -1 && PyErr_Occurred())
228 return NULL;
230 else if (arg == Py_None) {
231 /* Read until EOF is reached, by default. */
232 size = -1;
234 else {
235 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
236 Py_TYPE(arg)->tp_name);
237 return NULL;
240 /* adjust invalid sizes */
241 n = self->string_size - self->pos;
242 if (size < 0 || size > n) {
243 size = n;
244 if (size < 0)
245 size = 0;
248 output = self->buf + self->pos;
249 self->pos += size;
250 return PyUnicode_FromUnicode(output, size);
253 /* Internal helper, used by stringio_readline and stringio_iternext */
254 static PyObject *
255 _stringio_readline(stringio *self, Py_ssize_t limit)
257 Py_UNICODE *start, *end, old_char;
258 Py_ssize_t len, consumed;
260 /* In case of overseek, return the empty string */
261 if (self->pos >= self->string_size)
262 return PyUnicode_FromString("");
264 start = self->buf + self->pos;
265 if (limit < 0 || limit > self->string_size - self->pos)
266 limit = self->string_size - self->pos;
268 end = start + limit;
269 old_char = *end;
270 *end = '\0';
271 len = _PyIO_find_line_ending(
272 self->readtranslate, self->readuniversal, self->readnl,
273 start, end, &consumed);
274 *end = old_char;
275 /* If we haven't found any line ending, we just return everything
276 (`consumed` is ignored). */
277 if (len < 0)
278 len = limit;
279 self->pos += len;
280 return PyUnicode_FromUnicode(start, len);
283 PyDoc_STRVAR(stringio_readline_doc,
284 "Read until newline or EOF.\n"
285 "\n"
286 "Returns an empty string if EOF is hit immediately.\n");
288 static PyObject *
289 stringio_readline(stringio *self, PyObject *args)
291 PyObject *arg = Py_None;
292 Py_ssize_t limit = -1;
294 CHECK_INITIALIZED(self);
295 if (!PyArg_ParseTuple(args, "|O:readline", &arg))
296 return NULL;
297 CHECK_CLOSED(self);
299 if (PyNumber_Check(arg)) {
300 limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
301 if (limit == -1 && PyErr_Occurred())
302 return NULL;
304 else if (arg != Py_None) {
305 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
306 Py_TYPE(arg)->tp_name);
307 return NULL;
309 return _stringio_readline(self, limit);
312 static PyObject *
313 stringio_iternext(stringio *self)
315 PyObject *line;
317 CHECK_INITIALIZED(self);
318 CHECK_CLOSED(self);
320 if (Py_TYPE(self) == &PyStringIO_Type) {
321 /* Skip method call overhead for speed */
322 line = _stringio_readline(self, -1);
324 else {
325 /* XXX is subclassing StringIO really supported? */
326 line = PyObject_CallMethodObjArgs((PyObject *)self,
327 _PyIO_str_readline, NULL);
328 if (line && !PyUnicode_Check(line)) {
329 PyErr_Format(PyExc_IOError,
330 "readline() should have returned an str object, "
331 "not '%.200s'", Py_TYPE(line)->tp_name);
332 Py_DECREF(line);
333 return NULL;
337 if (line == NULL)
338 return NULL;
340 if (PyUnicode_GET_SIZE(line) == 0) {
341 /* Reached EOF */
342 Py_DECREF(line);
343 return NULL;
346 return line;
349 PyDoc_STRVAR(stringio_truncate_doc,
350 "Truncate size to pos.\n"
351 "\n"
352 "The pos argument defaults to the current file position, as\n"
353 "returned by tell(). Imply an absolute seek to pos.\n"
354 "Returns the new absolute position.\n");
356 static PyObject *
357 stringio_truncate(stringio *self, PyObject *args)
359 Py_ssize_t size;
360 PyObject *arg = Py_None;
362 CHECK_INITIALIZED(self);
363 if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
364 return NULL;
365 CHECK_CLOSED(self);
367 if (PyNumber_Check(arg)) {
368 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
369 if (size == -1 && PyErr_Occurred())
370 return NULL;
372 else if (arg == Py_None) {
373 /* Truncate to current position if no argument is passed. */
374 size = self->pos;
376 else {
377 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
378 Py_TYPE(arg)->tp_name);
379 return NULL;
382 if (size < 0) {
383 PyErr_Format(PyExc_ValueError,
384 "Negative size value %zd", size);
385 return NULL;
388 if (size < self->string_size) {
389 if (resize_buffer(self, size) < 0)
390 return NULL;
391 self->string_size = size;
393 self->pos = size;
395 return PyLong_FromSsize_t(size);
398 PyDoc_STRVAR(stringio_seek_doc,
399 "Change stream position.\n"
400 "\n"
401 "Seek to character offset pos relative to position indicated by whence:\n"
402 " 0 Start of stream (the default). pos should be >= 0;\n"
403 " 1 Current position - pos must be 0;\n"
404 " 2 End of stream - pos must be 0.\n"
405 "Returns the new absolute position.\n");
407 static PyObject *
408 stringio_seek(stringio *self, PyObject *args)
410 PyObject *posobj;
411 Py_ssize_t pos;
412 int mode = 0;
414 CHECK_INITIALIZED(self);
415 if (!PyArg_ParseTuple(args, "O|i:seek", &posobj, &mode))
416 return NULL;
418 pos = PyNumber_AsSsize_t(posobj, PyExc_OverflowError);
419 if (pos == -1 && PyErr_Occurred())
420 return NULL;
422 CHECK_CLOSED(self);
424 if (mode != 0 && mode != 1 && mode != 2) {
425 PyErr_Format(PyExc_ValueError,
426 "Invalid whence (%i, should be 0, 1 or 2)", mode);
427 return NULL;
429 else if (pos < 0 && mode == 0) {
430 PyErr_Format(PyExc_ValueError,
431 "Negative seek position %zd", pos);
432 return NULL;
434 else if (mode != 0 && pos != 0) {
435 PyErr_SetString(PyExc_IOError,
436 "Can't do nonzero cur-relative seeks");
437 return NULL;
440 /* mode 0: offset relative to beginning of the string.
441 mode 1: no change to current position.
442 mode 2: change position to end of file. */
443 if (mode == 1) {
444 pos = self->pos;
446 else if (mode == 2) {
447 pos = self->string_size;
450 self->pos = pos;
452 return PyLong_FromSsize_t(self->pos);
455 PyDoc_STRVAR(stringio_write_doc,
456 "Write string to file.\n"
457 "\n"
458 "Returns the number of characters written, which is always equal to\n"
459 "the length of the string.\n");
461 static PyObject *
462 stringio_write(stringio *self, PyObject *obj)
464 Py_ssize_t size;
466 CHECK_INITIALIZED(self);
467 if (!PyUnicode_Check(obj)) {
468 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
469 Py_TYPE(obj)->tp_name);
470 return NULL;
472 CHECK_CLOSED(self);
473 size = PyUnicode_GET_SIZE(obj);
475 if (size > 0 && write_str(self, obj) < 0)
476 return NULL;
478 return PyLong_FromSsize_t(size);
481 PyDoc_STRVAR(stringio_close_doc,
482 "Close the IO object. Attempting any further operation after the\n"
483 "object is closed will raise a ValueError.\n"
484 "\n"
485 "This method has no effect if the file is already closed.\n");
487 static PyObject *
488 stringio_close(stringio *self)
490 self->closed = 1;
491 /* Free up some memory */
492 if (resize_buffer(self, 0) < 0)
493 return NULL;
494 Py_CLEAR(self->readnl);
495 Py_CLEAR(self->writenl);
496 Py_CLEAR(self->decoder);
497 Py_RETURN_NONE;
500 static int
501 stringio_traverse(stringio *self, visitproc visit, void *arg)
503 Py_VISIT(self->dict);
504 return 0;
507 static int
508 stringio_clear(stringio *self)
510 Py_CLEAR(self->dict);
511 return 0;
514 static void
515 stringio_dealloc(stringio *self)
517 _PyObject_GC_UNTRACK(self);
518 self->ok = 0;
519 if (self->buf) {
520 PyMem_Free(self->buf);
521 self->buf = NULL;
523 Py_CLEAR(self->readnl);
524 Py_CLEAR(self->writenl);
525 Py_CLEAR(self->decoder);
526 Py_CLEAR(self->dict);
527 if (self->weakreflist != NULL)
528 PyObject_ClearWeakRefs((PyObject *) self);
529 Py_TYPE(self)->tp_free(self);
532 static PyObject *
533 stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
535 stringio *self;
537 assert(type != NULL && type->tp_alloc != NULL);
538 self = (stringio *)type->tp_alloc(type, 0);
539 if (self == NULL)
540 return NULL;
542 /* tp_alloc initializes all the fields to zero. So we don't have to
543 initialize them here. */
545 self->buf = (Py_UNICODE *)PyMem_Malloc(0);
546 if (self->buf == NULL) {
547 Py_DECREF(self);
548 return PyErr_NoMemory();
551 return (PyObject *)self;
554 static int
555 stringio_init(stringio *self, PyObject *args, PyObject *kwds)
557 char *kwlist[] = {"initial_value", "newline", NULL};
558 PyObject *value = NULL;
559 char *newline = "\n";
561 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz:__init__", kwlist,
562 &value, &newline))
563 return -1;
565 if (newline && newline[0] != '\0'
566 && !(newline[0] == '\n' && newline[1] == '\0')
567 && !(newline[0] == '\r' && newline[1] == '\0')
568 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
569 PyErr_Format(PyExc_ValueError,
570 "illegal newline value: %s", newline);
571 return -1;
573 if (value && value != Py_None && !PyUnicode_Check(value)) {
574 PyErr_Format(PyExc_TypeError,
575 "initial_value must be unicode or None, not %.200s",
576 Py_TYPE(value)->tp_name);
577 return -1;
580 self->ok = 0;
582 Py_CLEAR(self->readnl);
583 Py_CLEAR(self->writenl);
584 Py_CLEAR(self->decoder);
586 assert((newline != NULL && newline_obj != Py_None) ||
587 (newline == NULL && newline_obj == Py_None));
589 if (newline) {
590 self->readnl = PyString_FromString(newline);
591 if (self->readnl == NULL)
592 return -1;
594 self->readuniversal = (newline == NULL || newline[0] == '\0');
595 self->readtranslate = (newline == NULL);
596 /* If newline == "", we don't translate anything.
597 If newline == "\n" or newline == None, we translate to "\n", which is
598 a no-op.
599 (for newline == None, TextIOWrapper translates to os.sepline, but it
600 is pointless for StringIO)
602 if (newline != NULL && newline[0] == '\r') {
603 self->writenl = PyUnicode_FromString(newline);
606 if (self->readuniversal) {
607 self->decoder = PyObject_CallFunction(
608 (PyObject *)&PyIncrementalNewlineDecoder_Type,
609 "Oi", Py_None, (int) self->readtranslate);
610 if (self->decoder == NULL)
611 return -1;
614 /* Now everything is set up, resize buffer to size of initial value,
615 and copy it */
616 self->string_size = 0;
617 if (value && value != Py_None) {
618 Py_ssize_t len = PyUnicode_GetSize(value);
619 /* This is a heuristic, for newline translation might change
620 the string length. */
621 if (resize_buffer(self, len) < 0)
622 return -1;
623 self->pos = 0;
624 if (write_str(self, value) < 0)
625 return -1;
627 else {
628 if (resize_buffer(self, 0) < 0)
629 return -1;
631 self->pos = 0;
633 self->closed = 0;
634 self->ok = 1;
635 return 0;
638 /* Properties and pseudo-properties */
639 static PyObject *
640 stringio_seekable(stringio *self, PyObject *args)
642 CHECK_INITIALIZED(self);
643 Py_RETURN_TRUE;
646 static PyObject *
647 stringio_readable(stringio *self, PyObject *args)
649 CHECK_INITIALIZED(self);
650 Py_RETURN_TRUE;
653 static PyObject *
654 stringio_writable(stringio *self, PyObject *args)
656 CHECK_INITIALIZED(self);
657 Py_RETURN_TRUE;
660 /* Pickling support.
662 The implementation of __getstate__ is similar to the one for BytesIO,
663 except that we also save the newline parameter. For __setstate__ and unlike
664 BytesIO, we call __init__ to restore the object's state. Doing so allows us
665 to avoid decoding the complex newline state while keeping the object
666 representation compact.
668 See comment in bytesio.c regarding why only pickle protocols and onward are
669 supported.
672 static PyObject *
673 stringio_getstate(stringio *self)
675 PyObject *initvalue = stringio_getvalue(self);
676 PyObject *dict;
677 PyObject *state;
679 if (initvalue == NULL)
680 return NULL;
681 if (self->dict == NULL) {
682 Py_INCREF(Py_None);
683 dict = Py_None;
685 else {
686 dict = PyDict_Copy(self->dict);
687 if (dict == NULL)
688 return NULL;
691 state = Py_BuildValue("(OOnN)", initvalue,
692 self->readnl ? self->readnl : Py_None,
693 self->pos, dict);
694 Py_DECREF(initvalue);
695 return state;
698 static PyObject *
699 stringio_setstate(stringio *self, PyObject *state)
701 PyObject *initarg;
702 PyObject *position_obj;
703 PyObject *dict;
704 Py_ssize_t pos;
706 assert(state != NULL);
707 CHECK_CLOSED(self);
709 /* We allow the state tuple to be longer than 4, because we may need
710 someday to extend the object's state without breaking
711 backward-compatibility. */
712 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
713 PyErr_Format(PyExc_TypeError,
714 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
715 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
716 return NULL;
719 /* Initialize the object's state. */
720 initarg = PyTuple_GetSlice(state, 0, 2);
721 if (initarg == NULL)
722 return NULL;
723 if (stringio_init(self, initarg, NULL) < 0) {
724 Py_DECREF(initarg);
725 return NULL;
727 Py_DECREF(initarg);
729 /* Restore the buffer state. Even if __init__ did initialize the buffer,
730 we have to initialize it again since __init__ may translates the
731 newlines in the inital_value string. We clearly do not want that
732 because the string value in the state tuple has already been translated
733 once by __init__. So we do not take any chance and replace object's
734 buffer completely. */
736 Py_UNICODE *buf = PyUnicode_AS_UNICODE(PyTuple_GET_ITEM(state, 0));
737 Py_ssize_t bufsize = PyUnicode_GET_SIZE(PyTuple_GET_ITEM(state, 0));
738 if (resize_buffer(self, bufsize) < 0)
739 return NULL;
740 memcpy(self->buf, buf, bufsize * sizeof(Py_UNICODE));
741 self->string_size = bufsize;
744 /* Set carefully the position value. Alternatively, we could use the seek
745 method instead of modifying self->pos directly to better protect the
746 object internal state against errneous (or malicious) inputs. */
747 position_obj = PyTuple_GET_ITEM(state, 2);
748 if (!PyIndex_Check(position_obj)) {
749 PyErr_Format(PyExc_TypeError,
750 "third item of state must be an integer, got %.200s",
751 Py_TYPE(position_obj)->tp_name);
752 return NULL;
754 pos = PyNumber_AsSsize_t(position_obj, PyExc_OverflowError);
755 if (pos == -1 && PyErr_Occurred())
756 return NULL;
757 if (pos < 0) {
758 PyErr_SetString(PyExc_ValueError,
759 "position value cannot be negative");
760 return NULL;
762 self->pos = pos;
764 /* Set the dictionary of the instance variables. */
765 dict = PyTuple_GET_ITEM(state, 3);
766 if (dict != Py_None) {
767 if (!PyDict_Check(dict)) {
768 PyErr_Format(PyExc_TypeError,
769 "fourth item of state should be a dict, got a %.200s",
770 Py_TYPE(dict)->tp_name);
771 return NULL;
773 if (self->dict) {
774 /* Alternatively, we could replace the internal dictionary
775 completely. However, it seems more practical to just update it. */
776 if (PyDict_Update(self->dict, dict) < 0)
777 return NULL;
779 else {
780 Py_INCREF(dict);
781 self->dict = dict;
785 Py_RETURN_NONE;
789 static PyObject *
790 stringio_closed(stringio *self, void *context)
792 CHECK_INITIALIZED(self);
793 return PyBool_FromLong(self->closed);
796 static PyObject *
797 stringio_line_buffering(stringio *self, void *context)
799 CHECK_INITIALIZED(self);
800 CHECK_CLOSED(self);
801 Py_RETURN_FALSE;
804 static PyObject *
805 stringio_newlines(stringio *self, void *context)
807 CHECK_INITIALIZED(self);
808 CHECK_CLOSED(self);
809 if (self->decoder == NULL)
810 Py_RETURN_NONE;
811 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
814 static struct PyMethodDef stringio_methods[] = {
815 {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
816 {"getvalue", (PyCFunction)stringio_getvalue, METH_VARARGS, stringio_getvalue_doc},
817 {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
818 {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
819 {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
820 {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc},
821 {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc},
822 {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc},
824 {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS},
825 {"readable", (PyCFunction)stringio_readable, METH_NOARGS},
826 {"writable", (PyCFunction)stringio_writable, METH_NOARGS},
828 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
829 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
830 {NULL, NULL} /* sentinel */
833 static PyGetSetDef stringio_getset[] = {
834 {"closed", (getter)stringio_closed, NULL, NULL},
835 {"newlines", (getter)stringio_newlines, NULL, NULL},
836 /* (following comments straight off of the original Python wrapper:)
837 XXX Cruft to support the TextIOWrapper API. This would only
838 be meaningful if StringIO supported the buffer attribute.
839 Hopefully, a better solution, than adding these pseudo-attributes,
840 will be found.
842 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
843 {NULL}
846 PyTypeObject PyStringIO_Type = {
847 PyVarObject_HEAD_INIT(NULL, 0)
848 "_io.StringIO", /*tp_name*/
849 sizeof(stringio), /*tp_basicsize*/
850 0, /*tp_itemsize*/
851 (destructor)stringio_dealloc, /*tp_dealloc*/
852 0, /*tp_print*/
853 0, /*tp_getattr*/
854 0, /*tp_setattr*/
855 0, /*tp_reserved*/
856 0, /*tp_repr*/
857 0, /*tp_as_number*/
858 0, /*tp_as_sequence*/
859 0, /*tp_as_mapping*/
860 0, /*tp_hash*/
861 0, /*tp_call*/
862 0, /*tp_str*/
863 0, /*tp_getattro*/
864 0, /*tp_setattro*/
865 0, /*tp_as_buffer*/
866 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
867 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
868 stringio_doc, /*tp_doc*/
869 (traverseproc)stringio_traverse, /*tp_traverse*/
870 (inquiry)stringio_clear, /*tp_clear*/
871 0, /*tp_richcompare*/
872 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
873 0, /*tp_iter*/
874 (iternextfunc)stringio_iternext, /*tp_iternext*/
875 stringio_methods, /*tp_methods*/
876 0, /*tp_members*/
877 stringio_getset, /*tp_getset*/
878 0, /*tp_base*/
879 0, /*tp_dict*/
880 0, /*tp_descr_get*/
881 0, /*tp_descr_set*/
882 offsetof(stringio, dict), /*tp_dictoffset*/
883 (initproc)stringio_init, /*tp_init*/
884 0, /*tp_alloc*/
885 stringio_new, /*tp_new*/