From ea3375d96b35c2f2b1669da4d3e14ff7c4a189bb Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 9 Jan 2001 21:46:50 +0000 Subject: Jeff Epler's xreadlines module, with slight reformatting and some changes for safety and tuning. --- Modules/Setup.dist | 3 ++ Modules/xreadlinesmodule.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 Modules/xreadlinesmodule.c diff --git a/Modules/Setup.dist b/Modules/Setup.dist index e46eca4..53ab1fb 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -156,6 +156,9 @@ _socket socketmodule.c # socket(2) # Memory-mapped files (also works on Win32). mmap mmapmodule.c +# Dynamic readlines +xreadlines xreadlinesmodule.c + # Socket module compiled with SSL support; you must edit the SSL variable: #SSL=/usr/local/ssl #_socket socketmodule.c \ 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); +} -- cgit v0.12