blob: efc3de515fe9ee58c16bee0ae3575e789346373a [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
Thomas Wouters9fdcf4a2001-01-11 15:40:39 +000020xreadlines_dealloc(PyXReadlinesObject *op)
21{
Guido van Rossumea3375d2001-01-09 21:46:50 +000022 Py_XDECREF(op->file);
23 Py_XDECREF(op->lines);
24 PyObject_DEL(op);
25}
26
27/* A larger chunk size doesn't seem to make a difference */
28#define CHUNKSIZE 8192
29
30static PyXReadlinesObject *
Thomas Wouters9fdcf4a2001-01-11 15:40:39 +000031newreadlinesobject(PyObject *file)
32{
Guido van Rossumea3375d2001-01-09 21:46:50 +000033 PyXReadlinesObject *op;
34 op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type);
35 if (op == NULL)
36 return NULL;
37 Py_XINCREF(file);
38 op->file = file;
39 op->lines = NULL;
40 op->abslineno = op->lineno = op->lineslen = 0;
41 return op;
42}
43
44static PyObject *
Thomas Wouters9fdcf4a2001-01-11 15:40:39 +000045xreadlines(PyObject *self, PyObject *args)
46{
Guido van Rossumea3375d2001-01-09 21:46:50 +000047 PyObject *file;
48 PyXReadlinesObject *ret;
49
50 if (!PyArg_ParseTuple(args, "O:xreadlines", &file))
51 return NULL;
52 ret = newreadlinesobject(file);
Guido van Rossumea3375d2001-01-09 21:46:50 +000053 return (PyObject*)ret;
54}
55
Thomas Wouters9fdcf4a2001-01-11 15:40:39 +000056static PyObject *
Guido van Rossumc8555b32001-05-22 16:41:32 +000057xreadlines_common(PyXReadlinesObject *a)
Thomas Wouters9fdcf4a2001-01-11 15:40:39 +000058{
Guido van Rossumea3375d2001-01-09 21:46:50 +000059 if (a->lineno >= a->lineslen) {
60 Py_XDECREF(a->lines);
61 a->lines = PyObject_CallMethod(a->file, "readlines", "(i)",
62 CHUNKSIZE);
63 if (a->lines == NULL)
64 return NULL;
65 a->lineno = 0;
66 if ((a->lineslen = PySequence_Size(a->lines)) < 0)
67 return NULL;
68 }
69 a->abslineno++;
70 return PySequence_GetItem(a->lines, a->lineno++);
71}
72
Guido van Rossumc8555b32001-05-22 16:41:32 +000073static PyObject *
74xreadlines_item(PyXReadlinesObject *a, int i)
75{
76 if (i != a->abslineno) {
77 PyErr_SetString(PyExc_RuntimeError,
78 "xreadlines object accessed out of order");
79 return NULL;
80 }
81 return xreadlines_common(a);
82}
83
84static PyObject *
85xreadlines_getiter(PyXReadlinesObject *a)
86{
87 Py_INCREF(a);
88 return (PyObject *)a;
89}
90
91static PyObject *
92xreadlines_iternext(PyXReadlinesObject *a)
93{
94 PyObject *res;
95
96 res = xreadlines_common(a);
97 if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError))
98 PyErr_Clear();
99 return res;
100}
101
102static PyObject *
103xreadlines_next(PyXReadlinesObject *a, PyObject *args)
104{
105 PyObject *res;
106
107 if (!PyArg_ParseTuple(args, ""))
108 return NULL;
109 res = xreadlines_common(a);
110 if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError))
111 PyErr_SetObject(PyExc_StopIteration, Py_None);
112 return res;
113}
114
115static char next_doc[] = "x.next() -> the next line or raise StopIteration";
116
117static PyMethodDef xreadlines_methods[] = {
118 {"next", (PyCFunction)xreadlines_next, METH_VARARGS, next_doc},
119 {NULL, NULL}
120};
121
122static PyObject *
123xreadlines_getattr(PyObject *a, char *name)
124{
125 return Py_FindMethod(xreadlines_methods, a, name);
126}
127
Guido van Rossumea3375d2001-01-09 21:46:50 +0000128static PySequenceMethods xreadlines_as_sequence = {
129 0, /*sq_length*/
130 0, /*sq_concat*/
131 0, /*sq_repeat*/
132 (intargfunc)xreadlines_item, /*sq_item*/
133};
134
135static PyTypeObject XReadlinesObject_Type = {
Guido van Rossum7150a772001-01-19 00:29:06 +0000136 PyObject_HEAD_INIT(NULL)
Guido van Rossumea3375d2001-01-09 21:46:50 +0000137 0,
138 "xreadlines",
Neil Schemenauer01b66a82001-08-29 23:50:42 +0000139 sizeof(PyXReadlinesObject),
Guido van Rossumea3375d2001-01-09 21:46:50 +0000140 0,
Guido van Rossumc8555b32001-05-22 16:41:32 +0000141 (destructor)xreadlines_dealloc, /* tp_dealloc */
142 0, /* tp_print */
143 xreadlines_getattr, /* tp_getattr */
144 0, /* tp_setattr */
145 0, /* tp_compare */
146 0, /* tp_repr */
147 0, /* tp_as_number */
148 &xreadlines_as_sequence, /* tp_as_sequence */
149 0, /* tp_as_mapping */
150 0, /* tp_hash */
151 0, /* tp_call */
152 0, /* tp_str */
153 0, /* tp_getattro */
154 0, /* tp_setattro */
155 0, /* tp_as_buffer */
156 Py_TPFLAGS_DEFAULT, /* tp_flags */
157 0, /* tp_doc */
158 0, /* tp_traverse */
159 0, /* tp_clear */
160 0, /* tp_richcompare */
161 0, /* tp_weaklistoffset */
162 (getiterfunc)xreadlines_getiter, /* tp_iter */
163 (iternextfunc)xreadlines_iternext, /* tp_iternext */
Guido van Rossumea3375d2001-01-09 21:46:50 +0000164};
165
Guido van Rossumc8555b32001-05-22 16:41:32 +0000166static PyMethodDef xreadlines_functions[] = {
Guido van Rossumea3375d2001-01-09 21:46:50 +0000167 {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc},
168 {NULL, NULL}
169};
170
Tim Peters58c82f02001-01-09 23:26:39 +0000171DL_EXPORT(void)
Guido van Rossumea3375d2001-01-09 21:46:50 +0000172initxreadlines(void)
173{
Guido van Rossum7150a772001-01-19 00:29:06 +0000174 XReadlinesObject_Type.ob_type = &PyType_Type;
Fred Drakedff3a372001-07-19 21:29:49 +0000175 Py_InitModule("xreadlines", xreadlines_functions);
Guido van Rossumea3375d2001-01-09 21:46:50 +0000176}