cStringIO.c 20.3 KB
Newer Older
1 2 3 4

#include "Python.h"
#include "import.h"
#include "cStringIO.h"
5
#include "structmember.h"
6 7

PyDoc_STRVAR(cStringIO_module_documentation,
Guido van Rossum's avatar
Guido van Rossum committed
8 9 10 11
"A simple fast partial StringIO replacement.\n"
"\n"
"This module provides a simple useful replacement for\n"
"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"
Guido van Rossum's avatar
Guido van Rossum committed
14 15 16 17 18 19 20 21 22
"pickle module.\n"
"\n"
"Usage:\n"
"\n"
"  from cStringIO import StringIO\n"
"\n"
"  an_output_stream=StringIO()\n"
"  an_output_stream.write(some_stuff)\n"
"  ...\n"
Jeremy Hylton's avatar
Jeremy Hylton committed
23
"  value=an_output_stream.getvalue()\n"
Guido van Rossum's avatar
Guido van Rossum committed
24 25 26 27
"\n"
"  an_input_stream=StringIO(a_string)\n"
"  spam=an_input_stream.readline()\n"
"  spam=an_input_stream.read(5)\n"
28
"  an_input_stream.seek(0)           # OK, start over\n"
Guido van Rossum's avatar
Guido van Rossum committed
29 30 31 32
"  spam=an_input_stream.read()       # and read it all\n"
"  \n"
"If someone else wants to provide a more complete implementation,\n"
"go for it. :-)  \n"
33
"\n"
34
"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
Guido van Rossum's avatar
Guido van Rossum committed
35

36 37 38 39 40 41 42
/* Declaration for file-like objects that manage data as strings 

   The IOobject type should be though of as a common base type for
   Iobjects, which provide input (read-only) StringIO objects and
   Oobjects, which provide read-write objects.  Most of the methods
   depend only on common data.
*/
Guido van Rossum's avatar
Guido van Rossum committed
43 44 45 46

typedef struct {
  PyObject_HEAD
  char *buf;
Martin v. Löwis's avatar
Martin v. Löwis committed
47
  Py_ssize_t pos, string_size;
48 49 50 51
} IOobject;

#define IOOOBJECT(O) ((IOobject*)(O))

52
/* Declarations for objects of type StringO */
53 54 55 56

typedef struct { /* Subtype of IOobject */
  PyObject_HEAD
  char *buf;
Martin v. Löwis's avatar
Martin v. Löwis committed
57
  Py_ssize_t pos, string_size;
58

Martin v. Löwis's avatar
Martin v. Löwis committed
59 60
  Py_ssize_t buf_size;
  int softspace;
Guido van Rossum's avatar
Guido van Rossum committed
61 62 63 64
} Oobject;

/* Declarations for objects of type StringI */

65
typedef struct { /* Subtype of IOobject */
Guido van Rossum's avatar
Guido van Rossum committed
66 67
  PyObject_HEAD
  char *buf;
Martin v. Löwis's avatar
Martin v. Löwis committed
68
  Py_ssize_t pos, string_size;
69 70
  /* We store a reference to the object here in order to keep
     the buffer alive during the lifetime of the Iobject. */
Guido van Rossum's avatar
Guido van Rossum committed
71 72 73
  PyObject *pbuf;
} Iobject;

74
/* IOobject (common) methods */
Guido van Rossum's avatar
Guido van Rossum committed
75

76
PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
Guido van Rossum's avatar
Guido van Rossum committed
77

78 79
static int
IO__opencheck(IOobject *self) {
Martin v. Löwis's avatar
Martin v. Löwis committed
80
        if (!self->buf) {
81 82 83 84 85
                PyErr_SetString(PyExc_ValueError,
                                "I/O operation on closed file");
                return 0;
        }
        return 1;
Guido van Rossum's avatar
Guido van Rossum committed
86 87
}

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
static PyObject *
IO_get_closed(IOobject *self, void *closure)
{
	PyObject *result = Py_False;

	if (self->buf == NULL)
		result = Py_True;
	Py_INCREF(result);
	return result;
}

static PyGetSetDef file_getsetlist[] = {
	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
	{0},
};

104
static PyObject *
105
IO_flush(IOobject *self, PyObject *unused) {
Guido van Rossum's avatar
Guido van Rossum committed
106

Martin v. Löwis's avatar
Martin v. Löwis committed
107
        if (!IO__opencheck(self)) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
108

109 110
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
111 112
}

113 114 115 116 117
PyDoc_STRVAR(IO_getval__doc__,
"getvalue([use_pos]) -- Get the string value."
"\n"
"If use_pos is specified and is a true value, then the string returned\n"
"will include only the text up to the current file position.\n");
Guido van Rossum's avatar
Guido van Rossum committed
118 119

static PyObject *
120
IO_cgetval(PyObject *self) {
Martin v. Löwis's avatar
Martin v. Löwis committed
121
        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
122
        assert(IOOOBJECT(self)->pos >= 0);
123
        return PyString_FromStringAndSize(((IOobject*)self)->buf,
124 125
                                          ((IOobject*)self)->pos);
}
Guido van Rossum's avatar
Guido van Rossum committed
126

127 128 129
static PyObject *
IO_getval(IOobject *self, PyObject *args) {
        PyObject *use_pos=Py_None;
130
        Py_ssize_t s;
131

Martin v. Löwis's avatar
Martin v. Löwis committed
132 133
        if (!IO__opencheck(self)) return NULL;
        if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
134 135 136 137 138 139 140

        if (PyObject_IsTrue(use_pos)) {
                  s=self->pos;
                  if (s > self->string_size) s=self->string_size;
        }
        else
                  s=self->string_size;
141
        assert(self->pos >= 0);
142
        return PyString_FromStringAndSize(self->buf, s);
143
}
Guido van Rossum's avatar
Guido van Rossum committed
144

145
PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
Guido van Rossum's avatar
Guido van Rossum committed
146

147
static PyObject *
148
IO_isatty(IOobject *self, PyObject *unused) {
149 150
        if (!IO__opencheck(self)) return NULL;
        Py_INCREF(Py_False);
151
        return Py_False;
Guido van Rossum's avatar
Guido van Rossum committed
152 153
}

154 155
PyDoc_STRVAR(IO_read__doc__,
"read([s]) -- Read s characters, or the rest of the string");
Guido van Rossum's avatar
Guido van Rossum committed
156 157

static int
Martin v. Löwis's avatar
Martin v. Löwis committed
158
IO_cread(PyObject *self, char **output, Py_ssize_t  n) {
159
        Py_ssize_t l;
160

Martin v. Löwis's avatar
Martin v. Löwis committed
161
        if (!IO__opencheck(IOOOBJECT(self))) return -1;
162 163
        assert(IOOOBJECT(self)->pos >= 0);
        assert(IOOOBJECT(self)->string_size >= 0);
164 165 166 167 168 169 170 171 172
        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;  
        if (n < 0 || n > l) {
                n = l;
                if (n < 0) n=0;
        }

        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
        ((IOobject*)self)->pos += n;
        return n;
Guido van Rossum's avatar
Guido van Rossum committed
173 174 175
}

static PyObject *
176
IO_read(IOobject *self, PyObject *args) {
Martin v. Löwis's avatar
Martin v. Löwis committed
177
        Py_ssize_t n = -1;
178
        char *output = NULL;
Guido van Rossum's avatar
Guido van Rossum committed
179

Martin v. Löwis's avatar
Martin v. Löwis committed
180
        if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
181

182
        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
183

184
        return PyString_FromStringAndSize(output, n);
Guido van Rossum's avatar
Guido van Rossum committed
185 186
}

187
PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
Guido van Rossum's avatar
Guido van Rossum committed
188 189

static int
190 191
IO_creadline(PyObject *self, char **output) {
        char *n, *s;
Martin v. Löwis's avatar
Martin v. Löwis committed
192
        Py_ssize_t l;
193

Martin v. Löwis's avatar
Martin v. Löwis committed
194
        if (!IO__opencheck(IOOOBJECT(self))) return -1;
195 196 197 198

        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size; 
             n < s && *n != '\n'; n++);
199

200 201 202 203
        if (n < s) n++;

        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
204 205 206 207 208 209

        assert(IOOOBJECT(self)->pos <= PY_SSIZE_T_MAX - l);
        assert(IOOOBJECT(self)->pos >= 0);
        assert(IOOOBJECT(self)->string_size >= 0);

        ((IOobject*)self)->pos += l;
Martin v. Löwis's avatar
Martin v. Löwis committed
210
        return (int)l;
Guido van Rossum's avatar
Guido van Rossum committed
211 212 213
}

