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