17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "import.h"
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "cStringIO.h"
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "structmember.h"
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(cStringIO_module_documentation,
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"A simple fast partial StringIO replacement.\n"
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"This module provides a simple useful replacement for\n"
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"the StringIO module that is written in C.  It does not provide the\n"
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"full generality of StringIO, but it provides enough for most\n"
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"applications and is especially useful in conjunction with the\n"
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"pickle module.\n"
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Usage:\n"
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  from cStringIO import StringIO\n"
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  an_output_stream=StringIO()\n"
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  an_output_stream.write(some_stuff)\n"
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  ...\n"
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  value=an_output_stream.getvalue()\n"
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  an_input_stream=StringIO(a_string)\n"
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  spam=an_input_stream.readline()\n"
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  spam=an_input_stream.read(5)\n"
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  an_input_stream.seek(0)           # OK, start over\n"
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  spam=an_input_stream.read()       # and read it all\n"
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  \n"
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"If someone else wants to provide a more complete implementation,\n"
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"go for it. :-)  \n"
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Declaration for file-like objects that manage data as strings
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   The IOobject type should be though of as a common base type for
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Iobjects, which provide input (read-only) StringIO objects and
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Oobjects, which provide read-write objects.  Most of the methods
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   depend only on common data.
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct {
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject_HEAD
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  char *buf;
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_ssize_t pos, string_size;
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} IOobject;
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define IOOOBJECT(O) ((IOobject*)(O))
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Declarations for objects of type StringO */
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct { /* Subtype of IOobject */
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject_HEAD
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  char *buf;
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_ssize_t pos, string_size;
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_ssize_t buf_size;
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  int softspace;
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} Oobject;
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Declarations for objects of type StringI */
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct { /* Subtype of IOobject */
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject_HEAD
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  char *buf;
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_ssize_t pos, string_size;
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_buffer pbuf;
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} Iobject;
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* IOobject (common) methods */
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO__opencheck(IOobject *self) {
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!self->buf) {
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "I/O operation on closed file");
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 1;
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_get_closed(IOobject *self, void *closure)
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = Py_False;
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buf == NULL)
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = Py_True;
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(result);
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyGetSetDef file_getsetlist[] = {
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {0},
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_flush(IOobject *self, PyObject *unused) {
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(self)) return NULL;
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_getval__doc__,
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"getvalue([use_pos]) -- Get the string value."
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"If use_pos is specified and is a true value, then the string returned\n"
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"will include only the text up to the current file position.\n");
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_cgetval(PyObject *self) {
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(IOOOBJECT(self))) return NULL;
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->pos >= 0);
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize(((IOobject*)self)->buf,
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                      ((IOobject*)self)->pos);
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_getval(IOobject *self, PyObject *args) {
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *use_pos=Py_None;
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int b;
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t s;
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(self)) return NULL;
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    b = PyObject_IsTrue(use_pos);
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (b < 0)
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (b) {
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              s=self->pos;
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              if (s > self->string_size) s=self->string_size;
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              s=self->string_size;
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(self->pos >= 0);
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize(self->buf, s);
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_isatty(IOobject *self, PyObject *unused) {
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(self)) return NULL;
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_False);
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_False;
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_read__doc__,
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"read([s]) -- Read s characters, or the rest of the string");
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_cread(PyObject *self, char **output, Py_ssize_t  n) {
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t l;
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(IOOOBJECT(self))) return -1;
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->pos >= 0);
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->string_size >= 0);
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (n < 0 || n > l) {
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        n = l;
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (n < 0) n=0;
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (n > INT_MAX) {
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_OverflowError,
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "length too large");
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ((IOobject*)self)->pos += n;
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (int)n;
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_read(IOobject *self, PyObject *args) {
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t n = -1;
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *output = NULL;
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize(output, n);
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_creadline(PyObject *self, char **output) {
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *n, *start, *end;
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t len;
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(IOOOBJECT(self))) return -1;
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    n = start = ((IOobject*)self)->buf + ((IOobject*)self)->pos;
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    end = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (n < end && *n != '\n')
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        n++;
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (n < end) n++;
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = n - start;
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len > INT_MAX)
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        len = INT_MAX;
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    *output=start;
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->pos <= PY_SSIZE_T_MAX - len);
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->pos >= 0);
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->string_size >= 0);
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ((IOobject*)self)->pos += len;
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (int)len;
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_readline(IOobject *self, PyObject *args) {
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int n, m=-1;
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *output;
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (args)
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (m >= 0 && m < n) {
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        m = n - m;
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        n -= m;
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->pos -= m;
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(IOOOBJECT(self)->pos >= 0);
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize(output, n);
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_readlines(IOobject *self, PyObject *args) {
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int n;
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *output;
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result, *line;
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t hint = 0, length = 0;
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "|n:readlines", &hint)) return NULL;
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = PyList_New(0);
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!result)
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (1){
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto err;
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (n == 0)
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        line = PyString_FromStringAndSize (output, n);
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!line)
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto err;
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (PyList_Append (result, line) == -1) {
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF (line);
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto err;
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF (line);
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        length += n;
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (hint > 0 && length >= hint)
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel err:
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(result);
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return NULL;
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_reset__doc__,
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"reset() -- Reset the file position to the beginning");
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_reset(IOobject *self, PyObject *unused) {
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(self)) return NULL;
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->pos = 0;
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_tell(IOobject *self, PyObject *unused) {
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(self)) return NULL;
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(self->pos >= 0);
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromSsize_t(self->pos);
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_truncate__doc__,
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"truncate(): truncate the file at the current position.");
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_truncate(IOobject *self, PyObject *args) {
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t pos = -1;
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(self)) return NULL;
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyTuple_Size(args) == 0) {
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* No argument passed, truncate to current position */
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        pos = self->pos;
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (pos < 0) {
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        errno = EINVAL;
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetFromErrno(PyExc_IOError);
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->string_size > pos) self->string_size = pos;
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->pos = self->string_size;
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_iternext(Iobject *self)
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *next;
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    next = IO_readline((IOobject *)self, NULL);
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!next)
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyString_GET_SIZE(next)) {
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(next);
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetNone(PyExc_StopIteration);
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return next;
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Read-write object methods */
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_seek__doc__,
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"seek(position)       -- set the current position\n"
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_seek(Iobject *self, PyObject *args) {
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t position;
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int mode = 0;
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(IOOOBJECT(self))) return NULL;
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (mode == 2) {
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        position += self->string_size;
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (mode == 1) {
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        position += self->pos;
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (position < 0) position=0;
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->pos=position;
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(O_write__doc__,
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"write(s) -- Write a string to the file"
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n\nNote (hack:) writing None resets the buffer");
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielO_cwrite(PyObject *self, const char *c, Py_ssize_t  len) {
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t newpos;
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Oobject *oself;
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *newbuf;
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!IO__opencheck(IOOOBJECT(self))) return -1;
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    oself = (Oobject *)self;
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len > INT_MAX) {
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_OverflowError,
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "length too large");
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(len >= 0);
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (oself->pos >= PY_SSIZE_T_MAX - len) {
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_OverflowError,
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "new position too large");
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    newpos = oself->pos + len;
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (newpos >= oself->buf_size) {
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        size_t newsize = oself->buf_size;
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        newsize *= 2;
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (newsize <= (size_t)newpos || newsize > PY_SSIZE_T_MAX) {
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            assert(newpos < PY_SSIZE_T_MAX - 1);
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            newsize = newpos + 1;
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        newbuf = (char*)realloc(oself->buf, newsize);
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!newbuf) {
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetString(PyExc_MemoryError,"out of memory");
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        oself->buf_size = (Py_ssize_t)newsize;
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        oself->buf = newbuf;
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (oself->string_size < oself->pos) {
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* In case of overseek, pad with null bytes the buffer region between
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           the end of stream and the current position.
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          0   lo      string_size                           hi
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          |   |<---used--->|<----------available----------->|
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          |   |            <--to pad-->|<---to write--->    |
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          0   buf                   position
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        */
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        memset(oself->buf + oself->string_size, '\0',
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               (oself->pos - oself->string_size) * sizeof(char));
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    memcpy(oself->buf + oself->pos, c, len);
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    oself->pos = newpos;
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (oself->string_size < oself->pos) {
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        oself->string_size = oself->pos;
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (int)len;
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielO_write(Oobject *self, PyObject *args) {
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_buffer buf;
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int result;
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "s*:write", &buf)) return NULL;
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = O_cwrite((PyObject*)self, buf.buf, buf.len);
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBuffer_Release(&buf);
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (result < 0) return NULL;
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielO_close(Oobject *self, PyObject *unused) {
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buf != NULL) free(self->buf);
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buf = NULL;
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->pos = self->string_size = self->buf_size = 0;
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(O_writelines__doc__,
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Note that newlines are not added.  The sequence can be any iterable object\n"
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"producing strings. This is equivalent to calling write() for each string.");
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielO_writelines(Oobject *self, PyObject *args) {
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *it, *s;
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    it = PyObject_GetIter(args);
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (it == NULL)
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while ((s = PyIter_Next(it)) != NULL) {
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_ssize_t n;
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        char *c;
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (PyString_AsStringAndSize(s, &c, &n) == -1) {
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(it);
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(s);
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (O_cwrite((PyObject *)self, c, n) == -1) {
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(it);
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(s);
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           }
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           Py_DECREF(s);
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       }
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       Py_DECREF(it);
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       /* See if PyIter_Next failed */
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       if (PyErr_Occurred())
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           return NULL;
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       Py_RETURN_NONE;
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef O_methods[] = {
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Common methods: */
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"read",      (PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"readline",  (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"reset",     (PyCFunction)IO_reset,    METH_NOARGS,  IO_reset__doc__},
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"seek",      (PyCFunction)IO_seek,     METH_VARARGS, IO_seek__doc__},
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Read-write StringIO specific  methods: */
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"write",      (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"writelines", (PyCFunction)O_writelines, METH_O,       O_writelines__doc__},
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {NULL,         NULL}          /* sentinel */
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMemberDef O_memberlist[] = {
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"softspace",       T_INT,  offsetof(Oobject, softspace),   0,
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     "flag indicating that a space needs to be printed; used by print"},
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     /* getattr(f, "closed") is implemented without this table */
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL} /* Sentinel */
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielO_dealloc(Oobject *self) {
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buf != NULL)
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        free(self->buf);
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_Del(self);
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject Otype = {
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyVarObject_HEAD_INIT(NULL, 0)
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  "cStringIO.StringO",          /*tp_name*/
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  sizeof(Oobject),              /*tp_basicsize*/
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_itemsize*/
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* methods */
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  (destructor)O_dealloc,        /*tp_dealloc*/
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_print*/
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_getattr */
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_setattr */
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_compare*/
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_repr*/
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_as_number*/
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_as_sequence*/
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_as_mapping*/
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_hash*/
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0     ,                       /*tp_call*/
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_str*/
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_getattro */
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_setattro */
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_as_buffer */
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_TPFLAGS_DEFAULT,           /*tp_flags*/
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Otype__doc__,                 /*tp_doc */
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_traverse */
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_clear */
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_richcompare */
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                            /*tp_weaklistoffset */
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject_SelfIter,            /*tp_iter */
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  (iternextfunc)IO_iternext,    /*tp_iternext */
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  O_methods,                    /*tp_methods */
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  O_memberlist,                 /*tp_members */
5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  file_getsetlist,              /*tp_getset */
5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnewOobject(int  size) {
5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Oobject *self;
5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self = PyObject_New(Oobject, &Otype);
5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL)
5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->pos=0;
5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->string_size = 0;
5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->softspace = 0;
5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buf = (char *)malloc(size);
5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!self->buf) {
5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              PyErr_SetString(PyExc_MemoryError,"out of memory");
5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              self->buf_size = 0;
5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              Py_DECREF(self);
5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              return NULL;
5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buf_size=size;
6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (PyObject*)self;
6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* End of code for StringO objects */
6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -------------------------------------------------------- */
6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielI_close(Iobject *self, PyObject *unused) {
6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBuffer_Release(&self->pbuf);
6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buf = NULL;
6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->pos = self->string_size = 0;
6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef I_methods[] = {
6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Common methods: */
6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"read",      (PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"readline",  (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"reset",     (PyCFunction)IO_reset,    METH_NOARGS,  IO_reset__doc__},
6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"seek",      (PyCFunction)IO_seek,     METH_VARARGS, IO_seek__doc__},
6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Read-only StringIO specific  methods: */
6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {NULL,        NULL}
6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielI_dealloc(Iobject *self) {
6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyBuffer_Release(&self->pbuf);
6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject_Del(self);
6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(Itype__doc__,
6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Simple type for treating strings as input file streams");
6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject Itype = {
6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyVarObject_HEAD_INIT(NULL, 0)
6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  "cStringIO.StringI",                  /*tp_name*/
6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  sizeof(Iobject),                      /*tp_basicsize*/
6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_itemsize*/
6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* methods */
6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  (destructor)I_dealloc,                /*tp_dealloc*/
6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_print*/
6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_getattr */
6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_setattr*/
6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_compare*/
6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_repr*/
6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_as_number*/
6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_as_sequence*/
6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_as_mapping*/
6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_hash*/
6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_call*/
6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /*tp_str*/
6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_getattro */
6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_setattro */
6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_as_buffer */
6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_TPFLAGS_DEFAULT,                   /* tp_flags */
6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Itype__doc__,                         /* tp_doc */
6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_traverse */
6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_clear */
6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_richcompare */
6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_weaklistoffset */
6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject_SelfIter,                    /* tp_iter */
6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  (iternextfunc)IO_iternext,            /* tp_iternext */
6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  I_methods,                            /* tp_methods */
6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  0,                                    /* tp_members */
6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  file_getsetlist,                      /* tp_getset */
6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnewIobject(PyObject *s) {
6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Iobject *self;
6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_buffer buf;
6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject *args;
6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  int result;
6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  args = Py_BuildValue("(O)", s);
6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (args == NULL)
6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      return NULL;
6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  result = PyArg_ParseTuple(args, "s*:StringIO", &buf);
6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_DECREF(args);
6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (!result)
6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      return NULL;
6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  self = PyObject_New(Iobject, &Itype);
6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (!self) {
6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      PyBuffer_Release(&buf);
6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      return NULL;
6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  }
7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  self->buf=buf.buf;
7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  self->string_size=buf.len;
7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  self->pbuf=buf;
7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  self->pos=0;
7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  return (PyObject*)self;
7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* End of code for StringI objects */
7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -------------------------------------------------------- */
7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(IO_StringIO__doc__,
7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIO_StringIO(PyObject *self, PyObject *args) {
7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject *s=0;
7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (s) return newIobject(s);
7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  return newOobject(128);
7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* List of methods defined in the module */
7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef IO_methods[] = {
7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {"StringIO",  (PyCFunction)IO_StringIO,
7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   METH_VARARGS,        IO_StringIO__doc__},
7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  {NULL,                NULL}           /* sentinel */
7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Initialization function for the module (*must* be called initcStringIO) */
7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PycStringIO_CAPI CAPI = {
7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  IO_cread,
7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  IO_creadline,
7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  O_cwrite,
7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  IO_cgetval,
7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  newOobject,
7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  newIobject,
7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  &Itype,
7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  &Otype,
7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyMODINIT_FUNC void
7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinitcStringIO(void) {
7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyObject *m, *d, *v;
7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Create the module and add the functions */
7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  m = Py_InitModule4("cStringIO", IO_methods,
7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     cStringIO_module_documentation,
7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     (PyObject*)NULL,PYTHON_API_VERSION);
7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (m == NULL) return;
7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Add some symbolic constants to the module */
7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  d = PyModule_GetDict(m);
7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Export C API */
7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_TYPE(&Itype)=&PyType_Type;
7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_TYPE(&Otype)=&PyType_Type;
7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (PyType_Ready(&Otype) < 0) return;
7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (PyType_Ready(&Itype) < 0) return;
7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  v = PyCapsule_New(&CAPI, PycStringIO_CAPSULE_NAME, NULL);
7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyDict_SetItemString(d,"cStringIO_CAPI", v);
7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  Py_XDECREF(v);
7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Export Types */
7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  /* Maybe make certain warnings go away */
7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  if (0) PycString_IMPORT;
7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
780