static PyObject *
214 215 216 217
IO_readline(IOobject *self, PyObject *args) {
        int n, m=-1;
        char *output;

218
        if (args)
Martin v. Löwis's avatar
Martin v. Löwis committed
219
                if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
220 221 222 223 224 225 226

        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
        if (m >= 0 && m < n) {
                m = n - m;
                n -= m;
                self->pos -= m;
        }
227
        assert(IOOOBJECT(self)->pos >= 0);
228
        return PyString_FromStringAndSize(output, n);
Guido van Rossum's avatar
Guido van Rossum committed
229 230
}

231
PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
232 233

static PyObject *
234
IO_readlines(IOobject *self, PyObject *args) {
235 236 237 238 239
	int n;
	char *output;
	PyObject *result, *line;
        int hint = 0, length = 0;
	
Martin v. Löwis's avatar
Martin v. Löwis committed
240
        if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
241

242 243 244 245
	result = PyList_New(0);
	if (!result)
		return NULL;

246 247 248
	while (1){
		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
                        goto err;
249 250
		if (n == 0)
			break;
251
		line = PyString_FromStringAndSize (output, n);
252 253
		if (!line) 
                        goto err;
254 255 256 257
		if (PyList_Append (result, line) == -1) {
			Py_DECREF (line);
			goto err;
		}
258 259 260 261 262 263
		Py_DECREF (line);
                length += n;
                if (hint > 0 && length >= hint)
			break;
	}
	return result;
264 265 266
 err:
        Py_DECREF(result);
        return NULL;
267 268
}

