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