Move setting of ioready 'wait' earlier in call chain, to
[python/dscho.git] / Modules / cStringIO.c
blob4cabc5bb7cfc68dffda9f51c6428d6078400c659
2 #include "Python.h"
3 #include "import.h"
4 #include "cStringIO.h"
6 PyDoc_STRVAR(cStringIO_module_documentation,
7 "A simple fast partial StringIO replacement.\n"
8 "\n"
9 "This module provides a simple useful replacement for\n"
10 "the StringIO module that is written in C. It does not provide the\n"
11 "full generality of StringIO, but it provides enough for most\n"
12 "applications and is especially useful in conjunction with the\n"
13 "pickle module.\n"
14 "\n"
15 "Usage:\n"
16 "\n"
17 " from cStringIO import StringIO\n"
18 "\n"
19 " an_output_stream=StringIO()\n"
20 " an_output_stream.write(some_stuff)\n"
21 " ...\n"
22 " value=an_output_stream.getvalue()\n"
23 "\n"
24 " an_input_stream=StringIO(a_string)\n"
25 " spam=an_input_stream.readline()\n"
26 " spam=an_input_stream.read(5)\n"
27 " an_input_stream.seek(0) # OK, start over\n"
28 " spam=an_input_stream.read() # and read it all\n"
29 " \n"
30 "If someone else wants to provide a more complete implementation,\n"
31 "go for it. :-) \n"
32 "\n"
33 "cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
35 #define UNLESS(E) if (!(E))
38 /* Declaration for file-like objects that manage data as strings
40 The IOobject type should be though of as a common base type for
41 Iobjects, which provide input (read-only) StringIO objects and
42 Oobjects, which provide read-write objects. Most of the methods
43 depend only on common data.
46 typedef struct {
47 PyObject_HEAD
48 char *buf;
49 int pos, string_size;
50 } IOobject;
52 #define IOOOBJECT(O) ((IOobject*)(O))
54 /* Declarations for objects of type StringO */
56 typedef struct { /* Subtype of IOobject */
57 PyObject_HEAD
58 char *buf;
59 int pos, string_size;
61 int buf_size, softspace;
62 } Oobject;
64 /* Declarations for objects of type StringI */
66 typedef struct { /* Subtype of IOobject */
67 PyObject_HEAD
68 char *buf;
69 int pos, string_size;
70 /* We store a reference to the object here in order to keep
71 the buffer alive during the lifetime of the Iobject. */
72 PyObject *pbuf;
73 } Iobject;
75 /* IOobject (common) methods */
77 PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
79 static int
80 IO__opencheck(IOobject *self) {
81 UNLESS (self->buf) {
82 PyErr_SetString(PyExc_ValueError,
83 "I/O operation on closed file");
84 return 0;
86 return 1;
89 static PyObject *
90 IO_flush(IOobject *self, PyObject *unused) {
92 UNLESS (IO__opencheck(self)) return NULL;
94 Py_INCREF(Py_None);
95 return Py_None;
98 PyDoc_STRVAR(IO_getval__doc__,
99 "getvalue([use_pos]) -- Get the string value."
100 "\n"
101 "If use_pos is specified and is a true value, then the string returned\n"
102 "will include only the text up to the current file position.\n");
104 static PyObject *
105 IO_cgetval(PyObject *self) {
106 UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
107 return PyString_FromStringAndSize(((IOobject*)self)->buf,
108 ((IOobject*)self)->pos);
111 static PyObject *
112 IO_getval(IOobject *self, PyObject *args) {
113 PyObject *use_pos=Py_None;
114 int s;
116 UNLESS (IO__opencheck(self)) return NULL;
117 UNLESS (PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
119 if (PyObject_IsTrue(use_pos)) {
120 s=self->pos;
121 if (s > self->string_size) s=self->string_size;
123 else
124 s=self->string_size;
125 return PyString_FromStringAndSize(self->buf, s);
128 PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
130 static PyObject *
131 IO_isatty(IOobject *self, PyObject *unused) {
132 Py_INCREF(Py_False);
133 return Py_False;
136 PyDoc_STRVAR(IO_read__doc__,
137 "read([s]) -- Read s characters, or the rest of the string");
139 static int
140 IO_cread(PyObject *self, char **output, int n) {
141 int l;
143 UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
144 l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
145 if (n < 0 || n > l) {
146 n = l;
147 if (n < 0) n=0;
150 *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
151 ((IOobject*)self)->pos += n;
152 return n;
155 static PyObject *
156 IO_read(IOobject *self, PyObject *args) {
157 int n = -1;
158 char *output;
160 UNLESS (PyArg_ParseTuple(args, "|i:read", &n)) return NULL;
162 if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
164 return PyString_FromStringAndSize(output, n);
167 PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
169 static int
170 IO_creadline(PyObject *self, char **output) {
171 char *n, *s;
172 int l;
174 UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
176 for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
177 s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
178 n < s && *n != '\n'; n++);
179 if (n < s) n++;
181 *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
182 l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
183 ((IOobject*)self)->pos += l;
184 return l;
187 static PyObject *
188 IO_readline(IOobject *self, PyObject *args) {
189 int n, m=-1;
190 char *output;
192 UNLESS (PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
194 if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
195 if (m >= 0 && m < n) {
196 m = n - m;
197 n -= m;
198 self->pos -= m;
200 return PyString_FromStringAndSize(output, n);
203 PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
205 static PyObject *
206 IO_readlines(IOobject *self, PyObject *args) {
207 int n;
208 char *output;
209 PyObject *result, *line;
210 int hint = 0, length = 0;
212 UNLESS (PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
214 result = PyList_New(0);
215 if (!result)
216 return NULL;
218 while (1){
219 if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
220 goto err;
221 if (n == 0)
222 break;
223 line = PyString_FromStringAndSize (output, n);
224 if (!line)
225 goto err;
226 PyList_Append (result, line);
227 Py_DECREF (line);
228 length += n;
229 if (hint > 0 && length >= hint)
230 break;
232 return result;
233 err:
234 Py_DECREF(result);
235 return NULL;
238 PyDoc_STRVAR(IO_reset__doc__,
239 "reset() -- Reset the file position to the beginning");
241 static PyObject *
242 IO_reset(IOobject *self, PyObject *unused) {
244 UNLESS (IO__opencheck(self)) return NULL;
246 self->pos = 0;
248 Py_INCREF(Py_None);
249 return Py_None;
252 PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
254 static PyObject *
255 IO_tell(IOobject *self, PyObject *unused) {
257 UNLESS (IO__opencheck(self)) return NULL;
259 return PyInt_FromLong(self->pos);
262 PyDoc_STRVAR(IO_truncate__doc__,
263 "truncate(): truncate the file at the current position.");
265 static PyObject *
266 IO_truncate(IOobject *self, PyObject *args) {
267 int pos = -1;
269 UNLESS (IO__opencheck(self)) return NULL;
270 UNLESS (PyArg_ParseTuple(args, "|i:truncate", &pos)) return NULL;
271 if (pos < 0) pos = self->pos;
273 if (self->string_size > pos) self->string_size = pos;
275 Py_INCREF(Py_None);
276 return Py_None;
282 /* Read-write object methods */
284 PyDoc_STRVAR(O_seek__doc__,
285 "seek(position) -- set the current position\n"
286 "seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
288 static PyObject *
289 O_seek(Oobject *self, PyObject *args) {
290 int position, mode = 0;
292 UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
293 UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
294 return NULL;
296 if (mode == 2) {
297 position += self->string_size;
299 else if (mode == 1) {
300 position += self->pos;
303 if (position > self->buf_size) {
304 self->buf_size*=2;
305 if (self->buf_size <= position) self->buf_size=position+1;
306 UNLESS (self->buf=(char*)
307 realloc(self->buf,self->buf_size*sizeof(char))) {
308 self->buf_size=self->pos=0;
309 return PyErr_NoMemory();
312 else if (position < 0) position=0;
314 self->pos=position;
316 while (--position >= self->string_size) self->buf[position]=0;
318 Py_INCREF(Py_None);
319 return Py_None;
322 PyDoc_STRVAR(O_write__doc__,
323 "write(s) -- Write a string to the file"
324 "\n\nNote (hack:) writing None resets the buffer");
327 static int
328 O_cwrite(PyObject *self, char *c, int l) {
329 int newl;
330 Oobject *oself;
332 UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
333 oself = (Oobject *)self;
335 newl = oself->pos+l;
336 if (newl >= oself->buf_size) {
337 oself->buf_size *= 2;
338 if (oself->buf_size <= newl)
339 oself->buf_size = newl+1;
340 UNLESS (oself->buf =
341 (char*)realloc(oself->buf,
342 (oself->buf_size) * sizeof(char))) {
343 PyErr_SetString(PyExc_MemoryError,"out of memory");
344 oself->buf_size = oself->pos = 0;
345 return -1;
349 memcpy(oself->buf+oself->pos,c,l);
351 oself->pos += l;
353 if (oself->string_size < oself->pos) {
354 oself->string_size = oself->pos;
357 return l;
360 static PyObject *
361 O_write(Oobject *self, PyObject *args) {
362 char *c;
363 int l;
365 UNLESS (PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
367 if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
369 Py_INCREF(Py_None);
370 return Py_None;
373 PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
375 static PyObject *
376 O_close(Oobject *self, PyObject *unused) {
377 if (self->buf != NULL) free(self->buf);
378 self->buf = NULL;
380 self->pos = self->string_size = self->buf_size = 0;
382 Py_INCREF(Py_None);
383 return Py_None;
387 PyDoc_STRVAR(O_writelines__doc__,
388 "writelines(sequence_of_strings): write each string");
389 static PyObject *
390 O_writelines(Oobject *self, PyObject *args) {
391 PyObject *tmp = 0;
392 static PyObject *joiner = NULL;
394 if (!joiner) {
395 PyObject *empty_string = PyString_FromString("");
396 if (empty_string == NULL)
397 return NULL;
398 joiner = PyObject_GetAttrString(empty_string, "join");
399 Py_DECREF(empty_string);
400 if (joiner == NULL)
401 return NULL;
404 if (PyObject_Size(args) < 0) return NULL;
406 tmp = PyObject_CallFunction(joiner, "O", args);
407 UNLESS (tmp) return NULL;
409 args = Py_BuildValue("(O)", tmp);
410 Py_DECREF(tmp);
411 UNLESS (args) return NULL;
413 tmp = O_write(self, args);
414 Py_DECREF(args);
415 return tmp;
418 static struct PyMethodDef O_methods[] = {
419 /* Common methods: */
420 {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
421 {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
422 {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
423 {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
424 {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
425 {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
426 {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
427 {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
428 {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
430 /* Read-write StringIO specific methods: */
431 {"close", (PyCFunction)O_close, METH_NOARGS, O_close__doc__},
432 {"seek", (PyCFunction)O_seek, METH_VARARGS, O_seek__doc__},
433 {"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__},
434 {"writelines", (PyCFunction)O_writelines, METH_O, O_writelines__doc__},
435 {NULL, NULL} /* sentinel */
438 static void
439 O_dealloc(Oobject *self) {
440 if (self->buf != NULL)
441 free(self->buf);
442 PyObject_Del(self);
445 static PyObject *
446 O_getattr(Oobject *self, char *name) {
447 if (strcmp(name, "softspace") == 0) {
448 return PyInt_FromLong(self->softspace);
450 return Py_FindMethod(O_methods, (PyObject *)self, name);
453 static int
454 O_setattr(Oobject *self, char *name, PyObject *value) {
455 long x;
456 if (strcmp(name, "softspace") != 0) {
457 PyErr_SetString(PyExc_AttributeError, name);
458 return -1;
460 x = PyInt_AsLong(value);
461 if (x < 0 && PyErr_Occurred())
462 return -1;
463 self->softspace = x;
464 return 0;
467 PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
469 static PyTypeObject Otype = {
470 PyObject_HEAD_INIT(NULL)
471 0, /*ob_size*/
472 "cStringIO.StringO", /*tp_name*/
473 sizeof(Oobject), /*tp_basicsize*/
474 0, /*tp_itemsize*/
475 /* methods */
476 (destructor)O_dealloc, /*tp_dealloc*/
477 (printfunc)0, /*tp_print*/
478 (getattrfunc)O_getattr, /*tp_getattr*/
479 (setattrfunc)O_setattr, /*tp_setattr*/
480 (cmpfunc)0, /*tp_compare*/
481 (reprfunc)0, /*tp_repr*/
482 0, /*tp_as_number*/
483 0, /*tp_as_sequence*/
484 0, /*tp_as_mapping*/
485 (hashfunc)0, /*tp_hash*/
486 (ternaryfunc)0, /*tp_call*/
487 (reprfunc)0, /*tp_str*/
489 /* Space for future expansion */
490 0L,0L,0L,0L,
491 Otype__doc__ /* Documentation string */
494 static PyObject *
495 newOobject(int size) {
496 Oobject *self;
498 self = PyObject_New(Oobject, &Otype);
499 if (self == NULL)
500 return NULL;
501 self->pos=0;
502 self->string_size = 0;
503 self->softspace = 0;
505 UNLESS (self->buf=malloc(size*sizeof(char))) {
506 PyErr_SetString(PyExc_MemoryError,"out of memory");
507 self->buf_size = 0;
508 return NULL;
511 self->buf_size=size;
512 return (PyObject*)self;
515 /* End of code for StringO objects */
516 /* -------------------------------------------------------- */
518 static PyObject *
519 I_close(Iobject *self, PyObject *unused) {
520 Py_XDECREF(self->pbuf);
521 self->pbuf = NULL;
522 self->buf = NULL;
524 self->pos = self->string_size = 0;
526 Py_INCREF(Py_None);
527 return Py_None;
530 static PyObject *
531 I_seek(Iobject *self, PyObject *args) {
532 int position, mode = 0;
534 UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
535 UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
536 return NULL;
538 if (mode == 2) position += self->string_size;
539 else if (mode == 1) position += self->pos;
541 if (position < 0) position=0;
543 self->pos=position;
545 Py_INCREF(Py_None);
546 return Py_None;
549 static struct PyMethodDef I_methods[] = {
550 /* Common methods: */
551 {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
552 {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
553 {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
554 {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
555 {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
556 {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
557 {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
558 {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
559 {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
561 /* Read-only StringIO specific methods: */
562 {"close", (PyCFunction)I_close, METH_NOARGS, O_close__doc__},
563 {"seek", (PyCFunction)I_seek, METH_VARARGS, O_seek__doc__},
564 {NULL, NULL}
567 static void
568 I_dealloc(Iobject *self) {
569 Py_XDECREF(self->pbuf);
570 PyObject_Del(self);
573 static PyObject *
574 I_getattr(Iobject *self, char *name) {
575 return Py_FindMethod(I_methods, (PyObject *)self, name);
578 static PyObject *
579 I_getiter(Iobject *self)
581 PyObject *myreadline = PyObject_GetAttrString((PyObject*)self,
582 "readline");
583 PyObject *emptystring = PyString_FromString("");
584 PyObject *iter = NULL;
585 if (!myreadline || !emptystring)
586 goto finally;
588 iter = PyCallIter_New(myreadline, emptystring);
589 finally:
590 Py_XDECREF(myreadline);
591 Py_XDECREF(emptystring);
592 return iter;
596 PyDoc_STRVAR(Itype__doc__,
597 "Simple type for treating strings as input file streams");
599 static PyTypeObject Itype = {
600 PyObject_HEAD_INIT(NULL)
601 0, /*ob_size*/
602 "cStringIO.StringI", /*tp_name*/
603 sizeof(Iobject), /*tp_basicsize*/
604 0, /*tp_itemsize*/
605 /* methods */
606 (destructor)I_dealloc, /*tp_dealloc*/
607 (printfunc)0, /*tp_print*/
608 (getattrfunc)I_getattr, /*tp_getattr*/
609 (setattrfunc)0, /*tp_setattr*/
610 (cmpfunc)0, /*tp_compare*/
611 (reprfunc)0, /*tp_repr*/
612 0, /*tp_as_number*/
613 0, /*tp_as_sequence*/
614 0, /*tp_as_mapping*/
615 (hashfunc)0, /*tp_hash*/
616 (ternaryfunc)0, /*tp_call*/
617 (reprfunc)0, /*tp_str*/
618 0, /* tp_getattro */
619 0, /* tp_setattro */
620 0, /* tp_as_buffer */
621 Py_TPFLAGS_DEFAULT, /* tp_flags */
622 Itype__doc__, /* tp_doc */
623 0, /* tp_traverse */
624 0, /* tp_clear */
625 0, /* tp_richcompare */
626 0, /* tp_weaklistoffset */
627 (getiterfunc)I_getiter, /* tp_iter */
628 0, /* tp_iternext */
631 static PyObject *
632 newIobject(PyObject *s) {
633 Iobject *self;
634 char *buf;
635 int size;
637 if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
638 PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
639 s->ob_type->tp_name);
640 return NULL;
642 UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL;
643 Py_INCREF(s);
644 self->buf=buf;
645 self->string_size=size;
646 self->pbuf=s;
647 self->pos=0;
649 return (PyObject*)self;
652 /* End of code for StringI objects */
653 /* -------------------------------------------------------- */
656 PyDoc_STRVAR(IO_StringIO__doc__,
657 "StringIO([s]) -- Return a StringIO-like stream for reading or writing");
659 static PyObject *
660 IO_StringIO(PyObject *self, PyObject *args) {
661 PyObject *s=0;
663 if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
665 if (s) return newIobject(s);
666 return newOobject(128);
669 /* List of methods defined in the module */
671 static struct PyMethodDef IO_methods[] = {
672 {"StringIO", (PyCFunction)IO_StringIO,
673 METH_VARARGS, IO_StringIO__doc__},
674 {NULL, NULL} /* sentinel */
678 /* Initialization function for the module (*must* be called initcStringIO) */
680 static struct PycStringIO_CAPI CAPI = {
681 IO_cread,
682 IO_creadline,
683 O_cwrite,
684 IO_cgetval,
685 newOobject,
686 newIobject,
687 &Itype,
688 &Otype,
691 #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
692 #define PyMODINIT_FUNC void
693 #endif
694 PyMODINIT_FUNC
695 initcStringIO(void) {
696 PyObject *m, *d, *v;
699 /* Create the module and add the functions */
700 m = Py_InitModule4("cStringIO", IO_methods,
701 cStringIO_module_documentation,
702 (PyObject*)NULL,PYTHON_API_VERSION);
704 /* Add some symbolic constants to the module */
705 d = PyModule_GetDict(m);
707 /* Export C API */
708 Itype.ob_type=&PyType_Type;
709 Otype.ob_type=&PyType_Type;
710 PyDict_SetItemString(d,"cStringIO_CAPI",
711 v = PyCObject_FromVoidPtr(&CAPI,NULL));
712 Py_XDECREF(v);
714 /* Export Types */
715 PyDict_SetItemString(d,"InputType", (PyObject*)&Itype);
716 PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
718 /* Maybe make certain warnings go away */
719 if (0) PycString_IMPORT;