blob: dc74f5dc435d3fd89dd5a3a4ec2c413a82deb040 [file] [log] [blame]
Guido van Rossumea3375d2001-01-09 21:46:50 +00001#include "Python.h"
2
3static char xreadlines_doc [] =
4"xreadlines(f)\n\
5\n\
6Return an xreadlines object for the file f.";
7
8typedef struct {
9 PyObject_HEAD
10 PyObject *file;
11 PyObject *lines;
12 int lineslen;
13 int lineno;
14 int abslineno;
15} PyXReadlinesObject;
16
17staticforward PyTypeObject XReadlinesObject_Type;
18
19static void
20xreadlines_dealloc(PyXReadlinesObject *op) {
21 Py_XDECREF(op->file);
22 Py_XDECREF(op->lines);
23 PyObject_DEL(op);
24}
25
26/* A larger chunk size doesn't seem to make a difference */
27#define CHUNKSIZE 8192
28
29static PyXReadlinesObject *
30newreadlinesobject(PyObject *file) {
31 PyXReadlinesObject *op;
32 op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type);
33 if (op == NULL)
34 return NULL;
35 Py_XINCREF(file);
36 op->file = file;
37 op->lines = NULL;
38 op->abslineno = op->lineno = op->lineslen = 0;
39 return op;
40}
41
42static PyObject *
43xreadlines(PyObject *self, PyObject *args) {
44 PyObject *file;
45 PyXReadlinesObject *ret;
46
47 if (!PyArg_ParseTuple(args, "O:xreadlines", &file))
48 return NULL;
49 ret = newreadlinesobject(file);
50 Py_XINCREF(ret);
51 return (PyObject*)ret;
52}
53
54static PyObject*
55xreadlines_item(PyXReadlinesObject *a, int i) {
56 if (i != a->abslineno) {
57 PyErr_SetString(PyExc_RuntimeError,
58 "xreadlines object accessed out of order");
59 return NULL;
60 }
61 if (a->lineno >= a->lineslen) {
62 Py_XDECREF(a->lines);
63 a->lines = PyObject_CallMethod(a->file, "readlines", "(i)",
64 CHUNKSIZE);
65 if (a->lines == NULL)
66 return NULL;
67 a->lineno = 0;
68 if ((a->lineslen = PySequence_Size(a->lines)) < 0)
69 return NULL;
70 }
71 a->abslineno++;
72 return PySequence_GetItem(a->lines, a->lineno++);
73}
74
75static PySequenceMethods xreadlines_as_sequence = {
76 0, /*sq_length*/
77 0, /*sq_concat*/
78 0, /*sq_repeat*/
79 (intargfunc)xreadlines_item, /*sq_item*/
80};
81
82static PyTypeObject XReadlinesObject_Type = {
83 PyObject_HEAD_INIT(&PyType_Type)
84 0,
85 "xreadlines",
86 sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE,
87 0,
88 (destructor)xreadlines_dealloc, /*tp_dealloc*/
89 0, /*tp_print*/
90 0, /*tp_getattr*/
91 0, /*tp_setattr*/
92 0, /*tp_compare*/
93 0, /*tp_repr*/
94 0, /*tp_as_number*/
95 &xreadlines_as_sequence, /*tp_as_sequence*/
96 0, /*tp_as_mapping*/
97 0, /*tp_hash*/
98 0, /*tp_call*/
99 0, /*tp_str*/
100 0, /*tp_getattro*/
101 0, /*tp_setattro*/
102 0, /*tp_as_buffer*/
103 Py_TPFLAGS_DEFAULT, /*tp_flags*/
104 0, /* tp_doc */
105};
106
107static PyMethodDef xreadlines_methods[] = {
108 {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc},
109 {NULL, NULL}
110};
111
Tim Peters58c82f02001-01-09 23:26:39 +0000112DL_EXPORT(void)
Guido van Rossumea3375d2001-01-09 21:46:50 +0000113initxreadlines(void)
114{
115 PyObject *m;
116
117 m = Py_InitModule("xreadlines", xreadlines_methods);
118}