
#include "Python.h"
#include "import.h"
#include "cStringIO.h"
#include "structmember.h"

PyDoc_STRVAR(cStringIO_module_documentation,
"A simple fast partial StringIO replacement.\n"
"\n"
"This module provides a simple useful replacement for\n"
"the StringIO module that is written in C.  It does not provide the\n"
"full generality of StringIO, but it provides enough for most\n"
"applications and is especially useful in conjunction with the\n"
"pickle module.\n"
"\n"
"Usage:\n"
"\n"
"  from cStringIO import StringIO\n"
"\n"
"  an_output_stream=StringIO()\n"
"  an_output_stream.write(some_stuff)\n"
"  ...\n"
"  value=an_output_stream.getvalue()\n"
"\n"
"  an_input_stream=StringIO(a_string)\n"
"  spam=an_input_stream.readline()\n"
"  spam=an_input_stream.read(5)\n"
"  an_input_stream.seek(0)           # OK, start over\n"
"  spam=an_input_stream.read()       # and read it all\n"
"  \n"
"If someone else wants to provide a more complete implementation,\n"
"go for it. :-)  \n"
"\n"
"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");

/* Declaration for file-like objects that manage data as strings 

   The IOobject type should be though of as a common base type for
   Iobjects, which provide input (read-only) StringIO objects and
   Oobjects, which provide read-write objects.  Most of the methods
   depend only on common data.
*/

typedef struct {
  PyObject_HEAD
  char *buf;
  Py_ssize_t pos, string_size;
} IOobject;

#define IOOOBJECT(O) ((IOobject*)(O))

/* Declarations for objects of type StringO */

typedef struct { /* Subtype of IOobject */
  PyObject_HEAD
  char *buf;
  Py_ssize_t pos, string_size;

  Py_ssize_t buf_size;
  int softspace;
} Oobject;

/* Declarations for objects of type StringI */

typedef struct { /* Subtype of IOobject */
  PyObject_HEAD
  char *buf;
  Py_ssize_t pos, string_size;
  /* We store a reference to the object here in order to keep
     the buffer alive during the lifetime of the Iobject. */
  PyObject *pbuf;
} Iobject;

/* IOobject (common) methods */

PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");

static int
IO__opencheck(IOobject *self) {
        if (!self->buf) {
                PyErr_SetString(PyExc_ValueError,
                                "I/O operation on closed file");
                return 0;
        }
        return 1;
}

static PyObject *
IO_get_closed(IOobject *self, void *closure)
{
	PyObject *result = Py_False;

	if (self->buf == NULL)
		result = Py_True;
	Py_INCREF(result);
	return result;
}

static PyGetSetDef file_getsetlist[] = {
	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
	{0},
};

static PyObject *
IO_flush(IOobject *self, PyObject *unused) {

        if (!IO__opencheck(self)) return NULL;

        Py_INCREF(Py_None);
        return Py_None;
}

PyDoc_STRVAR(IO_getval__doc__,
"getvalue([use_pos]) -- Get the string value."
"\n"
"If use_pos is specified and is a true value, then the string returned\n"
"will include only the text up to the current file position.\n");

static PyObject *
IO_cgetval(PyObject *self) {
        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
        return PyString_FromStringAndSize(((IOobject*)self)->buf,
                                          ((IOobject*)self)->pos);
}

static PyObject *
IO_getval(IOobject *self, PyObject *args) {
        PyObject *use_pos=Py_None;
        Py_ssize_t s;

        if (!IO__opencheck(self)) return NULL;
        if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;

        if (PyObject_IsTrue(use_pos)) {
                  s=self->pos;
                  if (s > self->string_size) s=self->string_size;
        }
        else
                  s=self->string_size;
        return PyString_FromStringAndSize(self->buf, s);
}

PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");

static PyObject *
IO_isatty(IOobject *self, PyObject *unused) {
        if (!IO__opencheck(self)) return NULL;
        Py_INCREF(Py_False);
        return Py_False;
}

PyDoc_STRVAR(IO_read__doc__,
"read([s]) -- Read s characters, or the rest of the string");

static int
IO_cread(PyObject *self, char **output, Py_ssize_t  n) {
        Py_ssize_t l;

        if (!IO__opencheck(IOOOBJECT(self))) return -1;
        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;  
        if (n < 0 || n > l) {
                n = l;
                if (n < 0) n=0;
        }

        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
        ((IOobject*)self)->pos += n;
        return n;
}

static PyObject *
IO_read(IOobject *self, PyObject *args) {
        Py_ssize_t n = -1;
        char *output = NULL;

        if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;

        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;

        return PyString_FromStringAndSize(output, n);
}

PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");

