| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char xreadlines_doc [] = | 
					
						
							|  |  |  | "xreadlines(f)\n\
 | 
					
						
							|  |  |  | \n\ | 
					
						
							|  |  |  | Return an xreadlines object for the file f."; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	PyObject_HEAD | 
					
						
							|  |  |  | 	PyObject *file; | 
					
						
							|  |  |  | 	PyObject *lines; | 
					
						
							|  |  |  | 	int lineslen; | 
					
						
							|  |  |  | 	int lineno; | 
					
						
							|  |  |  | 	int abslineno; | 
					
						
							|  |  |  | } PyXReadlinesObject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | staticforward PyTypeObject XReadlinesObject_Type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2001-01-11 15:40:39 +00:00
										 |  |  | xreadlines_dealloc(PyXReadlinesObject *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | 	Py_XDECREF(op->file); | 
					
						
							|  |  |  | 	Py_XDECREF(op->lines); | 
					
						
							|  |  |  | 	PyObject_DEL(op); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A larger chunk size doesn't seem to make a difference */ | 
					
						
							|  |  |  | #define CHUNKSIZE  8192
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyXReadlinesObject * | 
					
						
							| 
									
										
										
										
											2001-01-11 15:40:39 +00:00
										 |  |  | newreadlinesobject(PyObject *file) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | 	PyXReadlinesObject *op; | 
					
						
							|  |  |  | 	op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type); | 
					
						
							|  |  |  | 	if (op == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	Py_XINCREF(file); | 
					
						
							|  |  |  | 	op->file = file; | 
					
						
							|  |  |  | 	op->lines = NULL; | 
					
						
							|  |  |  | 	op->abslineno = op->lineno = op->lineslen = 0; | 
					
						
							|  |  |  | 	return op; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2001-01-11 15:40:39 +00:00
										 |  |  | xreadlines(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | 	PyObject *file; | 
					
						
							|  |  |  | 	PyXReadlinesObject *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "O:xreadlines", &file)) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	ret = newreadlinesobject(file); | 
					
						
							|  |  |  | 	return (PyObject*)ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-01-11 15:40:39 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2001-05-22 16:41:32 +00:00
										 |  |  | xreadlines_common(PyXReadlinesObject *a) | 
					
						
							| 
									
										
										
										
											2001-01-11 15:40:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | 	if (a->lineno >= a->lineslen) { | 
					
						
							|  |  |  | 		Py_XDECREF(a->lines); | 
					
						
							|  |  |  | 		a->lines = PyObject_CallMethod(a->file, "readlines", "(i)", | 
					
						
							|  |  |  | 					       CHUNKSIZE); | 
					
						
							|  |  |  | 		if (a->lines == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		a->lineno = 0; | 
					
						
							|  |  |  | 		if ((a->lineslen = PySequence_Size(a->lines)) < 0) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	a->abslineno++; | 
					
						
							|  |  |  | 	return PySequence_GetItem(a->lines, a->lineno++); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-22 16:41:32 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | xreadlines_item(PyXReadlinesObject *a, int i) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (i != a->abslineno) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  | 			"xreadlines object accessed out of order"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return xreadlines_common(a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | xreadlines_getiter(PyXReadlinesObject *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_INCREF(a); | 
					
						
							|  |  |  | 	return (PyObject *)a; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | xreadlines_iternext(PyXReadlinesObject *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res = xreadlines_common(a); | 
					
						
							|  |  |  | 	if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError)) | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | xreadlines_next(PyXReadlinesObject *a, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_ParseTuple(args, "")) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	res = xreadlines_common(a); | 
					
						
							|  |  |  | 	if (res == NULL && PyErr_ExceptionMatches(PyExc_IndexError)) | 
					
						
							|  |  |  | 		PyErr_SetObject(PyExc_StopIteration, Py_None); | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char next_doc[] = "x.next() -> the next line or raise StopIteration"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef xreadlines_methods[] = { | 
					
						
							|  |  |  | 	{"next", (PyCFunction)xreadlines_next, METH_VARARGS, next_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | xreadlines_getattr(PyObject *a, char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return Py_FindMethod(xreadlines_methods, a, name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | static PySequenceMethods xreadlines_as_sequence = { | 
					
						
							|  |  |  | 	0, /*sq_length*/ | 
					
						
							|  |  |  | 	0, /*sq_concat*/ | 
					
						
							|  |  |  | 	0, /*sq_repeat*/ | 
					
						
							|  |  |  | 	(intargfunc)xreadlines_item, /*sq_item*/ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject XReadlinesObject_Type = { | 
					
						
							| 
									
										
										
										
											2001-01-19 00:29:06 +00:00
										 |  |  | 	PyObject_HEAD_INIT(NULL) | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | 	0, | 
					
						
							|  |  |  | 	"xreadlines", | 
					
						
							|  |  |  | 	sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE, | 
					
						
							|  |  |  | 	0, | 
					
						
							| 
									
										
										
										
											2001-05-22 16:41:32 +00:00
										 |  |  | 	(destructor)xreadlines_dealloc,		/* tp_dealloc */ | 
					
						
							|  |  |  | 	0,					/* tp_print */ | 
					
						
							|  |  |  | 	xreadlines_getattr,			/* tp_getattr */ | 
					
						
							|  |  |  | 	0,					/* tp_setattr */ | 
					
						
							|  |  |  | 	0,					/* tp_compare */ | 
					
						
							|  |  |  | 	0,					/* tp_repr */ | 
					
						
							|  |  |  | 	0,					/* tp_as_number */ | 
					
						
							|  |  |  | 	&xreadlines_as_sequence,		/* tp_as_sequence */ | 
					
						
							|  |  |  | 	0,					/* tp_as_mapping */ | 
					
						
							|  |  |  | 	0,					/* tp_hash */ | 
					
						
							|  |  |  | 	0,					/* tp_call */ | 
					
						
							|  |  |  | 	0,					/* tp_str */ | 
					
						
							|  |  |  | 	0,					/* tp_getattro */ | 
					
						
							|  |  |  | 	0,					/* tp_setattro */ | 
					
						
							|  |  |  | 	0,					/* tp_as_buffer */ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,			/* tp_flags */ | 
					
						
							|  |  |  | 	0,					/* tp_doc */ | 
					
						
							|  |  |  |  	0,					/* tp_traverse */ | 
					
						
							|  |  |  |  	0,					/* tp_clear */ | 
					
						
							|  |  |  | 	0,					/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,					/* tp_weaklistoffset */ | 
					
						
							|  |  |  | 	(getiterfunc)xreadlines_getiter,	/* tp_iter */ | 
					
						
							|  |  |  | 	(iternextfunc)xreadlines_iternext,	/* tp_iternext */ | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-22 16:41:32 +00:00
										 |  |  | static PyMethodDef xreadlines_functions[] = { | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | 	{"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc}, | 
					
						
							|  |  |  | 	{NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-01-09 23:26:39 +00:00
										 |  |  | DL_EXPORT(void) | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | initxreadlines(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-01-19 00:29:06 +00:00
										 |  |  | 	XReadlinesObject_Type.ob_type = &PyType_Type; | 
					
						
							| 
									
										
										
										
											2001-07-19 21:29:49 +00:00
										 |  |  | 	Py_InitModule("xreadlines", xreadlines_functions); | 
					
						
							| 
									
										
										
										
											2001-01-09 21:46:50 +00:00
										 |  |  | } |