view Modules/xreadlinesmodule.c @ 16798:258dcafe2d0b legacy-trunk

Gustavo Niemeyer <niemeyer@conectiva.com>: Fixed recno support (keys are integers rather than strings). Work around DB bug that cause stdin to be closed by rnopen() when the DB file needed to exist but did not (no longer segfaults). This closes SF tracker patch #403445. Also wrapped some long lines and added whitespace around operators -- FLD.
author Fred Drake <fdrake@acm.org>
date Tue, 27 Feb 2001 18:56:46 +0000
parents 4c856a180458
children f1a49eec7c2b
line wrap: on
line source

#include "Python.h"

static char 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;

staticforward 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);
	Py_XINCREF(ret);
	return (PyObject*)ret;
}

static PyObject *
xreadlines_item(PyXReadlinesObject *a, int i)
{
	if (i != a->abslineno) {
		PyErr_SetString(PyExc_RuntimeError,
			"xreadlines object accessed out of order");
		return NULL;
	}
	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 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",
	sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE,
	0,
	(destructor)xreadlines_dealloc, /*tp_dealloc*/
	0, /*tp_print*/
	0, /*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 */
};

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

DL_EXPORT(void)
initxreadlines(void)
{
	PyObject *m;

	XReadlinesObject_Type.ob_type = &PyType_Type;
	m = Py_InitModule("xreadlines", xreadlines_methods);
}