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