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