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() # str(an_output_stream) works too!\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))
90 /* Declarations for objects of type StringO */
95 int pos
, string_size
, buf_size
, softspace
;
98 /* Declarations for objects of type StringI */
103 int pos
, string_size
;
107 static char O_reset__doc__
[] =
108 "reset() -- Reset the file position to the beginning"
112 O_reset(Oobject
*self
, PyObject
*args
) {
120 static char O_tell__doc__
[] =
121 "tell() -- get the current position.";
124 O_tell(Oobject
*self
, PyObject
*args
) {
125 return PyInt_FromLong(self
->pos
);
129 static char O_seek__doc__
[] =
130 "seek(position) -- set the current position\n"
131 "seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF";
134 O_seek(Oobject
*self
, PyObject
*args
) {
135 int position
, mode
= 0;
137 UNLESS(PyArg_ParseTuple(args
, "i|i:seek", &position
, &mode
)) {
142 position
+= self
->string_size
;
144 else if (mode
== 1) {
145 position
+= self
->pos
;
148 if (position
> self
->buf_size
) {
150 if(self
->buf_size
<= position
) self
->buf_size
=position
+1;
151 UNLESS(self
->buf
=(char*)realloc(self
->buf
,self
->buf_size
*sizeof(char))) {
152 self
->buf_size
=self
->pos
=0;
153 return PyErr_NoMemory();
156 else if(position
< 0) position
=0;
160 while(--position
>= self
->string_size
) self
->buf
[position
]=0;
166 static char O_read__doc__
[] =
167 "read([s]) -- Read s characters, or the rest of the string"
171 O_cread(PyObject
*self
, char **output
, int n
) {
174 l
= ((Oobject
*)self
)->string_size
- ((Oobject
*)self
)->pos
;
175 if (n
< 0 || n
> l
) {
180 *output
=((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->pos
;
181 ((Oobject
*)self
)->pos
+= n
;
186 O_read(Oobject
*self
, PyObject
*args
) {
190 UNLESS(PyArg_ParseTuple(args
, "|i:read", &n
)) return NULL
;
192 n
=O_cread((PyObject
*)self
,&output
,n
);
194 return PyString_FromStringAndSize(output
, n
);
198 static char O_readline__doc__
[] =
199 "readline() -- Read one line"
203 O_creadline(PyObject
*self
, char **output
) {
207 for (n
= ((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->pos
,
208 s
= ((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->string_size
;
209 n
< s
&& *n
!= '\n'; n
++);
212 *output
=((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->pos
;
213 l
= n
- ((Oobject
*)self
)->buf
- ((Oobject
*)self
)->pos
;
214 ((Oobject
*)self
)->pos
+= l
;
219 O_readline(Oobject
*self
, PyObject
*args
) {
223 n
=O_creadline((PyObject
*)self
,&output
);
224 return PyString_FromStringAndSize(output
, n
);
227 static char O_write__doc__
[] =
228 "write(s) -- Write a string to the file"
229 "\n\nNote (hack:) writing None resets the buffer"
234 O_cwrite(PyObject
*self
, char *c
, int l
) {
237 newl
=((Oobject
*)self
)->pos
+l
;
238 if(newl
>= ((Oobject
*)self
)->buf_size
) {
239 ((Oobject
*)self
)->buf_size
*=2;
240 if(((Oobject
*)self
)->buf_size
<= newl
) ((Oobject
*)self
)->buf_size
=newl
+1;
241 UNLESS(((Oobject
*)self
)->buf
=
242 (char*)realloc(((Oobject
*)self
)->buf
,
243 (((Oobject
*)self
)->buf_size
) *sizeof(char))) {
244 PyErr_SetString(PyExc_MemoryError
,"out of memory");
245 ((Oobject
*)self
)->buf_size
=((Oobject
*)self
)->pos
=0;
250 memcpy(((Oobject
*)((Oobject
*)self
))->buf
+((Oobject
*)self
)->pos
,c
,l
);
252 ((Oobject
*)self
)->pos
+= l
;
254 if (((Oobject
*)self
)->string_size
< ((Oobject
*)self
)->pos
) {
255 ((Oobject
*)self
)->string_size
= ((Oobject
*)self
)->pos
;
262 O_write(Oobject
*self
, PyObject
*args
) {
267 UNLESS(PyArg_ParseTuple(args
, "O:write", &s
)) return NULL
;
268 UNLESS(-1 != (l
=PyString_Size(s
))) return NULL
;
269 UNLESS(c
=PyString_AsString(s
)) return NULL
;
270 UNLESS(-1 != O_cwrite((PyObject
*)self
,c
,l
)) return NULL
;
276 static char O_getval__doc__
[] =
277 "getvalue([use_pos]) -- Get the string value."
279 "If use_pos is specified and is a true value, then the string returned\n"
280 "will include only the text up to the current file position.\n"
284 O_getval(Oobject
*self
, PyObject
*args
) {
285 PyObject
*use_pos
=Py_None
;
289 UNLESS(PyArg_ParseTuple(args
,"|O:getval",&use_pos
)) return NULL
;
290 if(PyObject_IsTrue(use_pos
)) {
292 if (s
> self
->string_size
) s
=self
->string_size
;
296 return PyString_FromStringAndSize(self
->buf
, s
);
300 O_cgetval(PyObject
*self
) {
301 return PyString_FromStringAndSize(((Oobject
*)self
)->buf
,
302 ((Oobject
*)self
)->pos
);
305 static char O_truncate__doc__
[] =
306 "truncate(): truncate the file at the current position.";
309 O_truncate(Oobject
*self
, PyObject
*args
) {
310 if (self
->string_size
> self
->pos
)
311 self
->string_size
= self
->pos
;
316 static char O_isatty__doc__
[] = "isatty(): always returns 0";
319 O_isatty(Oobject
*self
, PyObject
*args
) {
320 return PyInt_FromLong(0);
323 static char O_close__doc__
[] = "close(): explicitly release resources held.";
326 O_close(Oobject
*self
, PyObject
*args
) {
327 if (self
->buf
!= NULL
)
331 self
->pos
= self
->string_size
= self
->buf_size
= 0;
337 static char O_flush__doc__
[] = "flush(): does nothing.";
340 O_flush(Oobject
*self
, PyObject
*args
) {
346 static char O_writelines__doc__
[] =
347 "writelines(sequence_of_strings): write each string";
349 O_writelines(Oobject
*self
, PyObject
*args
) {
350 PyObject
*string_module
= 0;
351 static PyObject
*string_joinfields
= 0;
353 UNLESS(PyArg_ParseTuple(args
, "O:writelines", &args
)) {
357 if (!string_joinfields
) {
358 UNLESS(string_module
= PyImport_ImportModule("string")) {
362 UNLESS(string_joinfields
=
363 PyObject_GetAttrString(string_module
, "joinfields")) {
367 Py_DECREF(string_module
);
370 if (PyObject_Size(args
) == -1) {
375 PyObject
*x
= PyObject_CallFunction(string_joinfields
,
379 args
= Py_BuildValue("(O)", x
);
383 x
= O_write(self
, args
);
389 static struct PyMethodDef O_methods
[] = {
390 {"write", (PyCFunction
)O_write
, METH_VARARGS
, O_write__doc__
},
391 {"read", (PyCFunction
)O_read
, METH_VARARGS
, O_read__doc__
},
392 {"readline", (PyCFunction
)O_readline
, METH_VARARGS
, O_readline__doc__
},
393 {"reset", (PyCFunction
)O_reset
, METH_VARARGS
, O_reset__doc__
},
394 {"seek", (PyCFunction
)O_seek
, METH_VARARGS
, O_seek__doc__
},
395 {"tell", (PyCFunction
)O_tell
, METH_VARARGS
, O_tell__doc__
},
396 {"getvalue", (PyCFunction
)O_getval
, METH_VARARGS
, O_getval__doc__
},
397 {"truncate", (PyCFunction
)O_truncate
, METH_VARARGS
, O_truncate__doc__
},
398 {"isatty", (PyCFunction
)O_isatty
, METH_VARARGS
, O_isatty__doc__
},
399 {"close", (PyCFunction
)O_close
, METH_VARARGS
, O_close__doc__
},
400 {"flush", (PyCFunction
)O_flush
, METH_VARARGS
, O_flush__doc__
},
401 {"writelines", (PyCFunction
)O_writelines
, METH_VARARGS
, O_writelines__doc__
},
402 {NULL
, NULL
} /* sentinel */
407 O_dealloc(Oobject
*self
) {
408 if (self
->buf
!= NULL
)
414 O_getattr(Oobject
*self
, char *name
) {
415 if (strcmp(name
, "softspace") == 0) {
416 return PyInt_FromLong(self
->softspace
);
418 return Py_FindMethod(O_methods
, (PyObject
*)self
, name
);
422 O_setattr(Oobject
*self
, char *name
, PyObject
*value
) {
424 if (strcmp(name
, "softspace") != 0) {
425 PyErr_SetString(PyExc_AttributeError
, name
);
428 x
= PyInt_AsLong(value
);
429 if (x
== -1 && PyErr_Occurred())
435 static char Otype__doc__
[] =
436 "Simple type for output to strings."
439 static PyTypeObject Otype
= {
440 PyObject_HEAD_INIT(NULL
)
442 "StringO", /*tp_name*/
443 sizeof(Oobject
), /*tp_basicsize*/
446 (destructor
)O_dealloc
, /*tp_dealloc*/
447 (printfunc
)0, /*tp_print*/
448 (getattrfunc
)O_getattr
, /*tp_getattr*/
449 (setattrfunc
)O_setattr
, /*tp_setattr*/
450 (cmpfunc
)0, /*tp_compare*/
451 (reprfunc
)0, /*tp_repr*/
453 0, /*tp_as_sequence*/
455 (hashfunc
)0, /*tp_hash*/
456 (ternaryfunc
)0, /*tp_call*/
457 (reprfunc
)0, /*tp_str*/
459 /* Space for future expansion */
461 Otype__doc__
/* Documentation string */
465 newOobject(int size
) {
468 self
= PyObject_New(Oobject
, &Otype
);
472 self
->string_size
= 0;
475 UNLESS(self
->buf
=malloc(size
*sizeof(char))) {
476 PyErr_SetString(PyExc_MemoryError
,"out of memory");
482 return (PyObject
*)self
;
485 /* End of code for StringO objects */
486 /* -------------------------------------------------------- */
489 I_close(Iobject
*self
, PyObject
*args
) {
490 Py_XDECREF(self
->pbuf
);
493 self
->pos
= self
->string_size
= 0;
500 I_seek(Oobject
*self
, PyObject
*args
) {
501 int position
, mode
= 0;
503 UNLESS(PyArg_ParseTuple(args
, "i|i:seek", &position
, &mode
)) {
508 position
+= self
->string_size
;
510 else if (mode
== 1) {
511 position
+= self
->pos
;
514 if(position
< 0) position
=0;
522 static struct PyMethodDef I_methods
[] = {
523 {"read", (PyCFunction
)O_read
, METH_VARARGS
, O_read__doc__
},
524 {"readline", (PyCFunction
)O_readline
, METH_VARARGS
, O_readline__doc__
},
525 {"reset", (PyCFunction
)O_reset
, METH_VARARGS
, O_reset__doc__
},
526 {"seek", (PyCFunction
)I_seek
, METH_VARARGS
, O_seek__doc__
},
527 {"tell", (PyCFunction
)O_tell
, METH_VARARGS
, O_tell__doc__
},
528 {"getvalue", (PyCFunction
)O_getval
, METH_VARARGS
, O_getval__doc__
},
529 {"truncate", (PyCFunction
)O_truncate
, METH_VARARGS
, O_truncate__doc__
},
530 {"isatty", (PyCFunction
)O_isatty
, METH_VARARGS
, O_isatty__doc__
},
531 {"close", (PyCFunction
)I_close
, METH_VARARGS
, O_close__doc__
},
532 {"flush", (PyCFunction
)O_flush
, METH_VARARGS
, O_flush__doc__
},
537 I_dealloc(Iobject
*self
) {
538 Py_XDECREF(self
->pbuf
);
543 I_getattr(Iobject
*self
, char *name
) {
544 return Py_FindMethod(I_methods
, (PyObject
*)self
, name
);
547 static char Itype__doc__
[] =
548 "Simple type for treating strings as input file streams"
551 static PyTypeObject Itype
= {
552 PyObject_HEAD_INIT(NULL
)
554 "StringI", /*tp_name*/
555 sizeof(Iobject
), /*tp_basicsize*/
558 (destructor
)I_dealloc
, /*tp_dealloc*/
559 (printfunc
)0, /*tp_print*/
560 (getattrfunc
)I_getattr
, /*tp_getattr*/
561 (setattrfunc
)0, /*tp_setattr*/
562 (cmpfunc
)0, /*tp_compare*/
563 (reprfunc
)0, /*tp_repr*/
565 0, /*tp_as_sequence*/
567 (hashfunc
)0, /*tp_hash*/
568 (ternaryfunc
)0, /*tp_call*/
569 (reprfunc
)0, /*tp_str*/
571 /* Space for future expansion */
573 Itype__doc__
/* Documentation string */
577 newIobject(PyObject
*s
) {
582 if (!PyString_Check(s
)) {
583 PyErr_Format(PyExc_TypeError
, "expected string, %.200s found",
584 s
->ob_type
->tp_name
);
587 buf
= PyString_AS_STRING(s
);
588 size
= PyString_GET_SIZE(s
);
589 UNLESS(self
= PyObject_New(Iobject
, &Itype
)) return NULL
;
592 self
->string_size
=size
;
596 return (PyObject
*)self
;
599 /* End of code for StringI objects */
600 /* -------------------------------------------------------- */
603 static char IO_StringIO__doc__
[] =
604 "StringIO([s]) -- Return a StringIO-like stream for reading or writing"
608 IO_StringIO(PyObject
*self
, PyObject
*args
) {
611 if (!PyArg_ParseTuple(args
, "|O:StringIO", &s
))
613 if(s
) return newIobject(s
);
614 return newOobject(128);
617 /* List of methods defined in the module */
619 static struct PyMethodDef IO_methods
[] = {
620 {"StringIO", (PyCFunction
)IO_StringIO
,
621 METH_VARARGS
, IO_StringIO__doc__
},
622 {NULL
, NULL
} /* sentinel */
626 /* Initialization function for the module (*must* be called initcStringIO) */
628 static struct PycStringIO_CAPI CAPI
= {
639 #ifndef DL_EXPORT /* declarations for DLL import/export */
640 #define DL_EXPORT(RTYPE) RTYPE
643 initcStringIO(void) {
647 /* Create the module and add the functions */
648 m
= Py_InitModule4("cStringIO", IO_methods
,
649 cStringIO_module_documentation
,
650 (PyObject
*)NULL
,PYTHON_API_VERSION
);
652 /* Add some symbolic constants to the module */
653 d
= PyModule_GetDict(m
);
656 Itype
.ob_type
=&PyType_Type
;
657 Otype
.ob_type
=&PyType_Type
;
658 PyDict_SetItemString(d
,"cStringIO_CAPI",
659 v
= PyCObject_FromVoidPtr(&CAPI
,NULL
));
663 PyDict_SetItemString(d
,"InputType", (PyObject
*)&Itype
);
664 PyDict_SetItemString(d
,"OutputType", (PyObject
*)&Otype
);
666 /* Maybe make certain warnings go away */
667 if(0) PycString_IMPORT
;