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