cStringIO.c 19.4 KB
Newer Older
1 2 3 4 5 6

#include "Python.h"
#include "import.h"
#include "cStringIO.h"

PyDoc_STRVAR(cStringIO_module_documentation,
Guido van Rossum's avatar
Guido van Rossum committed
7 8 9 10
"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"
11
"full generality of StringIO, but it provides enough for most\n"
12
"applications and is especially useful in conjunction with the\n"
Guido van Rossum's avatar
Guido van Rossum committed
13 14 15 16 17 18 19 20 21
"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
22
"  value=an_output_stream.getvalue()\n"
Guido van Rossum's avatar
Guido van Rossum committed
23 24 25 26
"\n"
"  an_input_stream=StringIO(a_string)\n"
"  spam=an_input_stream.readline()\n"
"  spam=an_input_stream.read(5)\n"
27
"  an_input_stream.seek(0)           # OK, start over\n"
Guido van Rossum's avatar
Guido van Rossum committed
28 29 30 31
"  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"
32
"\n"
33
"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
Guido van Rossum's avatar
Guido van Rossum committed
34

35
#define UNLESS(E) if (!(E))
Guido van Rossum's avatar
Guido van Rossum committed
36

37 38 39 40 41 42 43 44

/* 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
45 46 47 48

typedef struct {
  PyObject_HEAD
  char *buf;
49 50 51 52 53 54 55 56 57 58 59 60 61
  int pos, string_size;
} IOobject;

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

/* Declarations for objects of type StringO */

typedef struct { /* Subtype of IOobject */
  PyObject_HEAD
  char *buf;
  int pos, string_size;

  int buf_size, softspace;
Guido van Rossum's avatar
Guido van Rossum committed
62 63 64 65
} Oobject;

/* Declarations for objects of type StringI */

66
typedef struct { /* Subtype of IOobject */
Guido van Rossum's avatar
Guido van Rossum committed
67 68
  PyObject_HEAD
  char *buf;
Guido van Rossum's avatar
Guido van Rossum committed
69
  int pos, string_size;
70 71
  /* 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
72 73 74
  PyObject *pbuf;
} Iobject;

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

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

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

89 90
static PyObject *
IO_flush(IOobject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
91

92 93
        UNLESS (IO__opencheck(self)) return NULL;
        UNLESS (PyArg_ParseTuple(args, ":flush")) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
94

95 96
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
97 98
}

99 100 101 102 103
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
104 105

static PyObject *
106 107 108 109 110
IO_cgetval(PyObject *self) {
        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
        return PyString_FromStringAndSize(((IOobject*)self)->buf,
                                          ((IOobject*)self)->pos);
}
Guido van Rossum's avatar
Guido van Rossum committed
111

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
static PyObject *
IO_getval(IOobject *self, PyObject *args) {
        PyObject *use_pos=Py_None;
        int s;

        UNLESS (IO__opencheck(self)) return NULL;
        UNLESS (PyArg_ParseTuple(args,"|O:getval",&use_pos)) return NULL;

        if (PyObject_IsTrue(use_pos)) {
                  s=self->pos;
                  if (s > self->string_size) s=self->string_size;
        }
        else
                  s=self->string_size;
        return PyString_FromStringAndSize(self->buf, s);
}
Guido van Rossum's avatar
Guido van Rossum committed
128

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

131 132
static PyObject *
IO_isatty(IOobject *self, PyObject *args) {
133

134
        UNLESS (PyArg_ParseTuple(args, ":isatty")) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
135

136 137
	Py_INCREF(Py_False);
        return Py_False;
Guido van Rossum's avatar
Guido van Rossum committed
138 139
}

140 141
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
142 143

static int
144 145 146 147 148 149 150 151 152 153 154 155 156
IO_cread(PyObject *self, char **output, int  n) {
        int l;

        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
        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
157 158 159
}

static PyObject *
160 161 162
IO_read(IOobject *self, PyObject *args) {
        int n = -1;
        char *output;
Guido van Rossum's avatar
Guido van Rossum committed
163

164
        UNLESS (PyArg_ParseTuple(args, "|i:read", &n)) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
165

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

168
        return PyString_FromStringAndSize(output, n);
Guido van Rossum's avatar
Guido van Rossum committed
169 170
}

171
PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
Guido van Rossum's avatar
Guido van Rossum committed
172 173

static int
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
IO_creadline(PyObject *self, char **output) {
        char *n, *s;
        int l;

        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;

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

        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
        ((IOobject*)self)->pos += l;
        return l;
Guido van Rossum's avatar
Guido van Rossum committed
189 190 191
}

static PyObject *
192 193 194 195 196 197 198 199 200 201 202 203 204
IO_readline(IOobject *self, PyObject *args) {
        int n, m=-1;
        char *output;

        UNLESS (PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;

        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
        if (m >= 0 && m < n) {
                m = n - m;
                n -= m;
                self->pos -= m;
        }
        return PyString_FromStringAndSize(output, n);
Guido van Rossum's avatar
Guido van Rossum committed
205 206
}

207
PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
208 209

static PyObject *
210
IO_readlines(IOobject *self, PyObject *args) {
211 212 213 214 215
	int n;
	char *output;
	PyObject *result, *line;
        int hint = 0, length = 0;
	
216 217
        UNLESS (PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;

218 219 220 221
	result = PyList_New(0);
	if (!result)
		return NULL;

222 223 224
	while (1){
		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
                        goto err;
225 226 227
		if (n == 0)
			break;
		line = PyString_FromStringAndSize (output, n);
228 229
		if (!line) 
                        goto err;
230 231 232 233 234 235 236
		PyList_Append (result, line);
		Py_DECREF (line);
                length += n;
                if (hint > 0 && length >= hint)
			break;
	}
	return result;
237 238 239
 err:
        Py_DECREF(result);
        return NULL;
240 241
}

242 243
PyDoc_STRVAR(IO_reset__doc__,
"reset() -- Reset the file position to the beginning");
Guido van Rossum's avatar
Guido van Rossum committed
244

245 246
static PyObject *
IO_reset(IOobject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
247

248 249
        UNLESS (IO__opencheck(self)) return NULL;
        UNLESS (PyArg_ParseTuple(args, ":reset")) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
250

251
        self->pos = 0;
Guido van Rossum's avatar
Guido van Rossum committed
252

253 254
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
255 256
}

257
PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
258

Guido van Rossum's avatar
Guido van Rossum committed
259
static PyObject *
260
IO_tell(IOobject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
261

262 263
        UNLESS (IO__opencheck(self)) return NULL;
        UNLESS (PyArg_ParseTuple(args, ":tell")) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
264

265
        return PyInt_FromLong(self->pos);
Guido van Rossum's avatar
Guido van Rossum committed
266 267
}

268 269
PyDoc_STRVAR(IO_truncate__doc__,
"truncate(): truncate the file at the current position.");
Guido van Rossum's avatar
Guido van Rossum committed
270

Guido van Rossum's avatar
Guido van Rossum committed
271
static PyObject *
272 273 274 275 276 277
IO_truncate(IOobject *self, PyObject *args) {
        int pos = -1;
	
        UNLESS (IO__opencheck(self)) return NULL;
        UNLESS (PyArg_ParseTuple(args, "|i:truncate", &pos)) return NULL;
        if (pos < 0) pos = self->pos;
278

279 280 281 282
        if (self->string_size > pos) self->string_size = pos;

        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
283 284
}

285 286 287 288 289



/* Read-write object methods */

290
PyDoc_STRVAR(O_seek__doc__,
291
"seek(position)       -- set the current position\n"
292
"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
Guido van Rossum's avatar
Guido van Rossum committed
293 294

static PyObject *
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
O_seek(Oobject *self, PyObject *args) {
        int position, mode = 0;

        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode)) 
                return NULL;

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

        if (position > self->buf_size) {
                  self->buf_size*=2;
                  if (self->buf_size <= position) self->buf_size=position+1;
                  UNLESS (self->buf=(char*)
                          realloc(self->buf,self->buf_size*sizeof(char))) {
                      self->buf_size=self->pos=0;
                      return PyErr_NoMemory();
                    }
          }
        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
326 327
}

328
PyDoc_STRVAR(O_write__doc__,
329
"write(s) -- Write a string to the file"
330
"\n\nNote (hack:) writing None resets the buffer");
331 332 333 334 335


static int
O_cwrite(PyObject *self, char *c, int  l) {
        int newl;
336
        Oobject *oself;
337 338

        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
339 340 341 342 343 344 345 346 347 348
        oself = (Oobject *)self;

        newl = oself->pos+l;
        if (newl >= oself->buf_size) {
            oself->buf_size *= 2;
            if (oself->buf_size <= newl) 
                    oself->buf_size = newl+1;
            UNLESS (oself->buf = 
                    (char*)realloc(oself->buf,
                                   (oself->buf_size) * sizeof(char))) {
349
                    PyErr_SetString(PyExc_MemoryError,"out of memory");
350
                    oself->buf_size = oself->pos = 0;
351 352 353 354
                    return -1;
              }
          }

355
        memcpy(oself->buf+oself->pos,c,l);
356

357
        oself->pos += l;
358

359 360 361
        if (oself->string_size < oself->pos) {
            oself->string_size = oself->pos;
        }
362 363 364

        return l;
}
Guido van Rossum's avatar
Guido van Rossum committed
365 366

static PyObject *
367 368 369 370
O_write(Oobject *self, PyObject *args) {
        char *c;
        int l;

371
        UNLESS (PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
372 373 374 375 376

        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
377 378
}

379
PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
Guido van Rossum's avatar
Guido van Rossum committed
380 381

static PyObject *
382
O_close(Oobject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
383

384
        UNLESS (PyArg_ParseTuple(args, ":close")) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
385

386 387
        if (self->buf != NULL) free(self->buf);
        self->buf = NULL;
Guido van Rossum's avatar
Guido van Rossum committed
388

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

391 392
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
393 394 395
}


396 397
PyDoc_STRVAR(O_writelines__doc__,
"writelines(sequence_of_strings): write each string");
Guido van Rossum's avatar
Guido van Rossum committed
398
static PyObject *
399
O_writelines(Oobject *self, PyObject *args) {
400
        PyObject *tmp = 0;
401
	static PyObject *joiner = NULL;
Guido van Rossum's avatar
Guido van Rossum committed
402

403
        UNLESS (PyArg_ParseTuple(args, "O:writelines", &args)) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
404

405 406 407 408 409 410 411 412 413
	if (!joiner) {
		PyObject *empty_string = PyString_FromString("");
		if (empty_string == NULL)
			return NULL;
		joiner = PyObject_GetAttrString(empty_string, "join");
		Py_DECREF(empty_string);
		if (joiner == NULL)
			return NULL;
	}
Guido van Rossum's avatar
Guido van Rossum committed
414

415
        if (PyObject_Size(args) < 0) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
416

417
        tmp = PyObject_CallFunction(joiner, "O", args);
418
        UNLESS (tmp) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
419

420 421 422
        args = Py_BuildValue("(O)", tmp);
        Py_DECREF(tmp);
        UNLESS (args) return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
423

424 425 426
        tmp = O_write(self, args);
        Py_DECREF(args);
        return tmp;
Guido van Rossum's avatar
Guido van Rossum committed
427 428 429
}

static struct PyMethodDef O_methods[] = {
430 431 432 433 434 435 436 437 438 439 440 441
  /* Common methods: */
  {"flush",     (PyCFunction)IO_flush,    METH_VARARGS, IO_flush__doc__},
  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
  {"isatty",    (PyCFunction)IO_isatty,   METH_VARARGS, IO_isatty__doc__},
  {"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__},
  {"reset",	(PyCFunction)IO_reset,	  METH_VARARGS, IO_reset__doc__},
  {"tell",      (PyCFunction)IO_tell,     METH_VARARGS, IO_tell__doc__},
  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},

  /* Read-write StringIO specific  methods: */
Guido van Rossum's avatar
Guido van Rossum committed
442
  {"close",      (PyCFunction)O_close,      METH_VARARGS, O_close__doc__},
443 444
  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
Guido van Rossum's avatar
Guido van Rossum committed
445 446
  {"writelines", (PyCFunction)O_writelines, METH_VARARGS, O_writelines__doc__},
  {NULL,	 NULL}		/* sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
447 448 449
};

static void
450
O_dealloc(Oobject *self) {
451 452 453
        if (self->buf != NULL)
                free(self->buf);
        PyObject_Del(self);
Guido van Rossum's avatar
Guido van Rossum committed
454 455 456
}

static PyObject *
457
O_getattr(Oobject *self, char *name) {
458 459 460 461
        if (strcmp(name, "softspace") == 0) {
                return PyInt_FromLong(self->softspace);
        }
        return Py_FindMethod(O_methods, (PyObject *)self, name);
Guido van Rossum's avatar
Guido van Rossum committed
462 463
}

464 465 466 467 468 469 470 471
static int
O_setattr(Oobject *self, char *name, PyObject *value) {
	long x;
	if (strcmp(name, "softspace") != 0) {
		PyErr_SetString(PyExc_AttributeError, name);
		return -1;
	}
	x = PyInt_AsLong(value);
472
	if (x < 0 && PyErr_Occurred())
473 474 475 476 477
		return -1;
	self->softspace = x;
	return 0;
}

478
PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
Guido van Rossum's avatar
Guido van Rossum committed
479 480

static PyTypeObject Otype = {
481 482
  PyObject_HEAD_INIT(NULL)
  0,	       		/*ob_size*/
483
  "cStringIO.StringO",   		/*tp_name*/
484 485 486 487 488 489
  sizeof(Oobject),       	/*tp_basicsize*/
  0,	       		/*tp_itemsize*/
  /* methods */
  (destructor)O_dealloc,	/*tp_dealloc*/
  (printfunc)0,		/*tp_print*/
  (getattrfunc)O_getattr,	/*tp_getattr*/
490
  (setattrfunc)O_setattr,	/*tp_setattr*/
491 492 493 494 495 496 497 498 499 500 501 502
  (cmpfunc)0,		/*tp_compare*/
  (reprfunc)0,		/*tp_repr*/
  0,			/*tp_as_number*/
  0,			/*tp_as_sequence*/
  0,			/*tp_as_mapping*/
  (hashfunc)0,		/*tp_hash*/
  (ternaryfunc)0,		/*tp_call*/
  (reprfunc)0,		/*tp_str*/
  
  /* Space for future expansion */
  0L,0L,0L,0L,
  Otype__doc__ 		/* Documentation string */
Guido van Rossum's avatar
Guido van Rossum committed
503 504
};

505 506
static PyObject *
newOobject(int  size) {
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
        Oobject *self;

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

        UNLESS (self->buf=malloc(size*sizeof(char))) {
                  PyErr_SetString(PyExc_MemoryError,"out of memory");
                  self->buf_size = 0;
                  return NULL;
          }

        self->buf_size=size;
        return (PyObject*)self;
524 525
}

Guido van Rossum's avatar
Guido van Rossum committed
526 527 528 529
/* End of code for StringO objects */
/* -------------------------------------------------------- */

static PyObject *
530
I_close(Iobject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
531

532 533 534 535 536
        UNLESS (PyArg_ParseTuple(args, ":close")) return NULL;

        Py_XDECREF(self->pbuf);
        self->pbuf = NULL;
        self->buf = NULL;
Guido van Rossum's avatar
Guido van Rossum committed
537

538 539 540 541
        self->pos = self->string_size = 0;

        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
542 543 544
}

static PyObject *
545 546
I_seek(Iobject *self, PyObject *args) {
        int position, mode = 0;
Guido van Rossum's avatar
Guido van Rossum committed
547

548 549 550
        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode)) 
                return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
551

552 553
        if (mode == 2) position += self->string_size;
        else if (mode == 1) position += self->pos;
Guido van Rossum's avatar
Guido van Rossum committed
554

555 556 557
        if (position < 0) position=0;

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

559 560
        Py_INCREF(Py_None);
        return Py_None;
Guido van Rossum's avatar
Guido van Rossum committed
561 562 563
}