static int
IO_creadline(PyObject *self, char **output) {
        char *n, *s;
        Py_ssize_t l;

        if (!IO__opencheck(IOOOBJECT(self))) return -1;

        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size; 
             n < s && *n != '\n'; n++);
        if (n < s) n++;

        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
	assert(((IOobject*)self)->pos + l < INT_MAX);
        ((IOobject*)self)->pos += (int)l;
        return (int)l;
}

static PyObject *
IO_readline(IOobject *self, PyObject *args) {
        int n, m=-1;
        char *output;

        if (args)
                if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;

        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
        if (m >= 0 && m < n) {
                m = n - m;
                n -= m;
                self->pos -= m;
        }
        return PyString_FromStringAndSize(output, n);
}

PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");

static PyObject *
IO_readlines(IOobject *self, PyObject *args) {
	int n;
	char *output;
	PyObject *result, *line;
        int hint = 0, length = 0;
	
        if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;

	result = PyList_New(0);
	if (!result)
		return NULL;

	while (1){
		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
                        goto err;
		if (n == 0)
			break;
		line = PyString_FromStringAndSize (output, n);
		if (!line) 
                        goto err;
		if (PyList_Append (result, line) == -1) {
			Py_DECREF (line);
			goto err;
		}
		Py_DECREF (line);
                length += n;
                if (hint > 0 && length >= hint)
			break;
	}
	return result;
 err:
        Py_DECREF(result);
        return NULL;
}

PyDoc_STRVAR(IO_reset__doc__,
"reset() -- Reset the file position to the beginning");

static PyObject *
IO_reset(IOobject *self, PyObject *unused) {

        if (!IO__opencheck(self)) return NULL;

        self->pos = 0;

        Py_INCREF(Py_None);
        return Py_None;
}

PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");

static PyObject *
IO_tell(IOobject *self, PyObject *unused) {

        if (!IO__opencheck(self)) return NULL;

        return PyInt_FromSsize_t(self->pos);
}

PyDoc_STRVAR(IO_truncate__doc__,
"truncate(): truncate the file at the current position.");

static PyObject *
IO_truncate(IOobject *self, PyObject *args) {
        Py_ssize_t pos = -1;
	
        if (!IO__opencheck(self)) return NULL;
        if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;

	if (PyTuple_Size(args) == 0) {
		/* No argument passed, truncate to current position */
		pos = self->pos;
	}

        if (pos < 0) {
		errno = EINVAL;
		PyErr_SetFromErrno(PyExc_IOError);
		return NULL;
	}

        if (self->string_size > pos) self->string_size = pos;
        self->pos = self->string_size;

        Py_INCREF(Py_None);
        return Py_None;
}

static PyObject *
IO_iternext(Iobject *self)
{
	PyObject *next;
	next = IO_readline((IOobject *)self, NULL);
	if (!next)
		return NULL;
	if (!PyString_GET_SIZE(next)) {
		Py_DECREF(next);
		PyErr_SetNone(PyExc_StopIteration);
		return NULL;
	}
	return next;
}




/* Read-write object methods */

PyDoc_STRVAR(O_seek__doc__,
"seek(position)       -- set the current position\n"
"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");

static PyObject *
O_seek(Oobject *self, PyObject *args) {
	Py_ssize_t position;
	int mode = 0;

        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
                return NULL;

        if (mode == 2) {
                position += self->string_size;
        }
        else if (mode == 1) {
                position += self->pos;
        }

        if (position > self->buf_size) {
                  char *newbuf;
                  self->buf_size*=2;
                  if (self->buf_size <= position) self->buf_size=position+1;
		  newbuf = (char*) realloc(self->buf,self->buf_size);
                  if (!newbuf) {
                      free(self->buf);
                      self->buf = 0;
                      self->buf_size=self->pos=0;
                      return PyErr_NoMemory();
                    }
                  self->buf = newbuf;
          }
        else if (position < 0) position=0;

        self->pos=position;

        while (--position >= self->string_size) self->buf[position]=0;

        Py_INCREF(Py_None);
        return Py_None;
}

PyDoc_STRVAR(O_write__doc__,
"write(s) -- Write a string to the file"
"\n\nNote (hack:) writing None resets the buffer");


