cStringIO.c revision e138828d0360da3782ce56ba8161b45d1505252f
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 293 Py_INCREF(Py_None); 294 return Py_None; 295} 296 297static PyObject * 298IO_iternext(Iobject *self) 299{ 300 PyObject *next; 301 next = IO_readline((IOobject *)self, NULL); 302 if (!next) 303 return NULL; 304 if (!PyString_GET_SIZE(next)) { 305 Py_DECREF(next); 306 PyErr_SetNone(PyExc_StopIteration); 307 return NULL; 308 } 309 return next; 310} 311 312 313 314 315/* Read-write object methods */ 316 317PyDoc_STRVAR(O_seek__doc__, 318"seek(position) -- set the current position\n" 319"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF"); 320 321static PyObject * 322O_seek(Oobject *self, PyObject *args) { 323 int position, mode = 0; 324 325 UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL; 326 UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode)) 327 return NULL; 328 329 if (mode == 2) { 330 position += self->string_size; 331 } 332 else if (mode == 1) { 333 position += self->pos; 334 } 335 336 if (position > self->buf_size) { 337 self->buf_size*=2; 338 if (self->buf_size <= position) self->buf_size=position+1; 339 UNLESS (self->buf=(char*) 340 realloc(self->buf,self->buf_size*sizeof(char))) { 341 self->buf_size=self->pos=0; 342 return PyErr_NoMemory(); 343 } 344 } 345 else if (position < 0) position=0; 346 347 self->pos=position; 348 349 while (--position >= self->string_size) self->buf[position]=0; 350 351 Py_INCREF(Py_None); 352 return Py_None; 353} 354 355PyDoc_STRVAR(O_write__doc__, 356"write(s) -- Write a string to the file" 357"\n\nNote (hack:) writing None resets the buffer"); 358 359 360static int 361O_cwrite(PyObject *self, char *c, int l) { 362 int newl; 363 Oobject *oself; 364 365 UNLESS (IO__opencheck(IOOOBJECT(self))) return -1; 366 oself = (Oobject *)self; 367 368 newl = oself->pos+l; 369 if (newl >= oself->buf_size) { 370 oself->buf_size *= 2; 371 if (oself->buf_size <= newl) 372 oself->buf_size = newl+1; 373 UNLESS (oself->buf = 374 (char*)realloc(oself->buf, 375 (oself->buf_size) * sizeof(char))) { 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 419 420PyDoc_STRVAR(O_writelines__doc__, 421"writelines(sequence_of_strings): write each string"); 422static PyObject * 423O_writelines(Oobject *self, PyObject *args) { 424 PyObject *tmp = 0; 425 static PyObject *joiner = NULL; 426 427 if (!joiner) { 428 PyObject *empty_string = PyString_FromString(""); 429 if (empty_string == NULL) 430 return NULL; 431 joiner = PyObject_GetAttrString(empty_string, "join"); 432 Py_DECREF(empty_string); 433 if (joiner == NULL) 434 return NULL; 435 } 436 437 if (PyObject_Size(args) < 0) return NULL; 438 439 tmp = PyObject_CallFunction(joiner, "O", args); 440 UNLESS (tmp) return NULL; 441 442 args = Py_BuildValue("(O)", tmp); 443 Py_DECREF(tmp); 444 UNLESS (args) return NULL; 445 446 tmp = O_write(self, args); 447 Py_DECREF(args); 448 return tmp; 449} 450 451static struct PyMethodDef O_methods[] = { 452 /* Common methods: */ 453 {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__}, 454 {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, 455 {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__}, 456 {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, 457 {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, 458 {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, 459 {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__}, 460 {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__}, 461 {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__}, 462 463 /* Read-write StringIO specific methods: */ 464 {"close", (PyCFunction)O_close, METH_NOARGS, O_close__doc__}, 465 {"seek", (PyCFunction)O_seek, METH_VARARGS, O_seek__doc__}, 466 {"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__}, 467 {"writelines", (PyCFunction)O_writelines, METH_O, O_writelines__doc__}, 468 {NULL, NULL} /* sentinel */ 469}; 470 471static PyMemberDef O_memberlist[] = { 472 {"softspace", T_INT, offsetof(Oobject, softspace), 0, 473 "flag indicating that a space needs to be printed; used by print"}, 474 /* getattr(f, "closed") is implemented without this table */ 475 {NULL} /* Sentinel */ 476}; 477 478static void 479O_dealloc(Oobject *self) { 480 if (self->buf != NULL) 481 free(self->buf); 482 PyObject_Del(self); 483} 484 485PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings."); 486 487static PyTypeObject Otype = { 488 PyObject_HEAD_INIT(NULL) 489 0, /*ob_size*/ 490 "cStringIO.StringIO", /*tp_name*/ 491 sizeof(Oobject), /*tp_basicsize*/ 492 0, /*tp_itemsize*/ 493 /* methods */ 494 (destructor)O_dealloc, /*tp_dealloc*/ 495 (printfunc)0, /*tp_print*/ 496 0, /*tp_getattr */ 497 0, /*tp_setattr */ 498 (cmpfunc)0, /*tp_compare*/ 499 (reprfunc)0, /*tp_repr*/ 500 0, /*tp_as_number*/ 501 0, /*tp_as_sequence*/ 502 0, /*tp_as_mapping*/ 503 (hashfunc)0, /*tp_hash*/ 504 (ternaryfunc)0, /*tp_call*/ 505 (reprfunc)0, /*tp_str*/ 506 0, /*tp_getattro */ 507 0, /*tp_setattro */ 508 0, /*tp_as_buffer */ 509 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 510 Otype__doc__, /*tp_doc */ 511 0, /*tp_traverse */ 512 0, /*tp_clear */ 513 0, /*tp_richcompare */ 514 0, /*tp_weaklistoffset */ 515 PyObject_SelfIter, /*tp_iter */ 516 (iternextfunc)IO_iternext, /*tp_iternext */ 517 O_methods, /*tp_methods */ 518 O_memberlist, /*tp_members */ 519 file_getsetlist, /*tp_getset */ 520}; 521 522static PyObject * 523newOobject(int size) { 524 Oobject *self; 525 526 self = PyObject_New(Oobject, &Otype); 527 if (self == NULL) 528 return NULL; 529 self->pos=0; 530 self->string_size = 0; 531 self->softspace = 0; 532 533 UNLESS (self->buf=malloc(size*sizeof(char))) { 534 PyErr_SetString(PyExc_MemoryError,"out of memory"); 535 self->buf_size = 0; 536 return NULL; 537 } 538 539 self->buf_size=size; 540 return (PyObject*)self; 541} 542 543/* End of code for StringO objects */ 544/* -------------------------------------------------------- */ 545 546static PyObject * 547I_close(Iobject *self, PyObject *unused) { 548 Py_XDECREF(self->pbuf); 549 self->pbuf = NULL; 550 self->buf = NULL; 551 552 self->pos = self->string_size = 0; 553 554 Py_INCREF(Py_None); 555 return Py_None; 556} 557 558static PyObject * 559I_seek(Iobject *self, PyObject *args) { 560 int position, mode = 0; 561 562 UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL; 563 UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode)) 564 return NULL; 565 566 if (mode == 2) position += self->string_size; 567 else if (mode == 1) position += self->pos; 568 569 if (position < 0) position=0; 570 571 self->pos=position; 572 573 Py_INCREF(Py_None); 574 return Py_None; 575} 576 577static struct PyMethodDef I_methods[] = { 578 /* Common methods: */ 579 {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__}, 580 {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__}, 581 {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__}, 582 {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__}, 583 {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__}, 584 {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__}, 585 {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__}, 586 {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__}, 587 {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__}, 588 589 /* Read-only StringIO specific methods: */ 590 {"close", (PyCFunction)I_close, METH_NOARGS, O_close__doc__}, 591 {"seek", (PyCFunction)I_seek, METH_VARARGS, O_seek__doc__}, 592 {NULL, NULL} 593}; 594 595static void 596I_dealloc(Iobject *self) { 597 Py_XDECREF(self->pbuf); 598 PyObject_Del(self); 599} 600 601 602PyDoc_STRVAR(Itype__doc__, 603"Simple type for treating strings as input file streams"); 604 605static PyTypeObject Itype = { 606 PyObject_HEAD_INIT(NULL) 607 0, /*ob_size*/ 608 "cStringIO.StringIO", /*tp_name*/ 609 sizeof(Iobject), /*tp_basicsize*/ 610 0, /*tp_itemsize*/ 611 /* methods */ 612 (destructor)I_dealloc, /*tp_dealloc*/ 613 (printfunc)0, /*tp_print*/ 614 0, /* tp_getattr */ 615 (setattrfunc)0, /*tp_setattr*/ 616 (cmpfunc)0, /*tp_compare*/ 617 (reprfunc)0, /*tp_repr*/ 618 0, /*tp_as_number*/ 619 0, /*tp_as_sequence*/ 620 0, /*tp_as_mapping*/ 621 (hashfunc)0, /*tp_hash*/ 622 (ternaryfunc)0, /*tp_call*/ 623 (reprfunc)0, /*tp_str*/ 624 0, /* tp_getattro */ 625 0, /* tp_setattro */ 626 0, /* tp_as_buffer */ 627 Py_TPFLAGS_DEFAULT, /* tp_flags */ 628 Itype__doc__, /* tp_doc */ 629 0, /* tp_traverse */ 630 0, /* tp_clear */ 631 0, /* tp_richcompare */ 632 0, /* tp_weaklistoffset */ 633 PyObject_SelfIter, /* tp_iter */ 634 (iternextfunc)IO_iternext, /* tp_iternext */ 635 I_methods, /* tp_methods */ 636 0, /* tp_members */ 637 file_getsetlist, /* tp_getset */ 638}; 639 640static PyObject * 641newIobject(PyObject *s) { 642 Iobject *self; 643 char *buf; 644 int size; 645 646 if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) { 647 PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found", 648 s->ob_type->tp_name); 649 return NULL; 650 } 651 UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL; 652 Py_INCREF(s); 653 self->buf=buf; 654 self->string_size=size; 655 self->pbuf=s; 656 self->pos=0; 657 658 return (PyObject*)self; 659} 660 661/* End of code for StringI objects */ 662/* -------------------------------------------------------- */ 663 664 665PyDoc_STRVAR(IO_StringIO__doc__, 666"StringIO([s]) -- Return a StringIO-like stream for reading or writing"); 667 668static PyObject * 669IO_StringIO(PyObject *self, PyObject *args) { 670 PyObject *s=0; 671 672 if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL; 673 674 if (s) return newIobject(s); 675 return newOobject(128); 676} 677 678/* List of methods defined in the module */ 679 680static struct PyMethodDef IO_methods[] = { 681 {"StringIO", (PyCFunction)IO_StringIO, 682 METH_VARARGS, IO_StringIO__doc__}, 683 {NULL, NULL} /* sentinel */ 684}; 685 686 687/* Initialization function for the module (*must* be called initcStringIO) */ 688 689static struct PycStringIO_CAPI CAPI = { 690 IO_cread, 691 IO_creadline, 692 O_cwrite, 693 IO_cgetval, 694 newOobject, 695 newIobject, 696 &Itype, 697 &Otype, 698}; 699 700#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ 701#define PyMODINIT_FUNC void 702#endif 703PyMODINIT_FUNC 704initcStringIO(void) { 705 PyObject *m, *d, *v; 706 707 708 /* Create the module and add the functions */ 709 m = Py_InitModule4("cStringIO", IO_methods, 710 cStringIO_module_documentation, 711 (PyObject*)NULL,PYTHON_API_VERSION); 712 713 /* Add some symbolic constants to the module */ 714 d = PyModule_GetDict(m); 715 716 /* Export C API */ 717 Itype.ob_type=&PyType_Type; 718 Otype.ob_type=&PyType_Type; 719 if (PyType_Ready(&Otype) < 0) return; 720 if (PyType_Ready(&Itype) < 0) return; 721 PyDict_SetItemString(d,"cStringIO_CAPI", 722 v = PyCObject_FromVoidPtr(&CAPI,NULL)); 723 Py_XDECREF(v); 724 725 /* Export Types */ 726 PyDict_SetItemString(d,"InputType", (PyObject*)&Itype); 727 PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype); 728 729 /* Maybe make certain warnings go away */ 730 if (0) PycString_IMPORT; 731} 732