cStringIO.c revision 6819210b9e4e5719a6f7f9c1725f8fa70a8936f6
1
2#include "Python.h"
3#include "import.h"
4#include "cStringIO.h"
5#include "structmember.h"
6
7PyDoc_STRVAR(cStringIO_module_documentation,
8"A simple fast partial StringIO replacement.\n"
9"\n"
10"This module provides a simple useful replacement for\n"
11"the StringIO module that is written in C.  It does not provide the\n"
12"full generality of StringIO, but it provides enough for most\n"
13"applications and is especially useful in conjunction with the\n"
14"pickle module.\n"
15"\n"
16"Usage:\n"
17"\n"
18"  from cStringIO import StringIO\n"
19"\n"
20"  an_output_stream=StringIO()\n"
21"  an_output_stream.write(some_stuff)\n"
22"  ...\n"
23"  value=an_output_stream.getvalue()\n"
24"\n"
25"  an_input_stream=StringIO(a_string)\n"
26"  spam=an_input_stream.readline()\n"
27"  spam=an_input_stream.read(5)\n"
28"  an_input_stream.seek(0)           # OK, start over\n"
29"  spam=an_input_stream.read()       # and read it all\n"
30"  \n"
31"If someone else wants to provide a more complete implementation,\n"
32"go for it. :-)  \n"
33"\n"
34"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
35
36/* Declaration for file-like objects that manage data as strings
37
38   The IOobject type should be though of as a common base type for
39   Iobjects, which provide input (read-only) StringIO objects and
40   Oobjects, which provide read-write objects.  Most of the methods
41   depend only on common data.
42*/
43
44typedef struct {
45  PyObject_HEAD
46  char *buf;
47  Py_ssize_t pos, string_size;
48} IOobject;
49
50#define IOOOBJECT(O) ((IOobject*)(O))
51
52/* Declarations for objects of type StringO */
53
54typedef struct { /* Subtype of IOobject */
55  PyObject_HEAD
56  char *buf;
57  Py_ssize_t pos, string_size;
58
59  Py_ssize_t buf_size;
60  int softspace;
61} Oobject;
62
63/* Declarations for objects of type StringI */
64
65typedef struct { /* Subtype of IOobject */
66  PyObject_HEAD
67  char *buf;
68  Py_ssize_t pos, string_size;
69  /* We store a reference to the object here in order to keep
70     the buffer alive during the lifetime of the Iobject. */
71  PyObject *pbuf;
72} Iobject;
73
74/* IOobject (common) methods */
75
76PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
77
78static int
79IO__opencheck(IOobject *self) {
80        if (!self->buf) {
81                PyErr_SetString(PyExc_ValueError,
82                                "I/O operation on closed file");
83                return 0;
84        }
85        return 1;
86}
87
88static PyObject *
89IO_get_closed(IOobject *self, void *closure)
90{
91	PyObject *result = Py_False;
92
93	if (self->buf == NULL)
94		result = Py_True;
95	Py_INCREF(result);
96	return result;
97}
98
99static PyGetSetDef file_getsetlist[] = {
100	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
101	{0},
102};
103
104static PyObject *
105IO_flush(IOobject *self, PyObject *unused) {
106
107        if (!IO__opencheck(self)) return NULL;
108
109        Py_INCREF(Py_None);
110        return Py_None;
111}
112
113PyDoc_STRVAR(IO_getval__doc__,
114"getvalue([use_pos]) -- Get the string value."
115"\n"
116"If use_pos is specified and is a true value, then the string returned\n"
117"will include only the text up to the current file position.\n");
118
119static PyObject *
120IO_cgetval(PyObject *self) {
121        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
122        return PyString_FromStringAndSize(((IOobject*)self)->buf,
123                                          ((IOobject*)self)->pos);
124}
125
126static PyObject *
127IO_getval(IOobject *self, PyObject *args) {
128        PyObject *use_pos=Py_None;
129        Py_ssize_t s;
130
131        if (!IO__opencheck(self)) return NULL;
132        if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
133
134        if (PyObject_IsTrue(use_pos)) {
135                  s=self->pos;
136                  if (s > self->string_size) s=self->string_size;
137        }
138        else
139                  s=self->string_size;
140        return PyString_FromStringAndSize(self->buf, s);
141}
142
143PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
144
145static PyObject *
146IO_isatty(IOobject *self, PyObject *unused) {
147        if (!IO__opencheck(self)) return NULL;
148        Py_INCREF(Py_False);
149        return Py_False;
150}
151
152PyDoc_STRVAR(IO_read__doc__,
153"read([s]) -- Read s characters, or the rest of the string");
154
155static int
156IO_cread(PyObject *self, char **output, Py_ssize_t  n) {
157        Py_ssize_t l;
158
159        if (!IO__opencheck(IOOOBJECT(self))) return -1;
160        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
161        if (n < 0 || n > l) {
162                n = l;
163                if (n < 0) n=0;
164        }
165
166        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
167        ((IOobject*)self)->pos += n;
168        return n;
169}
170
171static PyObject *
172IO_read(IOobject *self, PyObject *args) {
173        Py_ssize_t n = -1;
174        char *output = NULL;
175
176        if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
177
178        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
179
180        return PyString_FromStringAndSize(output, n);
181}
182
183PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
184
185static int
186IO_creadline(PyObject *self, char **output) {
187        char *n, *s;
188        Py_ssize_t l;
189
190        if (!IO__opencheck(IOOOBJECT(self))) return -1;
191
192        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
193               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
194             n < s && *n != '\n'; n++);
195        if (n < s) n++;
196
197        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
198        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
199	assert(((IOobject*)self)->pos + l < INT_MAX);
200        ((IOobject*)self)->pos += (int)l;
201        return (int)l;
202}
203
204static PyObject *
205IO_readline(IOobject *self, PyObject *args) {
206        int n, m=-1;
207        char *output;
208
209        if (args)
210                if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
211
212        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
213        if (m >= 0 && m < n) {
214                m = n - m;
215                n -= m;
216                self->pos -= m;
217        }
218        return PyString_FromStringAndSize(output, n);
219}
220
221PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
222
223static PyObject *
224IO_readlines(IOobject *self, PyObject *args) {
225	int n;
226	char *output;
227	PyObject *result, *line;
228        int hint = 0, length = 0;
229
230        if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
231
232	result = PyList_New(0);
233	if (!result)
234		return NULL;
235
236	while (1){
237		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
238                        goto err;
239		if (n == 0)
240			break;
241		line = PyString_FromStringAndSize (output, n);
242		if (!line)
243                        goto err;
244		if (PyList_Append (result, line) == -1) {
245			Py_DECREF (line);
246			goto err;
247		}
248		Py_DECREF (line);
249                length += n;
250                if (hint > 0 && length >= hint)
251			break;
252	}
253	return result;
254 err:
255        Py_DECREF(result);
256        return NULL;
257}
258
259PyDoc_STRVAR(IO_reset__doc__,
260"reset() -- Reset the file position to the beginning");
261
262static PyObject *
263IO_reset(IOobject *self, PyObject *unused) {
264
265        if (!IO__opencheck(self)) return NULL;
266
267        self->pos = 0;
268
269        Py_INCREF(Py_None);
270        return Py_None;
271}
272
273PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
274
275static PyObject *
276IO_tell(IOobject *self, PyObject *unused) {
277
278        if (!IO__opencheck(self)) return NULL;
279
280        return PyInt_FromSsize_t(self->pos);
281}
282
283PyDoc_STRVAR(IO_truncate__doc__,
284"truncate(): truncate the file at the current position.");
285
286static PyObject *
287IO_truncate(IOobject *self, PyObject *args) {
288        Py_ssize_t pos = -1;
289
290        if (!IO__opencheck(self)) return NULL;
291        if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
292
293	if (PyTuple_Size(args) == 0) {
294		/* No argument passed, truncate to current position */
295		pos = self->pos;
296	}
297
298        if (pos < 0) {
299		errno = EINVAL;
300		PyErr_SetFromErrno(PyExc_IOError);
301		return NULL;
302	}
303
304        if (self->string_size > pos) self->string_size = pos;
305        self->pos = self->string_size;
306
307        Py_INCREF(Py_None);
308        return Py_None;
309}
310
311static PyObject *
312IO_iternext(Iobject *self)
313{
314	PyObject *next;
315	next = IO_readline((IOobject *)self, NULL);
316	if (!next)
317		return NULL;
318	if (!PyString_GET_SIZE(next)) {
319		Py_DECREF(next);
320		PyErr_SetNone(PyExc_StopIteration);
321		return NULL;
322	}
323	return next;
324}
325
326
327
328
329/* Read-write object methods */
330
331PyDoc_STRVAR(O_seek__doc__,
332"seek(position)       -- set the current position\n"
333"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
334
335static PyObject *
336O_seek(Oobject *self, PyObject *args) {
337	Py_ssize_t position;
338	int mode = 0;
339
340        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
341        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
342                return NULL;
343
344        if (mode == 2) {
345                position += self->string_size;
346        }
347        else if (mode == 1) {
348                position += self->pos;
349        }
350
351        if (position > self->buf_size) {
352                  char *newbuf;
353                  self->buf_size*=2;
354                  if (self->buf_size <= position) self->buf_size=position+1;
355		  newbuf = (char*) realloc(self->buf,self->buf_size);
356                  if (!newbuf) {
357                      free(self->buf);
358                      self->buf = 0;
359                      self->buf_size=self->pos=0;
360                      return PyErr_NoMemory();
361                    }
362                  self->buf = newbuf;
363          }
364        else if (position < 0) position=0;
365
366        self->pos=position;
367
368        while (--position >= self->string_size) self->buf[position]=0;
369
370        Py_INCREF(Py_None);
371        return Py_None;
372}
373
374PyDoc_STRVAR(O_write__doc__,
375"write(s) -- Write a string to the file"
376"\n\nNote (hack:) writing None resets the buffer");
377
378
379static int
380O_cwrite(PyObject *self, const char *c, Py_ssize_t  l) {
381        Py_ssize_t newl;
382        Oobject *oself;
383        char *newbuf;
384
385        if (!IO__opencheck(IOOOBJECT(self))) return -1;
386        oself = (Oobject *)self;
387
388        newl = oself->pos+l;
389        if (newl >= oself->buf_size) {
390            oself->buf_size *= 2;
391            if (oself->buf_size <= newl) {
392		    assert(newl + 1 < INT_MAX);
393                    oself->buf_size = (int)(newl+1);
394	    }
395            newbuf = (char*)realloc(oself->buf, oself->buf_size);
396	    if (!newbuf) {
397                    PyErr_SetString(PyExc_MemoryError,"out of memory");
398                    free(oself->buf);
399                    oself->buf = 0;
400                    oself->buf_size = oself->pos = 0;
401                    return -1;
402              }
403            oself->buf = newbuf;
404          }
405
406        memcpy(oself->buf+oself->pos,c,l);
407
408	assert(oself->pos + l < INT_MAX);
409        oself->pos += (int)l;
410
411        if (oself->string_size < oself->pos) {
412            oself->string_size = oself->pos;
413        }
414
415        return (int)l;
416}
417
418static PyObject *
419O_write(Oobject *self, PyObject *args) {
420        char *c;
421        int l;
422
423        if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
424
425        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
426
427        Py_INCREF(Py_None);
428        return Py_None;
429}
430
431PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
432
433static PyObject *
434O_close(Oobject *self, PyObject *unused) {
435        if (self->buf != NULL) free(self->buf);
436        self->buf = NULL;
437
438        self->pos = self->string_size = self->buf_size = 0;
439
440        Py_INCREF(Py_None);
441        return Py_None;
442}
443
444PyDoc_STRVAR(O_writelines__doc__,
445"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
446"\n"
447"Note that newlines are not added.  The sequence can be any iterable object\n"
448"producing strings. This is equivalent to calling write() for each string.");
449static PyObject *
450O_writelines(Oobject *self, PyObject *args) {
451	PyObject *it, *s;
452
453	it = PyObject_GetIter(args);
454	if (it == NULL)
455		return NULL;
456	while ((s = PyIter_Next(it)) != NULL) {
457		Py_ssize_t n;
458		char *c;
459		if (PyString_AsStringAndSize(s, &c, &n) == -1) {
460			Py_DECREF(it);
461			Py_DECREF(s);
462			return NULL;
463		}
464		if (O_cwrite((PyObject *)self, c, n) == -1) {
465			Py_DECREF(it);
466			Py_DECREF(s);
467			return NULL;
468               }
469               Py_DECREF(s);
470       }
471
472       Py_DECREF(it);
473
474       /* See if PyIter_Next failed */
475       if (PyErr_Occurred())
476               return NULL;
477
478       Py_RETURN_NONE;
479}
480static struct PyMethodDef O_methods[] = {
481  /* Common methods: */
482  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
483  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
484  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
485  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
486  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
487  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
488  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
489  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
490  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
491
492  /* Read-write StringIO specific  methods: */
493  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
494  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
495  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
496  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
497  {NULL,	 NULL}		/* sentinel */
498};
499
500static PyMemberDef O_memberlist[] = {
501	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
502	 "flag indicating that a space needs to be printed; used by print"},
503	 /* getattr(f, "closed") is implemented without this table */
504	{NULL} /* Sentinel */
505};
506
507static void
508O_dealloc(Oobject *self) {
509        if (self->buf != NULL)
510                free(self->buf);
511        PyObject_Del(self);
512}
513
514PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
515
516static PyTypeObject Otype = {
517  PyVarObject_HEAD_INIT(NULL, 0)
518  "cStringIO.StringO",   	/*tp_name*/
519  sizeof(Oobject),       	/*tp_basicsize*/
520  0,	       			/*tp_itemsize*/
521  /* methods */
522  (destructor)O_dealloc,	/*tp_dealloc*/
523  0,				/*tp_print*/
524  0,		 		/*tp_getattr */
525  0,		 		/*tp_setattr */
526  0,				/*tp_compare*/
527  0,				/*tp_repr*/
528  0,				/*tp_as_number*/
529  0,				/*tp_as_sequence*/
530  0,				/*tp_as_mapping*/
531  0,				/*tp_hash*/
532  0	,			/*tp_call*/
533  0,				/*tp_str*/
534  0,				/*tp_getattro */
535  0,				/*tp_setattro */
536  0,				/*tp_as_buffer */
537  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
538  Otype__doc__, 		/*tp_doc */
539  0,				/*tp_traverse */
540  0,				/*tp_clear */
541  0,				/*tp_richcompare */
542  0,				/*tp_weaklistoffset */
543  PyObject_SelfIter,		/*tp_iter */
544  (iternextfunc)IO_iternext,	/*tp_iternext */
545  O_methods,			/*tp_methods */
546  O_memberlist,			/*tp_members */
547  file_getsetlist,		/*tp_getset */
548};
549
550static PyObject *
551newOobject(int  size) {
552        Oobject *self;
553
554        self = PyObject_New(Oobject, &Otype);
555        if (self == NULL)
556                return NULL;
557        self->pos=0;
558        self->string_size = 0;
559        self->softspace = 0;
560
561        self->buf = (char *)malloc(size);
562	if (!self->buf) {
563                  PyErr_SetString(PyExc_MemoryError,"out of memory");
564                  self->buf_size = 0;
565                  Py_DECREF(self);
566                  return NULL;
567          }
568
569        self->buf_size=size;
570        return (PyObject*)self;
571}
572
573/* End of code for StringO objects */
574/* -------------------------------------------------------- */
575
576static PyObject *
577I_close(Iobject *self, PyObject *unused) {
578        Py_XDECREF(self->pbuf);
579        self->pbuf = NULL;
580        self->buf = NULL;
581
582        self->pos = self->string_size = 0;
583
584        Py_INCREF(Py_None);
585        return Py_None;
586}
587
588static PyObject *
589I_seek(Iobject *self, PyObject *args) {
590        Py_ssize_t position;
591	int mode = 0;
592
593        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
594        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
595                return NULL;
596
597        if (mode == 2) position += self->string_size;
598        else if (mode == 1) position += self->pos;
599
600        if (position < 0) position=0;
601
602        self->pos=position;
603
604        Py_INCREF(Py_None);
605        return Py_None;
606}
607
608static struct PyMethodDef I_methods[] = {
609  /* Common methods: */
610  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
611  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
612  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
613  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
614  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
615  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
616  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
617  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
618  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
619
620  /* Read-only StringIO specific  methods: */
621  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
622  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},
623  {NULL,	NULL}
624};
625
626static void
627I_dealloc(Iobject *self) {
628  Py_XDECREF(self->pbuf);
629  PyObject_Del(self);
630}
631
632
633PyDoc_STRVAR(Itype__doc__,
634"Simple type for treating strings as input file streams");
635
636static PyTypeObject Itype = {
637  PyVarObject_HEAD_INIT(NULL, 0)
638  "cStringIO.StringI",			/*tp_name*/
639  sizeof(Iobject),			/*tp_basicsize*/
640  0,					/*tp_itemsize*/
641  /* methods */
642  (destructor)I_dealloc,		/*tp_dealloc*/
643  0,					/*tp_print*/
644  0,		 			/* tp_getattr */
645  0,					/*tp_setattr*/
646  0,					/*tp_compare*/
647  0,					/*tp_repr*/
648  0,					/*tp_as_number*/
649  0,					/*tp_as_sequence*/
650  0,					/*tp_as_mapping*/
651  0,					/*tp_hash*/
652  0,					/*tp_call*/
653  0,					/*tp_str*/
654  0,					/* tp_getattro */
655  0,					/* tp_setattro */
656  0,					/* tp_as_buffer */
657  Py_TPFLAGS_DEFAULT,			/* tp_flags */
658  Itype__doc__,				/* tp_doc */
659  0,					/* tp_traverse */
660  0,					/* tp_clear */
661  0,					/* tp_richcompare */
662  0,					/* tp_weaklistoffset */
663  PyObject_SelfIter,			/* tp_iter */
664  (iternextfunc)IO_iternext,		/* tp_iternext */
665  I_methods,				/* tp_methods */
666  0,					/* tp_members */
667  file_getsetlist,			/* tp_getset */
668};
669
670static PyObject *
671newIobject(PyObject *s) {
672  Iobject *self;
673  char *buf;
674  Py_ssize_t size;
675
676  if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
677      return NULL;
678
679  self = PyObject_New(Iobject, &Itype);
680  if (!self) return NULL;
681  Py_INCREF(s);
682  self->buf=buf;
683  self->string_size=size;
684  self->pbuf=s;
685  self->pos=0;
686
687  return (PyObject*)self;
688}
689
690/* End of code for StringI objects */
691/* -------------------------------------------------------- */
692
693
694PyDoc_STRVAR(IO_StringIO__doc__,
695"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
696
697static PyObject *
698IO_StringIO(PyObject *self, PyObject *args) {
699  PyObject *s=0;
700
701  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
702
703  if (s) return newIobject(s);
704  return newOobject(128);
705}
706
707/* List of methods defined in the module */
708
709static struct PyMethodDef IO_methods[] = {
710  {"StringIO",	(PyCFunction)IO_StringIO,
711   METH_VARARGS,	IO_StringIO__doc__},
712  {NULL,		NULL}		/* sentinel */
713};
714
715
716/* Initialization function for the module (*must* be called initcStringIO) */
717
718static struct PycStringIO_CAPI CAPI = {
719  IO_cread,
720  IO_creadline,
721  O_cwrite,
722  IO_cgetval,
723  newOobject,
724  newIobject,
725  &Itype,
726  &Otype,
727};
728
729#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
730#define PyMODINIT_FUNC void
731#endif
732PyMODINIT_FUNC
733initcStringIO(void) {
734  PyObject *m, *d, *v;
735
736
737  /* Create the module and add the functions */
738  m = Py_InitModule4("cStringIO", IO_methods,
739		     cStringIO_module_documentation,
740		     (PyObject*)NULL,PYTHON_API_VERSION);
741  if (m == NULL) return;
742
743  /* Add some symbolic constants to the module */
744  d = PyModule_GetDict(m);
745
746  /* Export C API */
747  Py_Type(&Itype)=&PyType_Type;
748  Py_Type(&Otype)=&PyType_Type;
749  if (PyType_Ready(&Otype) < 0) return;
750  if (PyType_Ready(&Itype) < 0) return;
751  PyDict_SetItemString(d,"cStringIO_CAPI",
752		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
753  Py_XDECREF(v);
754
755  /* Export Types */
756  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
757  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
758
759  /* Maybe make certain warnings go away */
760  if (0) PycString_IMPORT;
761}
762