static int
O_cwrite(PyObject *self, const char *c, Py_ssize_t  l) {
        Py_ssize_t newl;
        Oobject *oself;
        char *newbuf;

        if (!IO__opencheck(IOOOBJECT(self))) return -1;
        oself = (Oobject *)self;

        newl = oself->pos+l;
        if (newl >= oself->buf_size) {
            oself->buf_size *= 2;
            if (oself->buf_size <= newl) {
		    assert(newl + 1 < INT_MAX);
                    oself->buf_size = (int)(newl+1);
	    }
            newbuf = (char*)realloc(oself->buf, oself->buf_size);
	    if (!newbuf) {
                    PyErr_SetString(PyExc_MemoryError,"out of memory");
                    free(oself->buf);
                    oself->buf = 0;
                    oself->buf_size = oself->pos = 0;
                    return -1;
              }
            oself->buf = newbuf;
          }

        memcpy(oself->buf+oself->pos,c,l);

	assert(oself->pos + l < INT_MAX);
        oself->pos += (int)l;

        if (oself->string_size < oself->pos) {
            oself->string_size = oself->pos;
        }

        return (int)l;
}

static PyObject *
O_write(Oobject *self, PyObject *args) {
        char *c;
        int l;

        if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;

        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;

        Py_INCREF(Py_None);
        return Py_None;
}

PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");

static PyObject *
O_close(Oobject *self, PyObject *unused) {
        if (self->buf != NULL) free(self->buf);
        self->buf = NULL;

        self->pos = self->string_size = self->buf_size = 0;

        Py_INCREF(Py_None);
        return Py_None;
}

PyDoc_STRVAR(O_writelines__doc__,
"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
"\n"
"Note that newlines are not added.  The sequence can be any iterable object\n"
"producing strings. This is equivalent to calling write() for each string.");
static PyObject *
O_writelines(Oobject *self, PyObject *args) {
	PyObject *it, *s;
	
	it = PyObject_GetIter(args);
	if (it == NULL)
		return NULL;
	while ((s = PyIter_Next(it)) != NULL) {
		Py_ssize_t n;
		char *c;
		if (PyString_AsStringAndSize(s, &c, &n) == -1) {
			Py_DECREF(it);
			Py_DECREF(s);
			return NULL;
		}
		if (O_cwrite((PyObject *)self, c, n) == -1) {
			Py_DECREF(it);
			Py_DECREF(s);
			return NULL;
               }
               Py_DECREF(s);
       }

       Py_DECREF(it);

       /* See if PyIter_Next failed */
       if (PyErr_Occurred())
               return NULL;

       Py_RETURN_NONE;
}
static struct PyMethodDef O_methods[] = {
  /* Common methods: */
  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},

  /* Read-write StringIO specific  methods: */
  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
  {NULL,	 NULL}		/* sentinel */
};

static PyMemberDef O_memberlist[] = {
	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
	 "flag indicating that a space needs to be printed; used by print"},
	 /* getattr(f, "closed") is implemented without this table */
	{NULL} /* Sentinel */
};

static void
O_dealloc(Oobject *self) {
        if (self->buf != NULL)
                free(self->buf);
        PyObject_Del(self);
}

PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");

static PyTypeObject Otype = {
  PyVarObject_HEAD_INIT(NULL, 0)
  "cStringIO.StringO",   	/*tp_name*/
  sizeof(Oobject),       	/*tp_basicsize*/
  0,	       			/*tp_itemsize*/
  /* methods */
  (destructor)O_dealloc,	/*tp_dealloc*/
  0,				/*tp_print*/
  0,		 		/*tp_getattr */
  0,		 		/*tp_setattr */
  0,				/*tp_compare*/
  0,				/*tp_repr*/
  0,				/*tp_as_number*/
  0,				/*tp_as_sequence*/
  0,				/*tp_as_mapping*/
  0,				/*tp_hash*/
  0	,			/*tp_call*/
  0,				/*tp_str*/
  0,				/*tp_getattro */
  0,				/*tp_setattro */
  0,				/*tp_as_buffer */
  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
  Otype__doc__, 		/*tp_doc */
  0,				/*tp_traverse */
  0,				/*tp_clear */
  0,				/*tp_richcompare */
  0,				/*tp_weaklistoffset */
  PyObject_SelfIter,		/*tp_iter */
  (iternextfunc)IO_iternext,	/*tp_iternext */
  O_methods,			/*tp_methods */
  O_memberlist,			/*tp_members */
  file_getsetlist,		/*tp_getset */
};

static PyObject *
newOobject(int  size) {
        Oobject *self;

        self = PyObject_New(Oobject, &Otype);
        if (self == NULL)
                return NULL;
        self->pos=0;
        self->string_size = 0;
        self->softspace = 0;

        self->buf = (char *)malloc(size);
	if (!self->buf) {
                  PyErr_SetString(PyExc_MemoryError,"out of memory");
                  self->buf_size = 0;
                  Py_DECREF(self);
                  return NULL;
          }

        self->buf_size=size;
        return (PyObject*)self;
}

/* End of code for StringO objects */
/* -------------------------------------------------------- */

