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