Bump version to 0.9.1.
[python/dscho.git] / Modules / cStringIO.c
blob749ebcb4d90506aca7c001e6ac4b21cc0c84201a
1 /*
2 * cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp
3 *
4 * Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
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
17 * distribution.
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
41 * DAMAGE.
44 # If you have questions regarding this software, contact:
46 # Digital Creations, L.C.
47 # 910 Princess Ann Street
48 # Fredericksburge, Virginia 22401
50 # info@digicool.com
52 # (540) 371-6909
54 static char cStringIO_module_documentation[] =
55 "A simple fast partial StringIO replacement.\n"
56 "\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"
61 "pickle module.\n"
62 "\n"
63 "Usage:\n"
64 "\n"
65 " from cStringIO import StringIO\n"
66 "\n"
67 " an_output_stream=StringIO()\n"
68 " an_output_stream.write(some_stuff)\n"
69 " ...\n"
70 " value=an_output_stream.getvalue() # str(an_output_stream) works too!\n"
71 "\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"
77 " \n"
78 "If someone else wants to provide a more complete implementation,\n"
79 "go for it. :-) \n"
80 "\n"
81 "cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n"
84 #include "Python.h"
85 #include "import.h"
86 #include "cStringIO.h"
88 #define UNLESS(E) if(!(E))
90 /* Declarations for objects of type StringO */
92 typedef struct {
93 PyObject_HEAD
94 char *buf;
95 int pos, string_size, buf_size, softspace;
96 } Oobject;
98 /* Declarations for objects of type StringI */
100 typedef struct {
101 PyObject_HEAD
102 char *buf;
103 int pos, string_size;
104 PyObject *pbuf;
105 } Iobject;
107 static char O_reset__doc__[] =
108 "reset() -- Reset the file position to the beginning"
111 static PyObject *
112 O_reset(Oobject *self, PyObject *args) {
113 self->pos = 0;
115 Py_INCREF(Py_None);
116 return Py_None;
120 static char O_tell__doc__[] =
121 "tell() -- get the current position.";
123 static PyObject *
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";
133 static PyObject *
134 O_seek(Oobject *self, PyObject *args) {
135 int position, mode = 0;
137 UNLESS(PyArg_ParseTuple(args, "i|i:seek", &position, &mode)) {
138 return NULL;
141 if (mode == 2) {
142 position += self->string_size;
144 else if (mode == 1) {
145 position += self->pos;
148 if (position > self->buf_size) {
149 self->buf_size*=2;
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;
158 self->pos=position;
160 while(--position >= self->string_size) self->buf[position]=0;
162 Py_INCREF(Py_None);
163 return Py_None;
166 static char O_read__doc__[] =
167 "read([s]) -- Read s characters, or the rest of the string"
170 static int
171 O_cread(PyObject *self, char **output, int n) {
172 int l;
174 l = ((Oobject*)self)->string_size - ((Oobject*)self)->pos;
175 if (n < 0 || n > l) {
176 n = l;
177 if (n < 0) n=0;
180 *output=((Oobject*)self)->buf + ((Oobject*)self)->pos;
181 ((Oobject*)self)->pos += n;
182 return n;
185 static PyObject *
186 O_read(Oobject *self, PyObject *args) {
187 int n = -1;
188 char *output;
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"
202 static int
203 O_creadline(PyObject *self, char **output) {
204 char *n, *s;
205 int l;
207 for (n = ((Oobject*)self)->buf + ((Oobject*)self)->pos,
208 s = ((Oobject*)self)->buf + ((Oobject*)self)->string_size;
209 n < s && *n != '\n'; n++);
210 if (n < s) n++;
212 *output=((Oobject*)self)->buf + ((Oobject*)self)->pos;
213 l = n - ((Oobject*)self)->buf - ((Oobject*)self)->pos;
214 ((Oobject*)self)->pos += l;
215 return l;
218 static PyObject *
219 O_readline(Oobject *self, PyObject *args) {
220 int n;
221 char *output;
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"
233 static int
234 O_cwrite(PyObject *self, char *c, int l) {
235 int newl;
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;
246 return -1;
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;
258 return l;
261 static PyObject *
262 O_write(Oobject *self, PyObject *args) {
263 PyObject *s;
264 char *c;
265 int l;
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;
272 Py_INCREF(Py_None);
273 return Py_None;
276 static char O_getval__doc__[] =
277 "getvalue([use_pos]) -- Get the string value."
278 "\n"
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"
283 static PyObject *
284 O_getval(Oobject *self, PyObject *args) {
285 PyObject *use_pos=Py_None;
286 int s;
288 use_pos=Py_None;
289 UNLESS(PyArg_ParseTuple(args,"|O:getval",&use_pos)) return NULL;
290 if(PyObject_IsTrue(use_pos)) {
291 s=self->pos;
292 if (s > self->string_size) s=self->string_size;
294 else
295 s=self->string_size;
296 return PyString_FromStringAndSize(self->buf, s);
299 static PyObject *
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.";
308 static PyObject *
309 O_truncate(Oobject *self, PyObject *args) {
310 if (self->string_size > self->pos)
311 self->string_size = self->pos;
312 Py_INCREF(Py_None);
313 return Py_None;
316 static char O_isatty__doc__[] = "isatty(): always returns 0";
318 static PyObject *
319 O_isatty(Oobject *self, PyObject *args) {
320 return PyInt_FromLong(0);
323 static char O_close__doc__[] = "close(): explicitly release resources held.";
325 static PyObject *
326 O_close(Oobject *self, PyObject *args) {
327 if (self->buf != NULL)
328 free(self->buf);
329 self->buf = NULL;
331 self->pos = self->string_size = self->buf_size = 0;
333 Py_INCREF(Py_None);
334 return Py_None;
337 static char O_flush__doc__[] = "flush(): does nothing.";
339 static PyObject *
340 O_flush(Oobject *self, PyObject *args) {
341 Py_INCREF(Py_None);
342 return Py_None;
346 static char O_writelines__doc__[] =
347 "writelines(sequence_of_strings): write each string";
348 static PyObject *
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)) {
354 return NULL;
357 if (!string_joinfields) {
358 UNLESS(string_module = PyImport_ImportModule("string")) {
359 return NULL;
362 UNLESS(string_joinfields=
363 PyObject_GetAttrString(string_module, "joinfields")) {
364 return NULL;
367 Py_DECREF(string_module);
370 if (PyObject_Size(args) == -1) {
371 return NULL;
375 PyObject *x = PyObject_CallFunction(string_joinfields,
376 "Os", args, "");
377 if (x == NULL)
378 return NULL;
379 args = Py_BuildValue("(O)", x);
380 Py_DECREF(x);
381 if (args == NULL)
382 return NULL;
383 x = O_write(self, args);
384 Py_DECREF(args);
385 return x;
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 */
406 static void
407 O_dealloc(Oobject *self) {
408 if (self->buf != NULL)
409 free(self->buf);
410 PyObject_Del(self);
413 static PyObject *
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);
421 static int
422 O_setattr(Oobject *self, char *name, PyObject *value) {
423 long x;
424 if (strcmp(name, "softspace") != 0) {
425 PyErr_SetString(PyExc_AttributeError, name);
426 return -1;
428 x = PyInt_AsLong(value);
429 if (x == -1 && PyErr_Occurred())
430 return -1;
431 self->softspace = x;
432 return 0;
435 static char Otype__doc__[] =
436 "Simple type for output to strings."
439 static PyTypeObject Otype = {
440 PyObject_HEAD_INIT(NULL)
441 0, /*ob_size*/
442 "StringO", /*tp_name*/
443 sizeof(Oobject), /*tp_basicsize*/
444 0, /*tp_itemsize*/
445 /* methods */
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*/
452 0, /*tp_as_number*/
453 0, /*tp_as_sequence*/
454 0, /*tp_as_mapping*/
455 (hashfunc)0, /*tp_hash*/
456 (ternaryfunc)0, /*tp_call*/
457 (reprfunc)0, /*tp_str*/
459 /* Space for future expansion */
460 0L,0L,0L,0L,
461 Otype__doc__ /* Documentation string */
464 static PyObject *
465 newOobject(int size) {
466 Oobject *self;
468 self = PyObject_New(Oobject, &Otype);
469 if (self == NULL)
470 return NULL;
471 self->pos=0;
472 self->string_size = 0;
473 self->softspace = 0;
475 UNLESS(self->buf=malloc(size*sizeof(char))) {
476 PyErr_SetString(PyExc_MemoryError,"out of memory");
477 self->buf_size = 0;
478 return NULL;
481 self->buf_size=size;
482 return (PyObject*)self;
485 /* End of code for StringO objects */
486 /* -------------------------------------------------------- */
488 static PyObject *
489 I_close(Iobject *self, PyObject *args) {
490 Py_XDECREF(self->pbuf);
491 self->pbuf = NULL;
493 self->pos = self->string_size = 0;
495 Py_INCREF(Py_None);
496 return Py_None;
499 static PyObject *
500 I_seek(Oobject *self, PyObject *args) {
501 int position, mode = 0;
503 UNLESS(PyArg_ParseTuple(args, "i|i:seek", &position, &mode)) {
504 return NULL;
507 if (mode == 2) {
508 position += self->string_size;
510 else if (mode == 1) {
511 position += self->pos;
514 if(position < 0) position=0;
516 self->pos=position;
518 Py_INCREF(Py_None);
519 return Py_None;
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__},
533 {NULL, NULL}
536 static void
537 I_dealloc(Iobject *self) {
538 Py_XDECREF(self->pbuf);
539 PyObject_Del(self);
542 static PyObject *
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)
553 0, /*ob_size*/
554 "StringI", /*tp_name*/
555 sizeof(Iobject), /*tp_basicsize*/
556 0, /*tp_itemsize*/
557 /* methods */
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*/
564 0, /*tp_as_number*/
565 0, /*tp_as_sequence*/
566 0, /*tp_as_mapping*/
567 (hashfunc)0, /*tp_hash*/
568 (ternaryfunc)0, /*tp_call*/
569 (reprfunc)0, /*tp_str*/
571 /* Space for future expansion */
572 0L,0L,0L,0L,
573 Itype__doc__ /* Documentation string */
576 static PyObject *
577 newIobject(PyObject *s) {
578 Iobject *self;
579 char *buf;
580 int size;
582 if (!PyString_Check(s)) {
583 PyErr_Format(PyExc_TypeError, "expected string, %.200s found",
584 s->ob_type->tp_name);
585 return NULL;
587 buf = PyString_AS_STRING(s);
588 size = PyString_GET_SIZE(s);
589 UNLESS(self = PyObject_New(Iobject, &Itype)) return NULL;
590 Py_INCREF(s);
591 self->buf=buf;
592 self->string_size=size;
593 self->pbuf=s;
594 self->pos=0;
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"
607 static PyObject *
608 IO_StringIO(PyObject *self, PyObject *args) {
609 PyObject *s=0;
611 if (!PyArg_ParseTuple(args, "|O:StringIO", &s))
612 return NULL;
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 = {
629 O_cread,
630 O_creadline,
631 O_cwrite,
632 O_cgetval,
633 newOobject,
634 newIobject,
635 &Itype,
636 &Otype,
639 #ifndef DL_EXPORT /* declarations for DLL import/export */
640 #define DL_EXPORT(RTYPE) RTYPE
641 #endif
642 DL_EXPORT(void)
643 initcStringIO(void) {
644 PyObject *m, *d, *v;
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);
655 /* Export C API */
656 Itype.ob_type=&PyType_Type;
657 Otype.ob_type=&PyType_Type;
658 PyDict_SetItemString(d,"cStringIO_CAPI",
659 v = PyCObject_FromVoidPtr(&CAPI,NULL));
660 Py_XDECREF(v);
662 /* Export Types */
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;