Move setting of ioready 'wait' earlier in call chain, to
[python/dscho.git] / Modules / xreadlinesmodule.c
blobbf3c091df05e74f6948a442533d9baffc790ffb9
1 #include "Python.h"
3 PyDoc_STRVAR(xreadlines_doc,
4 "xreadlines(f)\n\
5 \n\
6 Return an xreadlines object for the file f.");
8 typedef struct {
9 PyObject_HEAD
10 PyObject *file;
11 PyObject *lines;
12 int lineslen;
13 int lineno;
14 int abslineno;
15 } PyXReadlinesObject;
17 static PyTypeObject XReadlinesObject_Type;
19 static void
20 xreadlines_dealloc(PyXReadlinesObject *op)
22 Py_XDECREF(op->file);
23 Py_XDECREF(op->lines);
24 PyObject_DEL(op);
27 /* A larger chunk size doesn't seem to make a difference */
28 #define CHUNKSIZE 8192
30 static PyXReadlinesObject *
31 newreadlinesobject(PyObject *file)
33 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;
44 static PyObject *
45 xreadlines(PyObject *self, PyObject *args)
47 PyObject *file;
48 PyXReadlinesObject *ret;
50 if (!PyArg_ParseTuple(args, "O:xreadlines", &file))
51 return NULL;
52 ret = newreadlinesobject(file);
53 return (PyObject*)ret;
56 static PyObject *
57 xreadlines_common(PyXReadlinesObject *a)
59 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;
69 a->abslineno++;
70 return PySequence_GetItem(a->lines, a->lineno++);
73 static PyObject *
74 xreadlines_item(PyXReadlinesObject *a, int i)
76 if (i != a->abslineno) {
77 PyErr_SetString(PyExc_RuntimeError,
78 "xreadlines object accessed out of order");
79 return NULL;
81 return xreadlines_common(a);
84 static PyObject *
85 xreadlines_getiter(PyXReadlinesObject *a)
87 Py_INCREF(a);
88 return (PyObject *)a;
91 static PyObject *
92 xreadlines_iternext(PyXReadlinesObject *a)
94 PyObject *res;
96 res = xreadlines_common(a);
97 if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError))
98 PyErr_Clear();
99 return res;
102 static PyObject *
103 xreadlines_next(PyXReadlinesObject *a, PyObject *args)
105 PyObject *res;
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;
115 PyDoc_STRVAR(next_doc, "x.next() -> the next line or raise StopIteration");
117 static PyMethodDef xreadlines_methods[] = {
118 {"next", (PyCFunction)xreadlines_next, METH_VARARGS, next_doc},
119 {NULL, NULL}
122 static PyObject *
123 xreadlines_getattr(PyObject *a, char *name)
125 return Py_FindMethod(xreadlines_methods, a, name);
128 static PySequenceMethods xreadlines_as_sequence = {
129 0, /*sq_length*/
130 0, /*sq_concat*/
131 0, /*sq_repeat*/
132 (intargfunc)xreadlines_item, /*sq_item*/
135 static PyTypeObject XReadlinesObject_Type = {
136 PyObject_HEAD_INIT(NULL)
138 "xreadlines.xreadlines",
139 sizeof(PyXReadlinesObject),
141 (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 */
166 static PyMethodDef xreadlines_functions[] = {
167 {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc},
168 {NULL, NULL}
171 PyMODINIT_FUNC
172 initxreadlines(void)
174 XReadlinesObject_Type.ob_type = &PyType_Type;
175 Py_InitModule("xreadlines", xreadlines_functions);
176 PyErr_Warn(PyExc_DeprecationWarning,
177 "xreadlines is deprecated; use 'for line in file'.");