blob: db9e243a3ec84f177afea6d23dc2b73938d50ac8 [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 *
57xreadlines_item(PyXReadlinesObject *a, int i)
58{
Guido van Rossumea3375d2001-01-09 21:46:50 +000059 if (i != a->abslineno) {
60 PyErr_SetString(PyExc_RuntimeError,
61 "xreadlines object accessed out of order");
62 return NULL;
63 }
64 if (a->lineno >= a->lineslen) {
65 Py_XDECREF(a->lines);
66 a->lines = PyObject_CallMethod(a->file, "readlines", "(i)",
67 CHUNKSIZE);
68 if (a->lines == NULL)
69 return NULL;
70 a->lineno = 0;
71 if ((a->lineslen = PySequence_Size(a->lines)) < 0)
72 return NULL;
73 }
74 a->abslineno++;
75 return PySequence_GetItem(a->lines, a->lineno++);
76}
77
78static PySequenceMethods xreadlines_as_sequence = {
79 0, /*sq_length*/
80 0, /*sq_concat*/
81 0, /*sq_repeat*/
82 (intargfunc)xreadlines_item, /*sq_item*/
83};
84
85static PyTypeObject XReadlinesObject_Type = {
Guido van Rossum7150a772001-01-19 00:29:06 +000086 PyObject_HEAD_INIT(NULL)
Guido van Rossumea3375d2001-01-09 21:46:50 +000087 0,
88 "xreadlines",
89 sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE,
90 0,
91 (destructor)xreadlines_dealloc, /*tp_dealloc*/
92 0, /*tp_print*/
93 0, /*tp_getattr*/
94 0, /*tp_setattr*/
95 0, /*tp_compare*/
96 0, /*tp_repr*/
97 0, /*tp_as_number*/
98 &xreadlines_as_sequence, /*tp_as_sequence*/
99 0, /*tp_as_mapping*/
100 0, /*tp_hash*/
101 0, /*tp_call*/
102 0, /*tp_str*/
103 0, /*tp_getattro*/
104 0, /*tp_setattro*/
105 0, /*tp_as_buffer*/
106 Py_TPFLAGS_DEFAULT, /*tp_flags*/
107 0, /* tp_doc */
108};
109
110static PyMethodDef xreadlines_methods[] = {
111 {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc},
112 {NULL, NULL}
113};
114
Tim Peters58c82f02001-01-09 23:26:39 +0000115DL_EXPORT(void)
Guido van Rossumea3375d2001-01-09 21:46:50 +0000116initxreadlines(void)
117{
118 PyObject *m;
119
Guido van Rossum7150a772001-01-19 00:29:06 +0000120 XReadlinesObject_Type.ob_type = &PyType_Type;
Guido van Rossumea3375d2001-01-09 21:46:50 +0000121 m = Py_InitModule("xreadlines", xreadlines_methods);
122}