1 
2 #include "Python.h"
3 #include "import.h"
4 #include "cStringIO.h"
5 #include "structmember.h"
6 
7 PyDoc_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 
44 typedef 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 
54 typedef 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 
65 typedef 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 
74 PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
75 
76 static int
IO__opencheck(IOobject * self)77 IO__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 
86 static PyObject *
IO_get_closed(IOobject * self,void * closure)87 IO_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 
97 static PyGetSetDef file_getsetlist[] = {
98     {"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
99     {0},
100 };
101 
102 static PyObject *
IO_flush(IOobject * self,PyObject * unused)103 IO_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 
111 PyDoc_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 
117 static PyObject *
IO_cgetval(PyObject * self)118 IO_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 
125 static PyObject *
IO_getval(IOobject * self,PyObject * args)126 IO_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 
147 PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
148 
149 static PyObject *
IO_isatty(IOobject * self,PyObject * unused)150 IO_isatty(IOobject *self, PyObject *unused) {
151     if (!IO__opencheck(self)) return NULL;
152     Py_INCREF(Py_False);
153     return Py_False;
154 }
155 
156 PyDoc_STRVAR(IO_read__doc__,
157 "read([s]) -- Read s characters, or the rest of the string");
158 
159 static int
IO_cread(PyObject * self,char ** output,Py_ssize_t n)160 IO_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 
182 static PyObject *
IO_read(IOobject * self,PyObject * args)183 IO_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 
194 PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
195 
196 static int
IO_creadline(PyObject * self,char ** output)197 IO_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 
224 static PyObject *
IO_readline(IOobject * self,PyObject * args)225 IO_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 
242 PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
243 
244 static PyObject *
IO_readlines(IOobject * self,PyObject * args)245 IO_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 
280 PyDoc_STRVAR(IO_reset__doc__,
281 "reset() -- Reset the file position to the beginning");
282 
283 static PyObject *
IO_reset(IOobject * self,PyObject * unused)284 IO_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 
294 PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
295 
296 static PyObject *
IO_tell(IOobject * self,PyObject * unused)297 IO_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 
305 PyDoc_STRVAR(IO_truncate__doc__,
306 "truncate(): truncate the file at the current position.");
307 
308 static PyObject *
IO_truncate(IOobject * self,PyObject * args)309 IO_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 
333 static PyObject *
IO_iternext(Iobject * self)334 IO_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 
353 PyDoc_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 
357 static PyObject *
IO_seek(Iobject * self,PyObject * args)358 IO_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 
381 PyDoc_STRVAR(O_write__doc__,
382 "write(s) -- Write a string to the file"
383 "\n\nNote (hack:) writing None resets the buffer");
384 
385 
386 static int
O_cwrite(PyObject * self,const char * c,Py_ssize_t len)387 O_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 
447 static PyObject *
O_write(Oobject * self,PyObject * args)448 O_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 
462 PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
463 
464 static PyObject *
O_close(Oobject * self,PyObject * unused)465 O_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 
475 PyDoc_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.");
480 static PyObject *
O_writelines(Oobject * self,PyObject * args)481 O_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 }
511 static 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 
531 static 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 
538 static void
O_dealloc(Oobject * self)539 O_dealloc(Oobject *self) {
540     if (self->buf != NULL)
541         free(self->buf);
542     PyObject_Del(self);
543 }
544 
545 PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
546 
547 static 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 
581 static PyObject *
newOobject(int size)582 newOobject(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 
607 static PyObject *
I_close(Iobject * self,PyObject * unused)608 I_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 
618 static 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 
636 static void
I_dealloc(Iobject * self)637 I_dealloc(Iobject *self) {
638   PyBuffer_Release(&self->pbuf);
639   PyObject_Del(self);
640 }
641 
642 
643 PyDoc_STRVAR(Itype__doc__,
644 "Simple type for treating strings as input file streams");
645 
646 static 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 
680 static PyObject *
newIobject(PyObject * s)681 newIobject(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 
712 PyDoc_STRVAR(IO_StringIO__doc__,
713 "StringIO([s]) -- Return a StringIO-like stream for reading or writing");
714 
715 static PyObject *
IO_StringIO(PyObject * self,PyObject * args)716 IO_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 
727 static 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 
736 static 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
750 PyMODINIT_FUNC
initcStringIO(void)751 initcStringIO(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