269 270
PyDoc_STRVAR(IO_reset__doc__,
"reset() -- Reset the file position to the beginning");
Guido van Rossum's avatar
Guido van Rossum committed
271

272
static PyObject *
273
IO_reset(IOobject *self, PyObject *unused) {
Guido van Rossum's avatar
Guido van Rossum committed
274

Martin v. Löwis's avatar
Martin v. Löwis committed
275
        if (!IO__opencheck(self)) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
276

277
        self->pos = 0;
Guido van Rossum's avatar
Guido van Rossum committed
278

279 280
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
281 282
}

283
PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
284

Guido van Rossum's avatar
Guido van Rossum committed
285
static PyObject *
286
IO_tell(IOobject *self, PyObject *unused) {
Guido van Rossum's avatar
Guido van Rossum committed
287

Martin v. Löwis's avatar
Martin v. Löwis committed
288
        if (!IO__opencheck(self)) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
289

290
        assert(self->pos >= 0);
291
        return PyInt_FromSsize_t(self->pos);
Guido van Rossum's avatar
Guido van Rossum committed
292 293
}

294 295
PyDoc_STRVAR(IO_truncate__doc__,
"truncate(): truncate the file at the current position.");
Guido van Rossum's avatar
Guido van Rossum committed
296

Guido van Rossum's avatar
Guido van Rossum committed
297
static PyObject *
298
IO_truncate(IOobject *self, PyObject *args) {
Martin v. Löwis's avatar
Martin v. Löwis committed
299
        Py_ssize_t pos = -1;
300
	
Martin v. Löwis's avatar
Martin v. Löwis committed
301 302
        if (!IO__opencheck(self)) return NULL;
        if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
303 304 305 306 307 308 309 310 311 312 313

	if (PyTuple_Size(args) == 0) {
		/* No argument passed, truncate to current position */
		pos = self->pos;
	}

        if (pos < 0) {
		errno = EINVAL;
		PyErr_SetFromErrno(PyExc_IOError);
		return NULL;
	}
314

315
        if (self->string_size > pos) self->string_size = pos;
316
        self->pos = self->string_size;
317 318 319

        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
320 321
}

