#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_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 */
	PyObject_SelfIter,			/* 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'.");
}