static struct PyMethodDef I_methods[] = {
564 565 566 567 568 569 570 571 572 573 574 575
  /* Common methods: */
  {"flush",     (PyCFunction)IO_flush,    METH_VARARGS, IO_flush__doc__},
  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
  {"isatty",    (PyCFunction)IO_isatty,   METH_VARARGS, IO_isatty__doc__},
  {"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__},
  {"reset",	(PyCFunction)IO_reset,	  METH_VARARGS, IO_reset__doc__},
  {"tell",      (PyCFunction)IO_tell,     METH_VARARGS, IO_tell__doc__},
  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},

  /* Read-only StringIO specific  methods: */
Guido van Rossum's avatar
Guido van Rossum committed
576
  {"close",     (PyCFunction)I_close,    METH_VARARGS, O_close__doc__},
577
  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},  
Guido van Rossum's avatar
Guido van Rossum committed
578
  {NULL,	NULL}
Guido van Rossum's avatar
Guido van Rossum committed
579 580 581
};

static void
582
I_dealloc(Iobject *self) {
583
  Py_XDECREF(self->pbuf);
584
  PyObject_Del(self);
Guido van Rossum's avatar
Guido van Rossum committed
585 586 587
}

static PyObject *
588
I_getattr(Iobject *self, char *name) {
Guido van Rossum's avatar
Guido van Rossum committed
589 590 591
  return Py_FindMethod(I_methods, (PyObject *)self, name);
}