322 323 324 325 326 327 328
static PyObject *
IO_iternext(Iobject *self)
{
	PyObject *next;
	next = IO_readline((IOobject *)self, NULL);
	if (!next)
		return NULL;
329
	if (!PyString_GET_SIZE(next)) {
330 331 332 333 334 335 336
		Py_DECREF(next);
		PyErr_SetNone(PyExc_StopIteration);
		return NULL;
	}
	return next;
}

337 338 339 340 341



/* Read-write object methods */

342
PyDoc_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");
Guido van Rossum's avatar
Guido van Rossum committed
345 346

static PyObject *
347
O_seek(Oobject *self, PyObject *args) {
Martin v. Löwis's avatar
Martin v. Löwis committed
348 349
	Py_ssize_t position;
	int mode = 0;
350

Martin v. Löwis's avatar
Martin v. Löwis committed
351 352
        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
353 354 355 356 357 358 359 360 361 362
                return NULL;

        if (mode == 2) {
                position += self->string_size;
        }
        else if (mode == 1) {
                position += self->pos;
        }

        if (position > self->buf_size) {
363
                  char *newbuf;
364 365
                  self->buf_size*=2;
                  if (self->buf_size <= position) self->buf_size=position+1;
366 367 368 369
		  newbuf = (char*) realloc(self->buf,self->buf_size);
                  if (!newbuf) {
                      free(self->buf);
                      self->buf = 0;
370 371 372
                      self->buf_size=self->pos=0;
                      return PyErr_NoMemory();
                    }
373
                  self->buf = newbuf;
374 375 376 377 378 379 380 381 382
          }
        else if (position < 0) position=0;

        self->pos=position;

        while (--position >= self->string_size) self->buf[position]=0;

        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
383 384
}

385
PyDoc_STRVAR(O_write__doc__,
386
"write(s) -- Write a string to the file"
387
"\n\nNote (hack:) writing None resets the buffer");
388 389 390


static int
Martin v. Löwis's avatar
Martin v. Löwis committed
391 392
O_cwrite(PyObject *self, const char *c, Py_ssize_t  l) {
        Py_ssize_t newl;
393
        Oobject *oself;
394
        char *newbuf;
395

Martin v. Löwis's avatar
Martin v. Löwis committed
396
        if (!IO__opencheck(IOOOBJECT(self))) return -1;
397 398 399 400 401
        oself = (Oobject *)self;

        newl = oself->pos+l;
        if (newl >= oself->buf_size) {
            oself->buf_size *= 2;
Martin v. Löwis's avatar
Martin v. Löwis committed
402 403 404 405
            if (oself->buf_size <= newl) {
		    assert(newl + 1 < INT_MAX);
                    oself->buf_size = (int)(newl+1);
	    }
406 407
            newbuf = (char*)realloc(oself->buf, oself->buf_size);
	    if (!newbuf) {
408
                    PyErr_SetString(PyExc_MemoryError,"out of memory");
409 410
                    free(oself->buf);
                    oself->buf = 0;
411
                    oself->buf_size = oself->pos = 0;
412 413
                    return -1;
              }
414
            oself->buf = newbuf;
415 416
          }

417
        memcpy(oself->buf+oself->pos,c,l);
418

Martin v. Löwis's avatar
Martin v. Löwis committed
419 420
	assert(oself->pos + l < INT_MAX);
        oself->pos += (int)l;
421

422 423 424
        if (oself->string_size < oself->pos) {
            oself->string_size = oself->pos;
        }
425

Martin v. Löwis's avatar
Martin v. Löwis committed
426
        return (int)l;
427
}
Guido van Rossum's avatar
Guido van Rossum committed
428 429

static PyObject *
430 431 432 433
O_write(Oobject *self, PyObject *args) {
        char *c;
        int l;

Martin v. Löwis's avatar
Martin v. Löwis committed
434
        if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
435 436 437 438 439

        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;

        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
440 441
}

