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