#include "Python.h"

PyDoc_STRVAR(xreadlines_doc,
"xreadlines(f)\n\
\n\
Return an xreadlines object for the file f.");

typedef struct {
	PyObject_HEAD
	PyObject *file;
	PyObject *lines;
	int lineslen;
	int lineno;
	int abslineno;
} PyXReadlinesObject;

static PyTypeObject XReadlinesObject_Type;

static void
xreadlines_dealloc(PyXReadlinesObject *op)
{
	Py_XDECREF(op->file);
	Py_XDECREF(op->lines);
	PyObject_DEL(op);
}

/* A larger chunk size doesn't seem to make a difference */
#define CHUNKSIZE  8192

static PyXReadlinesObject *
newreadlinesobject(PyObject *file)
{
	PyXReadlinesObject *op;
	op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type);
	if (op == NULL)
		return NULL;
	Py_XINCREF(file);
	op->file = file;
	op->lines = NULL;
	op->abslineno = op->lineno = op->lineslen = 0;
	return op;
}

static PyObject *
xreadlines(PyObject *self, PyObject *args)
{
	PyObject *file;
	PyXReadlinesObject *ret;

	if (!PyArg_ParseTuple(args, "O:xreadlines", &file))
		return NULL;
	ret = newreadlinesobject(file);
	return (PyObject*)ret;
}

static PyObject *
xreadlines_common(PyXReadlinesObject *a)
{
	if (a->lineno >= a->lineslen) {
		Py_XDECREF(a->lines);
		a->lines = PyObject_CallMethod(a->file, "readlines", "(i)",
					       CHUNKSIZE);
		if (a->lines == NULL)
			return NULL;
		a->lineno = 0;
		if ((a->lineslen = PySequence_Size(a->lines)) < 0)
			return NULL;
	}
	a->abslineno++;
	return PySequence_GetItem(a->lines, a->lineno++);
}

static PyObject *
xreadlines_item(PyXReadlinesObject *a, int i)
{
	if (i != a->abslineno) {
		PyErr_SetString(PyExc_RuntimeError,
			"xreadlines object accessed out of order");
		return NULL;
	}
	return xreadlines_common(a);
}

static PyObject *
xreadlines_getiter(PyXReadlinesObject *a)
{
	Py_INCREF(a);
	return (PyObject *)a;
}

static PyObject *
xreadlines_iternext(PyXReadlinesObject *a)
{
	PyObject *res;

	res = xreadlines_common(a);
	if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError))
		PyErr_Clear();
	return res;
}

static PyObject *
xreadlines_next(PyXReadlinesObject *a, PyObject *args)
{
	PyObject *res;

	if (!PyArg_ParseTuple(args, ""))
		return NULL;
	res = xreadlines_common(a);
	if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError))
		PyErr_SetObject(PyExc_StopIteration, Py_None);
	return res;
}

PyDoc_STRVAR(next_doc, "x.next() -> the next line or raise StopIteration");

static PyMethodDef xreadlines_methods[] = {
	{"next", (PyCFunction)xreadlines_next, METH_VARARGS, next_doc},
	{NULL, NULL}
};

static PyObject *
xreadlines_getattr(PyObject *a, char *name)
{
	return Py_FindMethod(xreadlines_methods, a, name);
}

static PySequenceMethods xreadlines_as_sequence = {
	0, /*sq_length*/
	0, /*sq_concat*/
	0, /*sq_repeat*/
	(intargfunc)xreadlines_item, /*sq_item*/
};

static PyTypeObject XReadlinesObject_Type = {
	PyObject_HEAD_INIT(NULL)
	0,
	"xreadlines.xreadlines",
	sizeof(PyXReadlinesObject),
	0,
	(destructor)xreadlines_dealloc,		/* tp_dealloc */
	0,					/* tp_print */
	xreadlines_getattr,			/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	&xreadlines_as_sequence,		/* 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 */
	0,					/* tp_doc */
 	0,					/* tp_traverse */
 	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	(getiterfunc)xreadlines_getiter,	/* tp_iter */
	(iternextfunc)xreadlines_iternext,	/* tp_iternext */
};

static PyMethodDef xreadlines_functions[] = {
	{"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc},
	{NULL, NULL}
};

PyMODINIT_FUNC
initxreadlines(void)
{
	XReadlinesObject_Type.ob_type = &PyType_Type;
	Py_InitModule("xreadlines", xreadlines_functions);
	PyErr_Warn(PyExc_DeprecationWarning,
		   "xreadlines is deprecated; use 'for line in file'.");
}