442
PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
Guido van Rossum's avatar
Guido van Rossum committed
443 444

static PyObject *
445
O_close(Oobject *self, PyObject *unused) {
446 447
        if (self->buf != NULL) free(self->buf);
        self->buf = NULL;
Guido van Rossum's avatar
Guido van Rossum committed
448

449
        self->pos = self->string_size = self->buf_size = 0;
Guido van Rossum's avatar
Guido van Rossum committed
450

451 452
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
453 454
}

455
PyDoc_STRVAR(O_writelines__doc__,
456 457 458 459
"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
"\n"
"Note that newlines are not added.  The sequence can be any iterable object\n"
"producing strings. This is equivalent to calling write() for each string.");
Guido van Rossum's avatar
Guido van Rossum committed
460
static PyObject *
461
O_writelines(Oobject *self, PyObject *args) {
462 463 464 465 466 467
	PyObject *it, *s;
	
	it = PyObject_GetIter(args);
	if (it == NULL)
		return NULL;
	while ((s = PyIter_Next(it)) != NULL) {
Martin v. Löwis's avatar
Martin v. Löwis committed
468
		Py_ssize_t n;
469
		char *c;
470
		if (PyString_AsStringAndSize(s, &c, &n) == -1) {
471 472
			Py_DECREF(it);
			Py_DECREF(s);
473
			return NULL;
474 475 476 477
		}
		if (O_cwrite((PyObject *)self, c, n) == -1) {
			Py_DECREF(it);
			Py_DECREF(s);
478
			return NULL;
479 480 481
               }
               Py_DECREF(s);
       }
Guido van Rossum's avatar
Guido van Rossum committed
482

483 484 485 486 487 488 489 490
       Py_DECREF(it);

       /* See if PyIter_Next failed */
       if (PyErr_Occurred())
               return NULL;

       Py_RETURN_NONE;
}
Guido van Rossum's avatar
Guido van Rossum committed
491
static 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 497 498
  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
499 500
  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
501 502 503
  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},

  /* Read-write StringIO specific  methods: */
504
  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
505 506
  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
507
  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
Guido van Rossum's avatar
Guido van Rossum committed
508
  {NULL,	 NULL}		/* sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
509 510
};

511 512 513
static PyMemberDef O_memberlist[] = {
	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
	 "flag indicating that a space needs to be printed; used by print"},
514
	 /* getattr(f, "closed") is implemented without this table */
515 516 517
	{NULL} /* Sentinel */
};

Guido van Rossum's avatar
Guido van Rossum committed
518
static void
519
O_dealloc(Oobject *self) {
520 521 522
        if (self->buf != NULL)
                free(self->buf);
        PyObject_Del(self);
Guido van Rossum's avatar
Guido van Rossum committed
523 524
}

525
PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
Guido van Rossum's avatar
Guido van Rossum committed
526 527

static PyTypeObject Otype = {
528
  PyVarObject_HEAD_INIT(NULL, 0)
529
  "cStringIO.StringO",   	/*tp_name*/
530
  sizeof(Oobject),       	/*tp_basicsize*/
531
  0,	       			/*tp_itemsize*/
532 533
  /* methods */
  (destructor)O_dealloc,	/*tp_dealloc*/
534
  0,				/*tp_print*/
535 536
  0,		 		/*tp_getattr */
  0,		 		/*tp_setattr */
537 538
  0,				/*tp_compare*/
  0,				/*tp_repr*/
539 540 541
  0,				/*tp_as_number*/
  0,				/*tp_as_sequence*/
  0,				/*tp_as_mapping*/
542 543 544
  0,				/*tp_hash*/
  0	,			/*tp_call*/
  0,				/*tp_str*/
545 546 547 548 549 550 551 552 553 554 555 556
  0,				/*tp_getattro */
  0,				/*tp_setattro */
  0,				/*tp_as_buffer */
  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
  Otype__doc__, 		/*tp_doc */
  0,				/*tp_traverse */
  0,				/*tp_clear */
  0,				/*tp_richcompare */
  0,				/*tp_weaklistoffset */
  PyObject_SelfIter,		/*tp_iter */
  (iternextfunc)IO_iternext,	/*tp_iternext */
  O_methods,			/*tp_methods */
557 558
  O_memberlist,			/*tp_members */
  file_getsetlist,		/*tp_getset */
Guido van Rossum's avatar
Guido van Rossum committed
559 560
};