592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
static PyObject *
I_getiter(Iobject *self)
{
	PyObject *myreadline = PyObject_GetAttrString((PyObject*)self,
						      "readline");
	PyObject *emptystring = PyString_FromString("");
	PyObject *iter = NULL;
	if (!myreadline || !emptystring)
		goto finally;

	iter = PyCallIter_New(myreadline, emptystring);
  finally:
	Py_XDECREF(myreadline);
	Py_XDECREF(emptystring);
	return iter;
}


610 611
PyDoc_STRVAR(Itype__doc__,
"Simple type for treating strings as input file streams");
Guido van Rossum's avatar
Guido van Rossum committed
612 613

static PyTypeObject Itype = {
614
  PyObject_HEAD_INIT(NULL)
615
  0,					/*ob_size*/
616
  "cStringIO.StringI",			/*tp_name*/
617 618
  sizeof(Iobject),			/*tp_basicsize*/
  0,					/*tp_itemsize*/
619
  /* methods */
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
  (destructor)I_dealloc,		/*tp_dealloc*/
  (printfunc)0,				/*tp_print*/
  (getattrfunc)I_getattr,		/*tp_getattr*/
  (setattrfunc)0,			/*tp_setattr*/
  (cmpfunc)0,				/*tp_compare*/
  (reprfunc)0,				/*tp_repr*/
  0,					/*tp_as_number*/
  0,					/*tp_as_sequence*/
  0,					/*tp_as_mapping*/
  (hashfunc)0,				/*tp_hash*/
  (ternaryfunc)0,			/*tp_call*/
  (reprfunc)0,				/*tp_str*/
  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 */
  (getiterfunc)I_getiter,		/* tp_iter */
  0,					/* tp_iternext */
Guido van Rossum's avatar
Guido van Rossum committed
643 644
};

