PageRenderTime 43ms CodeModel.GetById 2ms app.highlight 35ms RepoModel.GetById 1ms app.codeStats 0ms

/Modules/cStringIO.c

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