561 562
static PyObject *
newOobject(int  size) {
563 564 565 566 567 568 569 570 571
        Oobject *self;

        self = PyObject_New(Oobject, &Otype);
        if (self == NULL)
                return NULL;
        self->pos=0;
        self->string_size = 0;
        self->softspace = 0;

Martin v. Löwis's avatar
Martin v. Löwis committed
572 573
        self->buf = (char *)malloc(size);
	if (!self->buf) {
574 575
                  PyErr_SetString(PyExc_MemoryError,"out of memory");
                  self->buf_size = 0;
576
                  Py_DECREF(self);
577 578 579 580 581
                  return NULL;
          }

        self->buf_size=size;
        return (PyObject*)self;
582 583
}

584
/* End of code for StringO objects */
Guido van Rossum's avatar
Guido van Rossum committed
585 586 587
/* -------------------------------------------------------- */

static PyObject *
588
I_close(Iobject *self, PyObject *unused) {
589
        Py_CLEAR(self->pbuf);
590
        self->buf = NULL;
Guido van Rossum's avatar
Guido van Rossum committed
591

592 593 594 595
        self->pos = self->string_size = 0;

        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
596 597 598
}

static PyObject *
599
I_seek(Iobject *self, PyObject *args) {
Martin v. Löwis's avatar
Martin v. Löwis committed
600 601
        Py_ssize_t position;
	int mode = 0;
Guido van Rossum's avatar
Guido van Rossum committed
602

Martin v. Löwis's avatar
Martin v. Löwis committed
603 604
        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
605
                return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
606

607 608
        if (mode == 2) position += self->string_size;
        else if (mode == 1) position += self->pos;
Guido van Rossum's avatar
Guido van Rossum committed
609

610 611 612
        if (position < 0) position=0;

        self->pos=position;
Guido van Rossum's avatar
Guido van Rossum committed
613

614 615
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
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 624 625
  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
626 627
  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
628 629 630
  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},

  /* 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__},  
Guido van Rossum's avatar
Guido van Rossum committed
633
  {NULL,	NULL}
Guido van Rossum's avatar
Guido van Rossum committed
634 635 636
};

static void
637
I_dealloc(Iobject *self) {
638
  Py_XDECREF(self->pbuf);
639
  PyObject_Del(self);
Guido van Rossum's avatar
Guido van Rossum committed
640 641
}

642

643 644
PyDoc_STRVAR(Itype__doc__,
"Simple type for treating strings as input file streams");
Guido van Rossum's avatar
Guido van Rossum committed
645 646

static PyTypeObject Itype = {
647
  PyVarObject_HEAD_INIT(NULL, 0)
648
  "cStringIO.StringI",			/*tp_name*/
649 650
  sizeof(Iobject),			/*tp_basicsize*/
  0,					/*tp_itemsize*/
651
  /* methods */
652
  (destructor)I_dealloc,		/*tp_dealloc*/
653
  0,					/*tp_print*/
654
  0,		 			/* tp_getattr */
655 656 657
  0,					/*tp_setattr*/
  0,					/*tp_compare*/
  0,					/*tp_repr*/
658 659 660
  0,					/*tp_as_number*/
  0,					/*tp_as_sequence*/
  0,					/*tp_as_mapping*/
661 662 663
  0,					/*tp_hash*/
  0,					/*tp_call*/
  0,					/*tp_str*/
664 665 666 667 668 669 670 671 672
  0,					/* tp_getattro */
  0,					/* tp_setattro */
  0,					/* tp_as_buffer */
  Py_TPFLAGS_DEFAULT,			/* tp_flags */
  Itype__doc__,				/* tp_doc */
  0,					/* tp_traverse */
  0,					/* tp_clear */
  0,					/* tp_richcompare */
  0,					/* tp_weaklistoffset */
