summaryrefslogtreecommitdiffstats
path: root/Modules/xreadlinesmodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-01-09 21:46:50 (GMT)
committerGuido van Rossum <guido@python.org>2001-01-09 21:46:50 (GMT)
commitea3375d96b35c2f2b1669da4d3e14ff7c4a189bb (patch)
tree03e047dfeb8f3bc910c6d4e30c34e79c5ee58194 /Modules/xreadlinesmodule.c
parentc49480ed51fe92a9bc1f0c175eec27cb0f6d9d5e (diff)
downloadcpython-ea3375d96b35c2f2b1669da4d3e14ff7c4a189bb.zip
cpython-ea3375d96b35c2f2b1669da4d3e14ff7c4a189bb.tar.gz
cpython-ea3375d96b35c2f2b1669da4d3e14ff7c4a189bb.tar.bz2
Jeff Epler's xreadlines module, with slight reformatting and some
changes for safety and tuning.
Diffstat (limited to 'Modules/xreadlinesmodule.c')
-rw-r--r--Modules/xreadlinesmodule.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/Modules/xreadlinesmodule.c b/Modules/xreadlinesmodule.c
new file mode 100644
index 0000000..c50dd06
--- /dev/null
+++ b/Modules/xreadlinesmodule.c
@@ -0,0 +1,118 @@
+#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(&PyType_Type)
+ 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}
+};
+
+void
+initxreadlines(void)
+{
+ PyObject *m;
+
+ m = Py_InitModule("xreadlines", xreadlines_methods);
+}