static PyObject *
I_close(Iobject *self, PyObject *unused) {
        Py_CLEAR(self->pbuf);
        self->buf = NULL;

        self->pos = self->string_size = 0;

        Py_INCREF(Py_None);
        return Py_None;
}

static PyObject *
I_seek(Iobject *self, PyObject *args) {
        Py_ssize_t position;
	int mode = 0;

        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
                return NULL;

        if (mode == 2) position += self->string_size;
        else if (mode == 1) position += self->pos;

        if (position < 0) position=0;

        self->pos=position;

        Py_INCREF(Py_None);
        return Py_None;
}

static struct PyMethodDef I_methods[] = {
  /* Common methods: */
  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},

  /* Read-only StringIO specific  methods: */
  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},  
  {NULL,	NULL}
};

static void
I_dealloc(Iobject *self) {
  Py_XDECREF(self->pbuf);
  PyObject_Del(self);
}


PyDoc_STRVAR(Itype__doc__,
"Simple type for treating strings as input file streams");

static PyTypeObject Itype = {
  PyVarObject_HEAD_INIT(NULL, 0)
  "cStringIO.StringI",			/*tp_name*/
  sizeof(Iobject),			/*tp_basicsize*/
  0,					/*tp_itemsize*/
  /* methods */
  (destructor)I_dealloc,		/*tp_dealloc*/
  0,					/*tp_print*/
  0,		 			/* tp_getattr */
  0,					/*tp_setattr*/
  0,					/*tp_compare*/
  0,					/*tp_repr*/
  0,					/*tp_as_number*/
  0,					/*tp_as_sequence*/
  0,					/*tp_as_mapping*/
  0,					/*tp_hash*/
  0,					/*tp_call*/
  0,					/*tp_str*/
  0,					/* tp_getattro */
  0,					/* tp_setattro */
  0,					/* tp_as_buffer */
  Py_TPFLAGS_DEFAULT,			/* tp_flags */
  Itype__doc__,				/* tp_doc */
  0,					/* tp_traverse */
  0,					/* tp_clear */
  0,					/* tp_richcompare */
  0,					/* tp_weaklistoffset */
  PyObject_SelfIter,			/* tp_iter */
  (iternextfunc)IO_iternext,		/* tp_iternext */
  I_methods,				/* tp_methods */
  0,					/* tp_members */
  file_getsetlist,			/* tp_getset */
};

static PyObject *
newIobject(PyObject *s) {
  Iobject *self;
  char *buf;
  Py_ssize_t size;

  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
    PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
                 s->ob_type->tp_name);
    return NULL;
  }

  self = PyObject_New(Iobject, &Itype);
  if (!self) return NULL;
  Py_INCREF(s);
  self->buf=buf;
  self->string_size=size;
  self->pbuf=s;
  self->pos=0;
  
  return (PyObject*)self;
}

/* End of code for StringI objects */
/* -------------------------------------------------------- */


PyDoc_STRVAR(IO_StringIO__doc__,
"StringIO([s]) -- Return a StringIO-like stream for reading or writing");

static PyObject *
IO_StringIO(PyObject *self, PyObject *args) {
  PyObject *s=0;

  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;

  if (s) return newIobject(s);
  return newOobject(128);
}

/* List of methods defined in the module */

static struct PyMethodDef IO_methods[] = {
  {"StringIO",	(PyCFunction)IO_StringIO,	
   METH_VARARGS,	IO_StringIO__doc__},
  {NULL,		NULL}		/* sentinel */
};


/* Initialization function for the module (*must* be called initcStringIO) */

static struct PycStringIO_CAPI CAPI = {
  IO_cread,
  IO_creadline,
  O_cwrite,
  IO_cgetval,
  newOobject,
  newIobject,
  &Itype,
  &Otype,
};

#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initcStringIO(void) {
  PyObject *m, *d, *v;


  /* Create the module and add the functions */
  m = Py_InitModule4("cStringIO", IO_methods,
		     cStringIO_module_documentation,
		     (PyObject*)NULL,PYTHON_API_VERSION);
  if (m == NULL) return;

  /* Add some symbolic constants to the module */
  d = PyModule_GetDict(m);
  
  /* Export C API */
  Py_TYPE(&Itype)=&PyType_Type;
  Py_TYPE(&Otype)=&PyType_Type;
  if (PyType_Ready(&Otype) < 0) return;
  if (PyType_Ready(&Itype) < 0) return;
  PyDict_SetItemString(d,"cStringIO_CAPI",
		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
  Py_XDECREF(v);

  /* Export Types */
  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);

  /* Maybe make certain warnings go away */
  if (0) PycString_IMPORT;
}