673 674
  PyObject_SelfIter,			/* tp_iter */
  (iternextfunc)IO_iternext,		/* tp_iternext */
675 676 677
  I_methods,				/* tp_methods */
  0,					/* tp_members */
  file_getsetlist,			/* tp_getset */
Guido van Rossum's avatar
Guido van Rossum committed
678 679
};

680 681 682 683
static PyObject *
newIobject(PyObject *s) {
  Iobject *self;
  char *buf;
Martin v. Löwis's avatar
Martin v. Löwis committed
684
  Py_ssize_t size;
685

Georg Brandl's avatar
Georg Brandl committed
686
  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
687 688 689 690
    PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
                 s->ob_type->tp_name);
    return NULL;
  }
691

Martin v. Löwis's avatar
Martin v. Löwis committed
692 693
  self = PyObject_New(Iobject, &Itype);
  if (!self) return NULL;
694 695 696 697 698 699 700 701 702
  Py_INCREF(s);
  self->buf=buf;
  self->string_size=size;
  self->pbuf=s;
  self->pos=0;
  
  return (PyObject*)self;
}

Guido van Rossum's avatar
Guido van Rossum committed
703 704 705 706
/* End of code for StringI objects */
/* -------------------------------------------------------- */


707 708
PyDoc_STRVAR(IO_StringIO__doc__,
"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
Guido van Rossum's avatar
Guido van Rossum committed
709 710

static PyObject *
711
IO_StringIO(PyObject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
712 713
  PyObject *s=0;

714
  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
715 716

  if (s) return newIobject(s);
717
  return newOobject(128);
Guido van Rossum's avatar
Guido van Rossum committed
718 719 720 721 722
}

/* List of methods defined in the module */

static struct PyMethodDef IO_methods[] = {
723 724
  {"StringIO",	(PyCFunction)IO_StringIO,	
   METH_VARARGS,	IO_StringIO__doc__},
Guido van Rossum's avatar
Guido van Rossum committed
725
  {NULL,		NULL}		/* sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
726 727 728 729 730
};


/* Initialization function for the module (*must* be called initcStringIO) */

731
static struct PycStringIO_CAPI CAPI = {
732 733
  IO_cread,
  IO_creadline,
734
  O_cwrite,
735
  IO_cgetval,
736 737 738 739 740 741
  newOobject,
  newIobject,
  &Itype,
  &Otype,
};

742 743
#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
Guido van Rossum's avatar
Guido van Rossum committed
744
#endif
745
PyMODINIT_FUNC
746
initcStringIO(void) {
747
  PyObject *m, *d, *v;
Guido van Rossum's avatar
Guido van Rossum committed
748

749

Guido van Rossum's avatar
Guido van Rossum committed
750 751 752 753
  /* Create the module and add the functions */
  m = Py_InitModule4("cStringIO", IO_methods,
		     cStringIO_module_documentation,
		     (PyObject*)NULL,PYTHON_API_VERSION);
754
  if (m == NULL) return;
Guido van Rossum's avatar
Guido van Rossum committed
755 756 757 758

  /* Add some symbolic constants to the module */
  d = PyModule_GetDict(m);
  
Guido van Rossum's avatar
Guido van Rossum committed
759
  /* Export C API */
760 761
  Py_TYPE(&Itype)=&PyType_Type;
  Py_TYPE(&Otype)=&PyType_Type;
762 763
  if (PyType_Ready(&Otype) < 0) return;
  if (PyType_Ready(&Itype) < 0) return;
764 765 766
  PyDict_SetItemString(d,"cStringIO_CAPI",
		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
  Py_XDECREF(v);
767 768

  /* Export Types */
Guido van Rossum's avatar
Guido van Rossum committed
769 770
  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
771 772

  /* Maybe make certain warnings go away */
773
  if (0) PycString_IMPORT;
Guido van Rossum's avatar
Guido van Rossum committed
774
}