645 646 647 648 649
static PyObject *
newIobject(PyObject *s) {
  Iobject *self;
  char *buf;
  int size;
650

651 652
  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
      PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
653 654 655
		   s->ob_type->tp_name);
      return NULL;
  }
656
  UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL;
657 658 659 660 661 662 663 664 665
  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
666 667 668 669
/* End of code for StringI objects */
/* -------------------------------------------------------- */


670 671
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
672 673

static PyObject *
674
IO_StringIO(PyObject *self, PyObject *args) {
Guido van Rossum's avatar
Guido van Rossum committed
675 676
  PyObject *s=0;

677 678 679
  if (!PyArg_ParseTuple(args, "|O:StringIO", &s)) return NULL;

  if (s) return newIobject(s);
680
  return newOobject(128);
Guido van Rossum's avatar
Guido van Rossum committed
681 682 683 684 685
}

/* List of methods defined in the module */

static struct PyMethodDef IO_methods[] = {
686 687
  {"StringIO",	(PyCFunction)IO_StringIO,	
   METH_VARARGS,	IO_StringIO__doc__},
Guido van Rossum's avatar
Guido van Rossum committed
688
  {NULL,		NULL}		/* sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
689 690 691 692 693
};


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

694
static struct PycStringIO_CAPI CAPI = {
695 696
  IO_cread,
  IO_creadline,
697
  O_cwrite,
698
  IO_cgetval,
699 700 701 702 703 704
  newOobject,
  newIobject,
  &Itype,
  &Otype,
};

705 706
#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
#define PyMODINIT_FUNC void
Guido van Rossum's avatar
Guido van Rossum committed
707
#endif
708
PyMODINIT_FUNC
709
initcStringIO(void) {
710
  PyObject *m, *d, *v;
Guido van Rossum's avatar
Guido van Rossum committed
711

712

Guido van Rossum's avatar
Guido van Rossum committed
713 714 715 716 717 718 719 720
  /* Create the module and add the functions */
  m = Py_InitModule4("cStringIO", IO_methods,
		     cStringIO_module_documentation,
		     (PyObject*)NULL,PYTHON_API_VERSION);

  /* Add some symbolic constants to the module */
  d = PyModule_GetDict(m);
  
Guido van Rossum's avatar
Guido van Rossum committed
721
  /* Export C API */
722 723
  Itype.ob_type=&PyType_Type;
  Otype.ob_type=&PyType_Type;
724 725 726
  PyDict_SetItemString(d,"cStringIO_CAPI",
		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
  Py_XDECREF(v);
727 728

  /* Export Types */
Guido van Rossum's avatar
Guido van Rossum committed
729 730
  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
731 732

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