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 | +} | |