2 * cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp
4 * Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
11 * o Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the disclaimer that follows.
14 * o Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions, and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * o All advertising materials mentioning features or use of this
20 * software must display the following acknowledgement:
22 * This product includes software developed by Digital Creations
23 * and its contributors.
25 * o Neither the name of Digital Creations nor the names of its
26 * contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
31 * IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
32 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
33 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
34 * CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
37 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
44 # If you have questions regarding this software, contact:
46 # Digital Creations, L.C.
47 # 910 Princess Ann Street
48 # Fredericksburge, Virginia 22401
54 static char cStringIO_module_documentation
[] =
55 "A simple fast partial StringIO replacement.\n"
57 "This module provides a simple useful replacement for\n"
58 "the StringIO module that is written in C. It does not provide the\n"
59 "full generality of StringIO, but it provides enough for most\n"
60 "applications and is especially useful in conjunction with the\n"
65 " from cStringIO import StringIO\n"
67 " an_output_stream=StringIO()\n"
68 " an_output_stream.write(some_stuff)\n"
70 " value=an_output_stream.getvalue()\n"
72 " an_input_stream=StringIO(a_string)\n"
73 " spam=an_input_stream.readline()\n"
74 " spam=an_input_stream.read(5)\n"
75 " an_input_stream.seek(0) # OK, start over\n"
76 " spam=an_input_stream.read() # and read it all\n"
78 "If someone else wants to provide a more complete implementation,\n"
81 "cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n"
86 #include "cStringIO.h"
88 #define UNLESS(E) if (!(E))
91 /* Declaration for file-like objects that manage data as strings
93 The IOobject type should be though of as a common base type for
94 Iobjects, which provide input (read-only) StringIO objects and
95 Oobjects, which provide read-write objects. Most of the methods
96 depend only on common data.
102 int pos
, string_size
;
105 #define IOOOBJECT(O) ((IOobject*)(O))
107 /* Declarations for objects of type StringO */
109 typedef struct { /* Subtype of IOobject */
112 int pos
, string_size
;
114 int buf_size
, softspace
;
117 /* Declarations for objects of type StringI */
119 typedef struct { /* Subtype of IOobject */
122 int pos
, string_size
;
123 /* We store a reference to the object here in order to keep
124 the buffer alive during the lifetime of the Iobject. */
128 /* IOobject (common) methods */
130 static char IO_flush__doc__
[] = "flush(): does nothing.";
133 IO__opencheck(IOobject
*self
) {
135 PyErr_SetString(PyExc_ValueError
,
136 "I/O operation on closed file");
143 IO_flush(IOobject
*self
, PyObject
*args
) {
145 UNLESS (IO__opencheck(self
)) return NULL
;
146 UNLESS (PyArg_ParseTuple(args
, ":flush")) return NULL
;
152 static char IO_getval__doc__
[] =
153 "getvalue([use_pos]) -- Get the string value."
155 "If use_pos is specified and is a true value, then the string returned\n"
156 "will include only the text up to the current file position.\n"
160 IO_cgetval(PyObject
*self
) {
161 UNLESS (IO__opencheck(IOOOBJECT(self
))) return NULL
;
162 return PyString_FromStringAndSize(((IOobject
*)self
)->buf
,
163 ((IOobject
*)self
)->pos
);
167 IO_getval(IOobject
*self
, PyObject
*args
) {
168 PyObject
*use_pos
=Py_None
;
171 UNLESS (IO__opencheck(self
)) return NULL
;
172 UNLESS (PyArg_ParseTuple(args
,"|O:getval",&use_pos
)) return NULL
;
174 if (PyObject_IsTrue(use_pos
)) {
176 if (s
> self
->string_size
) s
=self
->string_size
;
180 return PyString_FromStringAndSize(self
->buf
, s
);
183 static char IO_isatty__doc__
[] = "isatty(): always returns 0";
186 IO_isatty(IOobject
*self
, PyObject
*args
) {
188 UNLESS (PyArg_ParseTuple(args
, ":isatty")) return NULL
;
190 return PyInt_FromLong(0);
193 static char IO_read__doc__
[] =
194 "read([s]) -- Read s characters, or the rest of the string"
198 IO_cread(PyObject
*self
, char **output
, int n
) {
201 UNLESS (IO__opencheck(IOOOBJECT(self
))) return -1;
202 l
= ((IOobject
*)self
)->string_size
- ((IOobject
*)self
)->pos
;
203 if (n
< 0 || n
> l
) {
208 *output
=((IOobject
*)self
)->buf
+ ((IOobject
*)self
)->pos
;
209 ((IOobject
*)self
)->pos
+= n
;
214 IO_read(IOobject
*self
, PyObject
*args
) {
218 UNLESS (PyArg_ParseTuple(args
, "|i:read", &n
)) return NULL
;
220 if ( (n
=IO_cread((PyObject
*)self
,&output
,n
)) < 0) return NULL
;
222 return PyString_FromStringAndSize(output
, n
);
225 static char IO_readline__doc__
[] =
226 "readline() -- Read one line"
230 IO_creadline(PyObject
*self
, char **output
) {
234 UNLESS (IO__opencheck(IOOOBJECT(self
))) return -1;
236 for (n
= ((IOobject
*)self
)->buf
+ ((IOobject
*)self
)->pos
,
237 s
= ((IOobject
*)self
)->buf
+ ((IOobject
*)self
)->string_size
;
238 n
< s
&& *n
!= '\n'; n
++);
241 *output
=((IOobject
*)self
)->buf
+ ((IOobject
*)self
)->pos
;
242 l
= n
- ((IOobject
*)self
)->buf
- ((IOobject
*)self
)->pos
;
243 ((IOobject
*)self
)->pos
+= l
;
248 IO_readline(IOobject
*self
, PyObject
*args
) {
252 UNLESS (PyArg_ParseTuple(args
, "|i:readline", &m
)) return NULL
;
254 if( (n
=IO_creadline((PyObject
*)self
,&output
)) < 0) return NULL
;
255 if (m
>= 0 && m
< n
) {
260 return PyString_FromStringAndSize(output
, n
);
263 static char IO_readlines__doc__
[] =
264 "readlines() -- Read all lines"
268 IO_readlines(IOobject
*self
, PyObject
*args
) {
271 PyObject
*result
, *line
;
272 int hint
= 0, length
= 0;
274 UNLESS (PyArg_ParseTuple(args
, "|i:readlines", &hint
)) return NULL
;
276 result
= PyList_New(0);
281 if ( (n
= IO_creadline((PyObject
*)self
,&output
)) < 0)
285 line
= PyString_FromStringAndSize (output
, n
);
288 PyList_Append (result
, line
);
291 if (hint
> 0 && length
>= hint
)
300 static char IO_reset__doc__
[] =
301 "reset() -- Reset the file position to the beginning"
305 IO_reset(IOobject
*self
, PyObject
*args
) {
307 UNLESS (IO__opencheck(self
)) return NULL
;
308 UNLESS (PyArg_ParseTuple(args
, ":reset")) return NULL
;
316 static char IO_tell__doc__
[] =
317 "tell() -- get the current position.";
320 IO_tell(IOobject
*self
, PyObject
*args
) {
322 UNLESS (IO__opencheck(self
)) return NULL
;
323 UNLESS (PyArg_ParseTuple(args
, ":tell")) return NULL
;
325 return PyInt_FromLong(self
->pos
);
328 static char IO_truncate__doc__
[] =
329 "truncate(): truncate the file at the current position.";
332 IO_truncate(IOobject
*self
, PyObject
*args
) {
335 UNLESS (IO__opencheck(self
)) return NULL
;
336 UNLESS (PyArg_ParseTuple(args
, "|i:truncate", &pos
)) return NULL
;
337 if (pos
< 0) pos
= self
->pos
;
339 if (self
->string_size
> pos
) self
->string_size
= pos
;
348 /* Read-write object methods */
350 static char O_seek__doc__
[] =
351 "seek(position) -- set the current position\n"
352 "seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF";
355 O_seek(Oobject
*self
, PyObject
*args
) {
356 int position
, mode
= 0;
358 UNLESS (IO__opencheck(IOOOBJECT(self
))) return NULL
;
359 UNLESS (PyArg_ParseTuple(args
, "i|i:seek", &position
, &mode
))
363 position
+= self
->string_size
;
365 else if (mode
== 1) {
366 position
+= self
->pos
;
369 if (position
> self
->buf_size
) {
371 if (self
->buf_size
<= position
) self
->buf_size
=position
+1;
372 UNLESS (self
->buf
=(char*)
373 realloc(self
->buf
,self
->buf_size
*sizeof(char))) {
374 self
->buf_size
=self
->pos
=0;
375 return PyErr_NoMemory();
378 else if (position
< 0) position
=0;
382 while (--position
>= self
->string_size
) self
->buf
[position
]=0;
388 static char O_write__doc__
[] =
389 "write(s) -- Write a string to the file"
390 "\n\nNote (hack:) writing None resets the buffer"
395 O_cwrite(PyObject
*self
, char *c
, int l
) {
399 UNLESS (IO__opencheck(IOOOBJECT(self
))) return -1;
400 oself
= (Oobject
*)self
;
403 if (newl
>= oself
->buf_size
) {
404 oself
->buf_size
*= 2;
405 if (oself
->buf_size
<= newl
)
406 oself
->buf_size
= newl
+1;
408 (char*)realloc(oself
->buf
,
409 (oself
->buf_size
) * sizeof(char))) {
410 PyErr_SetString(PyExc_MemoryError
,"out of memory");
411 oself
->buf_size
= oself
->pos
= 0;
416 memcpy(oself
->buf
+oself
->pos
,c
,l
);
420 if (oself
->string_size
< oself
->pos
) {
421 oself
->string_size
= oself
->pos
;
428 O_write(Oobject
*self
, PyObject
*args
) {
432 UNLESS (PyArg_ParseTuple(args
, "s#:write", &c
, &l
)) return NULL
;
434 if (O_cwrite((PyObject
*)self
,c
,l
) < 0) return NULL
;
440 static char O_close__doc__
[] = "close(): explicitly release resources held.";
443 O_close(Oobject
*self
, PyObject
*args
) {
445 UNLESS (PyArg_ParseTuple(args
, ":close")) return NULL
;
447 if (self
->buf
!= NULL
) free(self
->buf
);
450 self
->pos
= self
->string_size
= self
->buf_size
= 0;
457 static char O_writelines__doc__
[] =
458 "writelines(sequence_of_strings): write each string";
460 O_writelines(Oobject
*self
, PyObject
*args
) {
462 static PyObject
*joiner
= NULL
;
464 UNLESS (PyArg_ParseTuple(args
, "O:writelines", &args
)) return NULL
;
467 PyObject
*empty_string
= PyString_FromString("");
468 if (empty_string
== NULL
)
470 joiner
= PyObject_GetAttrString(empty_string
, "join");
471 Py_DECREF(empty_string
);
476 if (PyObject_Size(args
) < 0) return NULL
;
478 tmp
= PyObject_CallFunction(joiner
, "O", args
);
479 UNLESS (tmp
) return NULL
;
481 args
= Py_BuildValue("(O)", tmp
);
483 UNLESS (args
) return NULL
;
485 tmp
= O_write(self
, args
);
490 static struct PyMethodDef O_methods
[] = {
491 /* Common methods: */
492 {"flush", (PyCFunction
)IO_flush
, METH_VARARGS
, IO_flush__doc__
},
493 {"getvalue", (PyCFunction
)IO_getval
, METH_VARARGS
, IO_getval__doc__
},
494 {"isatty", (PyCFunction
)IO_isatty
, METH_VARARGS
, IO_isatty__doc__
},
495 {"read", (PyCFunction
)IO_read
, METH_VARARGS
, IO_read__doc__
},
496 {"readline", (PyCFunction
)IO_readline
, METH_VARARGS
, IO_readline__doc__
},
497 {"readlines", (PyCFunction
)IO_readlines
,METH_VARARGS
, IO_readlines__doc__
},
498 {"reset", (PyCFunction
)IO_reset
, METH_VARARGS
, IO_reset__doc__
},
499 {"tell", (PyCFunction
)IO_tell
, METH_VARARGS
, IO_tell__doc__
},
500 {"truncate", (PyCFunction
)IO_truncate
, METH_VARARGS
, IO_truncate__doc__
},
502 /* Read-write StringIO specific methods: */
503 {"close", (PyCFunction
)O_close
, METH_VARARGS
, O_close__doc__
},
504 {"seek", (PyCFunction
)O_seek
, METH_VARARGS
, O_seek__doc__
},
505 {"write", (PyCFunction
)O_write
, METH_VARARGS
, O_write__doc__
},
506 {"writelines", (PyCFunction
)O_writelines
, METH_VARARGS
, O_writelines__doc__
},
507 {NULL
, NULL
} /* sentinel */
511 O_dealloc(Oobject
*self
) {
512 if (self
->buf
!= NULL
)
518 O_getattr(Oobject
*self
, char *name
) {
519 if (strcmp(name
, "softspace") == 0) {
520 return PyInt_FromLong(self
->softspace
);
522 return Py_FindMethod(O_methods
, (PyObject
*)self
, name
);
526 O_setattr(Oobject
*self
, char *name
, PyObject
*value
) {
528 if (strcmp(name
, "softspace") != 0) {
529 PyErr_SetString(PyExc_AttributeError
, name
);
532 x
= PyInt_AsLong(value
);
533 if (x
< 0 && PyErr_Occurred())
539 static char Otype__doc__
[] =
540 "Simple type for output to strings."
543 static PyTypeObject Otype
= {
544 PyObject_HEAD_INIT(NULL
)
546 "cStringIO.StringO", /*tp_name*/
547 sizeof(Oobject
), /*tp_basicsize*/
550 (destructor
)O_dealloc
, /*tp_dealloc*/
551 (printfunc
)0, /*tp_print*/
552 (getattrfunc
)O_getattr
, /*tp_getattr*/
553 (setattrfunc
)O_setattr
, /*tp_setattr*/
554 (cmpfunc
)0, /*tp_compare*/
555 (reprfunc
)0, /*tp_repr*/
557 0, /*tp_as_sequence*/
559 (hashfunc
)0, /*tp_hash*/
560 (ternaryfunc
)0, /*tp_call*/
561 (reprfunc
)0, /*tp_str*/
563 /* Space for future expansion */
565 Otype__doc__
/* Documentation string */
569 newOobject(int size
) {
572 self
= PyObject_New(Oobject
, &Otype
);
576 self
->string_size
= 0;
579 UNLESS (self
->buf
=malloc(size
*sizeof(char))) {
580 PyErr_SetString(PyExc_MemoryError
,"out of memory");
586 return (PyObject
*)self
;
589 /* End of code for StringO objects */
590 /* -------------------------------------------------------- */
593 I_close(Iobject
*self
, PyObject
*args
) {
595 UNLESS (PyArg_ParseTuple(args
, ":close")) return NULL
;
597 Py_XDECREF(self
->pbuf
);
601 self
->pos
= self
->string_size
= 0;
608 I_seek(Iobject
*self
, PyObject
*args
) {
609 int position
, mode
= 0;
611 UNLESS (IO__opencheck(IOOOBJECT(self
))) return NULL
;
612 UNLESS (PyArg_ParseTuple(args
, "i|i:seek", &position
, &mode
))
615 if (mode
== 2) position
+= self
->string_size
;
616 else if (mode
== 1) position
+= self
->pos
;
618 if (position
< 0) position
=0;
626 static struct PyMethodDef I_methods
[] = {
627 /* Common methods: */
628 {"flush", (PyCFunction
)IO_flush
, METH_VARARGS
, IO_flush__doc__
},
629 {"getvalue", (PyCFunction
)IO_getval
, METH_VARARGS
, IO_getval__doc__
},
630 {"isatty", (PyCFunction
)IO_isatty
, METH_VARARGS
, IO_isatty__doc__
},
631 {"read", (PyCFunction
)IO_read
, METH_VARARGS
, IO_read__doc__
},
632 {"readline", (PyCFunction
)IO_readline
, METH_VARARGS
, IO_readline__doc__
},
633 {"readlines", (PyCFunction
)IO_readlines
,METH_VARARGS
, IO_readlines__doc__
},
634 {"reset", (PyCFunction
)IO_reset
, METH_VARARGS
, IO_reset__doc__
},
635 {"tell", (PyCFunction
)IO_tell
, METH_VARARGS
, IO_tell__doc__
},
636 {"truncate", (PyCFunction
)IO_truncate
, METH_VARARGS
, IO_truncate__doc__
},
638 /* Read-only StringIO specific methods: */
639 {"close", (PyCFunction
)I_close
, METH_VARARGS
, O_close__doc__
},
640 {"seek", (PyCFunction
)I_seek
, METH_VARARGS
, O_seek__doc__
},
645 I_dealloc(Iobject
*self
) {
646 Py_XDECREF(self
->pbuf
);
651 I_getattr(Iobject
*self
, char *name
) {
652 return Py_FindMethod(I_methods
, (PyObject
*)self
, name
);
656 I_getiter(Iobject
*self
)
658 PyObject
*myreadline
= PyObject_GetAttrString((PyObject
*)self
,
660 PyObject
*emptystring
= PyString_FromString("");
661 PyObject
*iter
= NULL
;
662 if (!myreadline
|| !emptystring
)
665 iter
= PyCallIter_New(myreadline
, emptystring
);
667 Py_XDECREF(myreadline
);
668 Py_XDECREF(emptystring
);
673 static char Itype__doc__
[] =
674 "Simple type for treating strings as input file streams"
677 static PyTypeObject Itype
= {
678 PyObject_HEAD_INIT(NULL
)
680 "cStringIO.StringI", /*tp_name*/
681 sizeof(Iobject
), /*tp_basicsize*/
684 (destructor
)I_dealloc
, /*tp_dealloc*/
685 (printfunc
)0, /*tp_print*/
686 (getattrfunc
)I_getattr
, /*tp_getattr*/
687 (setattrfunc
)0, /*tp_setattr*/
688 (cmpfunc
)0, /*tp_compare*/
689 (reprfunc
)0, /*tp_repr*/
691 0, /*tp_as_sequence*/
693 (hashfunc
)0, /*tp_hash*/
694 (ternaryfunc
)0, /*tp_call*/
695 (reprfunc
)0, /*tp_str*/
698 0, /* tp_as_buffer */
699 Py_TPFLAGS_DEFAULT
, /* tp_flags */
700 Itype__doc__
, /* tp_doc */
703 0, /* tp_richcompare */
704 0, /* tp_weaklistoffset */
705 (getiterfunc
)I_getiter
, /* tp_iter */
710 newIobject(PyObject
*s
) {
715 if (PyObject_AsReadBuffer(s
, (const void **)&buf
, &size
)) {
716 PyErr_Format(PyExc_TypeError
, "expected read buffer, %.200s found",
717 s
->ob_type
->tp_name
);
720 UNLESS (self
= PyObject_New(Iobject
, &Itype
)) return NULL
;
723 self
->string_size
=size
;
727 return (PyObject
*)self
;
730 /* End of code for StringI objects */
731 /* -------------------------------------------------------- */
734 static char IO_StringIO__doc__
[] =
735 "StringIO([s]) -- Return a StringIO-like stream for reading or writing"
739 IO_StringIO(PyObject
*self
, PyObject
*args
) {
742 if (!PyArg_ParseTuple(args
, "|O:StringIO", &s
)) return NULL
;
744 if (s
) return newIobject(s
);
745 return newOobject(128);
748 /* List of methods defined in the module */
750 static struct PyMethodDef IO_methods
[] = {
751 {"StringIO", (PyCFunction
)IO_StringIO
,
752 METH_VARARGS
, IO_StringIO__doc__
},
753 {NULL
, NULL
} /* sentinel */
757 /* Initialization function for the module (*must* be called initcStringIO) */
759 static struct PycStringIO_CAPI CAPI
= {
770 #ifndef DL_EXPORT /* declarations for DLL import/export */
771 #define DL_EXPORT(RTYPE) RTYPE
774 initcStringIO(void) {
778 /* Create the module and add the functions */
779 m
= Py_InitModule4("cStringIO", IO_methods
,
780 cStringIO_module_documentation
,
781 (PyObject
*)NULL
,PYTHON_API_VERSION
);
783 /* Add some symbolic constants to the module */
784 d
= PyModule_GetDict(m
);
787 Itype
.ob_type
=&PyType_Type
;
788 Otype
.ob_type
=&PyType_Type
;
789 PyDict_SetItemString(d
,"cStringIO_CAPI",
790 v
= PyCObject_FromVoidPtr(&CAPI
,NULL
));
794 PyDict_SetItemString(d
,"InputType", (PyObject
*)&Itype
);
795 PyDict_SetItemString(d
,"OutputType", (PyObject
*)&Otype
);
797 /* Maybe make certain warnings go away */
798 if (0) PycString_IMPORT
;