3 cStringIO.c,v 1.23 1997/12/04 00:12:05 jim Exp
5 A simple fast partial StringIO replacement.
11 Copyright 1996 Digital Creations, L.C., 910 Princess Anne
12 Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
13 rights reserved. Copyright in this software is owned by DCLC,
14 unless otherwise indicated. Permission to use, copy and
15 distribute this software is hereby granted, provided that the
16 above copyright notice appear in all copies and that both that
17 copyright notice and this permission notice appear. Note that
18 any product, process or technology described in this software
19 may be the subject of other Intellectual Property rights
20 reserved by Digital Creations, L.C. and are not licensed
25 Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
26 All other trademarks are owned by their respective companies.
30 The software is provided "as is" without warranty of any kind,
31 either express or implied, including, but not limited to, the
32 implied warranties of merchantability, fitness for a particular
33 purpose, or non-infringement. This software could include
34 technical inaccuracies or typographical errors. Changes are
35 periodically made to the software; these changes will be
36 incorporated in new editions of the software. DCLC may make
37 improvements and/or changes in this software at any time
40 Limitation Of Liability
42 In no event will DCLC be liable for direct, indirect, special,
43 incidental, economic, cover, or consequential damages arising
44 out of the use of or inability to use this software even if
45 advised of the possibility of such damages. Some states do not
46 allow the exclusion or limitation of implied warranties or
47 limitation of liability for incidental or consequential
48 damages, so the above limitation or exclusion may not apply to
51 If you have questions regarding this software,
55 Digital Creations L.C.
61 static char cStringIO_module_documentation
[] =
62 "A simple fast partial StringIO replacement.\n"
64 "This module provides a simple useful replacement for\n"
65 "the StringIO module that is written in C. It does not provide the\n"
66 "full generality if StringIO, but it provides anough for most\n"
67 "applications and is especially useful in conjuction with the\n"
72 " from cStringIO import StringIO\n"
74 " an_output_stream=StringIO()\n"
75 " an_output_stream.write(some_stuff)\n"
77 " value=an_output_stream.getvalue() # str(an_output_stream) works too!\n"
79 " an_input_stream=StringIO(a_string)\n"
80 " spam=an_input_stream.readline()\n"
81 " spam=an_input_stream.read(5)\n"
82 " an_input_stream.reset() # OK, start over\n"
83 " spam=an_input_stream.read() # and read it all\n"
85 "If someone else wants to provide a more complete implementation,\n"
88 "cStringIO.c,v 1.23 1997/12/04 00:12:05 jim Exp\n"
93 #include "cStringIO.h"
95 #define UNLESS(E) if(!(E))
97 /* Declarations for objects of type StringO */
102 int pos
, string_size
, buf_size
, closed
, softspace
;
105 /* Declarations for objects of type StringI */
110 int pos
, string_size
, closed
;
114 static char O_reset__doc__
[] =
115 "reset() -- Reset the file position to the beginning"
119 O_reset(Oobject
*self
, PyObject
*args
) {
127 static char O_tell__doc__
[] =
128 "tell() -- get the current position.";
131 O_tell(Oobject
*self
, PyObject
*args
) {
132 return PyInt_FromLong(self
->pos
);
136 static char O_seek__doc__
[] =
137 "seek(position) -- set the current position\n"
138 "seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF";
141 O_seek(Oobject
*self
, PyObject
*args
) {
142 int position
, mode
= 0;
144 UNLESS(PyArg_ParseTuple(args
, "i|i", &position
, &mode
)) {
149 position
+= self
->string_size
;
151 else if (mode
== 1) {
152 position
+= self
->pos
;
155 self
->pos
= (position
> self
->string_size
? self
->string_size
:
156 (position
< 0 ? 0 : position
));
162 static char O_read__doc__
[] =
163 "read([s]) -- Read s characters, or the rest of the string"
167 O_cread(PyObject
*self
, char **output
, int n
) {
170 l
= ((Oobject
*)self
)->string_size
- ((Oobject
*)self
)->pos
;
171 if (n
< 0 || n
> l
) {
175 *output
=((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->pos
;
176 ((Oobject
*)self
)->pos
+= n
;
181 O_read(Oobject
*self
, PyObject
*args
) {
185 UNLESS(PyArg_ParseTuple(args
, "|i", &n
)) return NULL
;
187 n
=O_cread((PyObject
*)self
,&output
,n
);
189 return PyString_FromStringAndSize(output
, n
);
193 static char O_readline__doc__
[] =
194 "readline() -- Read one line"
198 O_creadline(PyObject
*self
, char **output
) {
202 for (n
= ((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->pos
,
203 s
= ((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->string_size
;
204 n
< s
&& *n
!= '\n'; n
++);
207 *output
=((Oobject
*)self
)->buf
+ ((Oobject
*)self
)->pos
;
208 l
= n
- ((Oobject
*)self
)->buf
- ((Oobject
*)self
)->pos
;
209 ((Oobject
*)self
)->pos
+= l
;
214 O_readline(Oobject
*self
, PyObject
*args
) {
218 n
=O_creadline((PyObject
*)self
,&output
);
219 return PyString_FromStringAndSize(output
, n
);
222 static char O_write__doc__
[] =
223 "write(s) -- Write a string to the file"
224 "\n\nNote (hack:) writing None resets the buffer"
229 O_cwrite(PyObject
*self
, char *c
, int l
) {
232 newl
=((Oobject
*)self
)->pos
+l
;
233 if(newl
>= ((Oobject
*)self
)->buf_size
) {
234 ((Oobject
*)self
)->buf_size
*=2;
235 if(((Oobject
*)self
)->buf_size
<= newl
) ((Oobject
*)self
)->buf_size
=newl
+1;
236 UNLESS(((Oobject
*)self
)->buf
=
237 (char*)realloc(((Oobject
*)self
)->buf
,
238 (((Oobject
*)self
)->buf_size
) *sizeof(char))) {
239 PyErr_SetString(PyExc_MemoryError
,"out of memory");
240 ((Oobject
*)self
)->buf_size
=((Oobject
*)self
)->pos
=0;
245 memcpy(((Oobject
*)((Oobject
*)self
))->buf
+((Oobject
*)self
)->pos
,c
,l
);
247 ((Oobject
*)self
)->pos
+= l
;
249 if (((Oobject
*)self
)->string_size
< ((Oobject
*)self
)->pos
) {
250 ((Oobject
*)self
)->string_size
= ((Oobject
*)self
)->pos
;
257 O_write(Oobject
*self
, PyObject
*args
) {
262 UNLESS(PyArg_Parse(args
, "O", &s
)) return NULL
;
263 UNLESS(-1 != (l
=PyString_Size(s
))) return NULL
;
264 UNLESS(c
=PyString_AsString(s
)) return NULL
;
265 UNLESS(-1 != O_cwrite((PyObject
*)self
,c
,l
)) return NULL
;
272 O_getval(Oobject
*self
, PyObject
*args
) {
277 UNLESS(PyArg_ParseTuple(args
,"|O",&use_pos
)) return NULL
;
278 if(PyObject_IsTrue(use_pos
)) s
=self
->pos
;
279 else s
=self
->string_size
;
280 return PyString_FromStringAndSize(self
->buf
, s
);
284 O_cgetval(PyObject
*self
) {
285 return PyString_FromStringAndSize(((Oobject
*)self
)->buf
,
286 ((Oobject
*)self
)->pos
);
289 static char O_truncate__doc__
[] =
290 "truncate(): truncate the file at the current position.";
293 O_truncate(Oobject
*self
, PyObject
*args
) {
294 self
->string_size
= self
->pos
;
299 static char O_isatty__doc__
[] = "isatty(): always returns 0";
302 O_isatty(Oobject
*self
, PyObject
*args
) {
303 return PyInt_FromLong(0);
306 static char O_close__doc__
[] = "close(): explicitly release resources held.";
309 O_close(Oobject
*self
, PyObject
*args
) {
310 if (self
->buf
!= NULL
)
314 self
->pos
= self
->string_size
= self
->buf_size
= 0;
321 static char O_flush__doc__
[] = "flush(): does nothing.";
324 O_flush(Oobject
*self
, PyObject
*args
) {
330 static char O_writelines__doc__
[] = "blah";
332 O_writelines(Oobject
*self
, PyObject
*args
) {
333 PyObject
*string_module
= 0;
334 static PyObject
*string_joinfields
= 0;
336 UNLESS(PyArg_Parse(args
, "O", args
)) {
340 if (!string_joinfields
) {
341 UNLESS(string_module
= PyImport_ImportModule("string")) {
345 UNLESS(string_joinfields
=
346 PyObject_GetAttrString(string_module
, "joinfields")) {
350 Py_DECREF(string_module
);
353 if (PyObject_Length(args
) == -1) {
358 PyObject_CallFunction(string_joinfields
, "Os", args
, ""));
361 static struct PyMethodDef O_methods
[] = {
362 {"write", (PyCFunction
)O_write
, 0, O_write__doc__
},
363 {"read", (PyCFunction
)O_read
, 1, O_read__doc__
},
364 {"readline", (PyCFunction
)O_readline
, 0, O_readline__doc__
},
365 {"reset", (PyCFunction
)O_reset
, 0, O_reset__doc__
},
366 {"seek", (PyCFunction
)O_seek
, 1, O_seek__doc__
},
367 {"tell", (PyCFunction
)O_tell
, 0, O_tell__doc__
},
368 {"getvalue", (PyCFunction
)O_getval
, 1,
369 "getvalue([use_pos]) -- Get the string value."
371 "If use_pos is specified and is a true value, then the string returned\n"
372 "will include only the text up to the current file position.\n"
374 {"truncate", (PyCFunction
)O_truncate
, 0, O_truncate__doc__
},
375 {"isatty", (PyCFunction
)O_isatty
, 0, O_isatty__doc__
},
376 {"close", (PyCFunction
)O_close
, 0, O_close__doc__
},
377 {"flush", (PyCFunction
)O_flush
, 0, O_flush__doc__
},
378 {"writelines", (PyCFunction
)O_writelines
, 0, O_writelines__doc__
},
379 {NULL
, NULL
} /* sentinel */
384 O_dealloc(Oobject
*self
) {
385 if (self
->buf
!= NULL
)
391 O_getattr(Oobject
*self
, char *name
) {
392 if (name
[0] == 's' && strcmp(name
, "softspace") == 0) {
393 return PyInt_FromLong(self
->softspace
);
395 else if (name
[0] == 'c' && strcmp(name
, "closed") == 0) {
396 return PyInt_FromLong(self
->closed
);
398 return Py_FindMethod(O_methods
, (PyObject
*)self
, name
);
402 O_setattr(Oobject
*self
, char *name
, PyObject
*value
) {
404 if (strcmp(name
, "softspace") != 0) {
405 PyErr_SetString(PyExc_AttributeError
, name
);
408 x
= PyInt_AsLong(value
);
409 if (x
== -1 && PyErr_Occurred())
415 static char Otype__doc__
[] =
416 "Simple type for output to strings."
419 static PyTypeObject Otype
= {
420 PyObject_HEAD_INIT(NULL
)
422 "StringO", /*tp_name*/
423 sizeof(Oobject
), /*tp_basicsize*/
426 (destructor
)O_dealloc
, /*tp_dealloc*/
427 (printfunc
)0, /*tp_print*/
428 (getattrfunc
)O_getattr
, /*tp_getattr*/
429 (setattrfunc
)O_setattr
, /*tp_setattr*/
430 (cmpfunc
)0, /*tp_compare*/
431 (reprfunc
)0, /*tp_repr*/
433 0, /*tp_as_sequence*/
435 (hashfunc
)0, /*tp_hash*/
436 (ternaryfunc
)0, /*tp_call*/
437 (reprfunc
)0, /*tp_str*/
439 /* Space for future expansion */
441 Otype__doc__
/* Documentation string */
445 newOobject(int size
) {
448 self
= PyObject_NEW(Oobject
, &Otype
);
453 self
->string_size
= 0;
456 UNLESS(self
->buf
=malloc(size
*sizeof(char))) {
457 PyErr_SetString(PyExc_MemoryError
,"out of memory");
463 return (PyObject
*)self
;
466 /* End of code for StringO objects */
467 /* -------------------------------------------------------- */
470 I_close(Iobject
*self
, PyObject
*args
) {
471 Py_XDECREF(self
->pbuf
);
474 self
->pos
= self
->string_size
= 0;
481 static struct PyMethodDef I_methods
[] = {
482 {"read", (PyCFunction
)O_read
, 1, O_read__doc__
},
483 {"readline", (PyCFunction
)O_readline
, 0, O_readline__doc__
},
484 {"reset", (PyCFunction
)O_reset
, 0, O_reset__doc__
},
485 {"seek", (PyCFunction
)O_seek
, 1, O_seek__doc__
},
486 {"tell", (PyCFunction
)O_tell
, 0, O_tell__doc__
},
487 {"truncate", (PyCFunction
)O_truncate
, 0, O_truncate__doc__
},
488 {"isatty", (PyCFunction
)O_isatty
, 0, O_isatty__doc__
},
489 {"close", (PyCFunction
)I_close
, 0, O_close__doc__
},
490 {"flush", (PyCFunction
)O_flush
, 0, O_flush__doc__
},
491 {NULL
, NULL
} /* sentinel */
495 I_dealloc(Iobject
*self
) {
496 Py_XDECREF(self
->pbuf
);
501 I_getattr(Iobject
*self
, char *name
) {
502 if (name
[0] == 'c' && strcmp(name
,"closed") == 0) {
503 return PyInt_FromLong(self
->closed
);
505 return Py_FindMethod(I_methods
, (PyObject
*)self
, name
);
508 static char Itype__doc__
[] =
509 "Simple type for treating strings as input file streams"
512 static PyTypeObject Itype
= {
513 PyObject_HEAD_INIT(NULL
)
515 "StringI", /*tp_name*/
516 sizeof(Iobject
), /*tp_basicsize*/
519 (destructor
)I_dealloc
, /*tp_dealloc*/
520 (printfunc
)0, /*tp_print*/
521 (getattrfunc
)I_getattr
, /*tp_getattr*/
522 (setattrfunc
)0, /*tp_setattr*/
523 (cmpfunc
)0, /*tp_compare*/
524 (reprfunc
)0, /*tp_repr*/
526 0, /*tp_as_sequence*/
528 (hashfunc
)0, /*tp_hash*/
529 (ternaryfunc
)0, /*tp_call*/
530 (reprfunc
)0, /*tp_str*/
532 /* Space for future expansion */
534 Itype__doc__
/* Documentation string */
538 newIobject(PyObject
*s
) {
543 UNLESS(buf
=PyString_AsString(s
)) return NULL
;
544 UNLESS(-1 != (size
=PyString_Size(s
))) return NULL
;
545 UNLESS(self
= PyObject_NEW(Iobject
, &Itype
)) return NULL
;
548 self
->string_size
=size
;
553 return (PyObject
*)self
;
556 /* End of code for StringI objects */
557 /* -------------------------------------------------------- */
560 static char IO_StringIO__doc__
[] =
561 "StringIO([s]) -- Return a StringIO-like stream for reading or writing"
565 IO_StringIO(PyObject
*self
, PyObject
*args
) {
568 UNLESS(PyArg_ParseTuple(args
, "|S", &s
)) return NULL
;
569 if(s
) return newIobject(s
);
570 return newOobject(128);
573 /* List of methods defined in the module */
575 static struct PyMethodDef IO_methods
[] = {
576 {"StringIO", (PyCFunction
)IO_StringIO
, 1, IO_StringIO__doc__
},
577 {NULL
, NULL
} /* sentinel */
581 /* Initialization function for the module (*must* be called initcStringIO) */
583 static struct PycStringIO_CAPI CAPI
= {
599 /* Create the module and add the functions */
600 m
= Py_InitModule4("cStringIO", IO_methods
,
601 cStringIO_module_documentation
,
602 (PyObject
*)NULL
,PYTHON_API_VERSION
);
604 /* Add some symbolic constants to the module */
605 d
= PyModule_GetDict(m
);
608 Itype
.ob_type
=&PyType_Type
;
609 Otype
.ob_type
=&PyType_Type
;
610 PyDict_SetItemString(d
,"cStringIO_CAPI",
611 v
= PyCObject_FromVoidPtr(&CAPI
,NULL
));
615 PyDict_SetItemString(d
,"InputType", (PyObject
*)&Itype
);
616 PyDict_SetItemString(d
,"OutputType", (PyObject
*)&Otype
);
618 /* Maybe make certain warnings go away */
619 if(0) PycString_IMPORT
;
621 /* Check for errors */
622 if (PyErr_Occurred()) Py_FatalError("can't initialize module cStringIO");