blob: 89f1dd6d2d07b922ecd2db695410102ff499e682 [file] [log] [blame]
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001
2#include "Python.h"
3#include "import.h"
4#include "cStringIO.h"
Raymond Hettinger352f9472003-04-24 15:50:11 +00005#include "structmember.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006
7PyDoc_STRVAR(cStringIO_module_documentation,
Guido van Rossum049cd901996-12-05 23:30:48 +00008"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"
Fred Drakeaef10002000-06-19 13:17:41 +000012"full generality of StringIO, but it provides enough for most\n"
Thomas Wouters7e474022000-07-16 12:04:32 +000013"applications and is especially useful in conjunction with the\n"
Guido van Rossum049cd901996-12-05 23:30:48 +000014"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"
Jeremy Hyltonb189b072002-03-08 17:17:33 +000023" value=an_output_stream.getvalue()\n"
Guido van Rossum049cd901996-12-05 23:30:48 +000024"\n"
25" an_input_stream=StringIO(a_string)\n"
26" spam=an_input_stream.readline()\n"
27" spam=an_input_stream.read(5)\n"
Guido van Rossum7d9b4131998-11-25 16:17:32 +000028" an_input_stream.seek(0) # OK, start over\n"
Guido van Rossum049cd901996-12-05 23:30:48 +000029" 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"
Guido van Rossum142eeb81997-08-13 03:14:41 +000033"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
Guido van Rossum049cd901996-12-05 23:30:48 +000035
Antoine Pitrouc83ea132010-05-09 14:46:46 +000036/* Declaration for file-like objects that manage data as strings
Guido van Rossum049cd901996-12-05 23:30:48 +000037
Jim Fultone60de4d2000-10-06 19:24:23 +000038 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*/
Guido van Rossum049cd901996-12-05 23:30:48 +000043
44typedef struct {
45 PyObject_HEAD
46 char *buf;
Martin v. Löwis18e16552006-02-15 17:27:45 +000047 Py_ssize_t pos, string_size;
Jim Fultone60de4d2000-10-06 19:24:23 +000048} IOobject;
49
50#define IOOOBJECT(O) ((IOobject*)(O))
51
Skip Montanaroe1388282003-08-11 13:15:11 +000052/* Declarations for objects of type StringO */
Jim Fultone60de4d2000-10-06 19:24:23 +000053
54typedef struct { /* Subtype of IOobject */
55 PyObject_HEAD
56 char *buf;
Martin v. Löwis18e16552006-02-15 17:27:45 +000057 Py_ssize_t pos, string_size;
Jim Fultone60de4d2000-10-06 19:24:23 +000058
Martin v. Löwis18e16552006-02-15 17:27:45 +000059 Py_ssize_t buf_size;
60 int softspace;
Jim Fultone60de4d2000-10-06 19:24:23 +000061} Oobject;
62
63/* Declarations for objects of type StringI */
64
65typedef struct { /* Subtype of IOobject */
66 PyObject_HEAD
67 char *buf;
Martin v. Löwis18e16552006-02-15 17:27:45 +000068 Py_ssize_t pos, string_size;
Marc-André Lemburge47df7a2001-09-24 17:34:52 +000069 /* We store a reference to the object here in order to keep
70 the buffer alive during the lifetime of the Iobject. */
Guido van Rossum049cd901996-12-05 23:30:48 +000071 PyObject *pbuf;
72} Iobject;
73
Jim Fultone60de4d2000-10-06 19:24:23 +000074/* IOobject (common) methods */
75
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000076PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
Jim Fultone60de4d2000-10-06 19:24:23 +000077
78static int
79IO__opencheck(IOobject *self) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000080 if (!self->buf) {
81 PyErr_SetString(PyExc_ValueError,
82 "I/O operation on closed file");
83 return 0;
84 }
85 return 1;
Jim Fultone60de4d2000-10-06 19:24:23 +000086}
87
88static PyObject *
Raymond Hettinger5475f232003-08-08 12:20:03 +000089IO_get_closed(IOobject *self, void *closure)
90{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000091 PyObject *result = Py_False;
Raymond Hettinger5475f232003-08-08 12:20:03 +000092
Antoine Pitrouc83ea132010-05-09 14:46:46 +000093 if (self->buf == NULL)
94 result = Py_True;
95 Py_INCREF(result);
96 return result;
Raymond Hettinger5475f232003-08-08 12:20:03 +000097}
98
99static PyGetSetDef file_getsetlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000100 {"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
101 {0},
Raymond Hettinger5475f232003-08-08 12:20:03 +0000102};
103
104static PyObject *
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000105IO_flush(IOobject *self, PyObject *unused) {
Jim Fultone60de4d2000-10-06 19:24:23 +0000106
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000107 if (!IO__opencheck(self)) return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000108
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000109 Py_INCREF(Py_None);
110 return Py_None;
Jim Fultone60de4d2000-10-06 19:24:23 +0000111}
112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000113PyDoc_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");
Guido van Rossum049cd901996-12-05 23:30:48 +0000118
119static PyObject *
Jim Fultone60de4d2000-10-06 19:24:23 +0000120IO_cgetval(PyObject *self) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000121 if (!IO__opencheck(IOOOBJECT(self))) return NULL;
122 assert(IOOOBJECT(self)->pos >= 0);
123 return PyString_FromStringAndSize(((IOobject*)self)->buf,
124 ((IOobject*)self)->pos);
Guido van Rossum049cd901996-12-05 23:30:48 +0000125}
126
Guido van Rossum049cd901996-12-05 23:30:48 +0000127static PyObject *
Jim Fultone60de4d2000-10-06 19:24:23 +0000128IO_getval(IOobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000129 PyObject *use_pos=Py_None;
130 Py_ssize_t s;
Jim Fultone60de4d2000-10-06 19:24:23 +0000131
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000132 if (!IO__opencheck(self)) return NULL;
133 if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000134
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000135 if (PyObject_IsTrue(use_pos)) {
136 s=self->pos;
137 if (s > self->string_size) s=self->string_size;
138 }
139 else
140 s=self->string_size;
141 assert(self->pos >= 0);
142 return PyString_FromStringAndSize(self->buf, s);
Guido van Rossum049cd901996-12-05 23:30:48 +0000143}
144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000145PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
Guido van Rossum049cd901996-12-05 23:30:48 +0000146
147static PyObject *
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000148IO_isatty(IOobject *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000149 if (!IO__opencheck(self)) return NULL;
150 Py_INCREF(Py_False);
151 return Py_False;
Guido van Rossum049cd901996-12-05 23:30:48 +0000152}
153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000154PyDoc_STRVAR(IO_read__doc__,
155"read([s]) -- Read s characters, or the rest of the string");
Guido van Rossum049cd901996-12-05 23:30:48 +0000156
157static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000158IO_cread(PyObject *self, char **output, Py_ssize_t n) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000159 Py_ssize_t l;
Guido van Rossum049cd901996-12-05 23:30:48 +0000160
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000161 if (!IO__opencheck(IOOOBJECT(self))) return -1;
162 assert(IOOOBJECT(self)->pos >= 0);
163 assert(IOOOBJECT(self)->string_size >= 0);
164 l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
165 if (n < 0 || n > l) {
166 n = l;
167 if (n < 0) n=0;
168 }
Guido van Rossum049cd901996-12-05 23:30:48 +0000169
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000170 *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
171 ((IOobject*)self)->pos += n;
172 return n;
Guido van Rossum049cd901996-12-05 23:30:48 +0000173}
174
175static PyObject *
Jim Fultone60de4d2000-10-06 19:24:23 +0000176IO_read(IOobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000177 Py_ssize_t n = -1;
178 char *output = NULL;
Guido van Rossum049cd901996-12-05 23:30:48 +0000179
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000180 if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
Guido van Rossum049cd901996-12-05 23:30:48 +0000181
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000182 if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
Guido van Rossum049cd901996-12-05 23:30:48 +0000183
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000184 return PyString_FromStringAndSize(output, n);
Guido van Rossum049cd901996-12-05 23:30:48 +0000185}
186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000187PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
Guido van Rossum049cd901996-12-05 23:30:48 +0000188
189static int
Jim Fultone60de4d2000-10-06 19:24:23 +0000190IO_creadline(PyObject *self, char **output) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000191 char *n, *s;
192 Py_ssize_t l;
Guido van Rossum049cd901996-12-05 23:30:48 +0000193
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000194 if (!IO__opencheck(IOOOBJECT(self))) return -1;
Jim Fultone60de4d2000-10-06 19:24:23 +0000195
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000196 for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
197 s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
198 n < s && *n != '\n'; n++);
Gregory P. Smith9d534572008-06-11 07:41:16 +0000199
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000200 if (n < s) n++;
Jim Fultone60de4d2000-10-06 19:24:23 +0000201
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000202 *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
203 l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
Gregory P. Smith9d534572008-06-11 07:41:16 +0000204
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000205 assert(IOOOBJECT(self)->pos <= PY_SSIZE_T_MAX - l);
206 assert(IOOOBJECT(self)->pos >= 0);
207 assert(IOOOBJECT(self)->string_size >= 0);
Gregory P. Smith9d534572008-06-11 07:41:16 +0000208
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000209 ((IOobject*)self)->pos += l;
210 return (int)l;
Guido van Rossum049cd901996-12-05 23:30:48 +0000211}
212
213static PyObject *
Jim Fultone60de4d2000-10-06 19:24:23 +0000214IO_readline(IOobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 int n, m=-1;
216 char *output;
Guido van Rossum049cd901996-12-05 23:30:48 +0000217
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000218 if (args)
219 if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000220
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000221 if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
222 if (m >= 0 && m < n) {
223 m = n - m;
224 n -= m;
225 self->pos -= m;
226 }
227 assert(IOOOBJECT(self)->pos >= 0);
228 return PyString_FromStringAndSize(output, n);
Guido van Rossum049cd901996-12-05 23:30:48 +0000229}
230
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000231PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
Martin v. Löwisc912a3a2000-09-19 11:06:46 +0000232
233static PyObject *
Jim Fultone60de4d2000-10-06 19:24:23 +0000234IO_readlines(IOobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000235 int n;
236 char *output;
237 PyObject *result, *line;
238 int hint = 0, length = 0;
Jim Fultone60de4d2000-10-06 19:24:23 +0000239
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000240 if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
Martin v. Löwisc912a3a2000-09-19 11:06:46 +0000241
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000242 result = PyList_New(0);
243 if (!result)
Jim Fultone60de4d2000-10-06 19:24:23 +0000244 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000245
246 while (1){
247 if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
248 goto err;
249 if (n == 0)
250 break;
251 line = PyString_FromStringAndSize (output, n);
252 if (!line)
253 goto err;
254 if (PyList_Append (result, line) == -1) {
255 Py_DECREF (line);
256 goto err;
257 }
258 Py_DECREF (line);
259 length += n;
260 if (hint > 0 && length >= hint)
261 break;
262 }
263 return result;
264 err:
265 Py_DECREF(result);
266 return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000267}
268
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000269PyDoc_STRVAR(IO_reset__doc__,
270"reset() -- Reset the file position to the beginning");
Jim Fultone60de4d2000-10-06 19:24:23 +0000271
272static PyObject *
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000273IO_reset(IOobject *self, PyObject *unused) {
Jim Fultone60de4d2000-10-06 19:24:23 +0000274
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000275 if (!IO__opencheck(self)) return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000276
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000277 self->pos = 0;
Jim Fultone60de4d2000-10-06 19:24:23 +0000278
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000279 Py_INCREF(Py_None);
280 return Py_None;
Jim Fultone60de4d2000-10-06 19:24:23 +0000281}
282
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000283PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
Jim Fultone60de4d2000-10-06 19:24:23 +0000284
285static PyObject *
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000286IO_tell(IOobject *self, PyObject *unused) {
Jim Fultone60de4d2000-10-06 19:24:23 +0000287
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000288 if (!IO__opencheck(self)) return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000289
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000290 assert(self->pos >= 0);
291 return PyInt_FromSsize_t(self->pos);
Jim Fultone60de4d2000-10-06 19:24:23 +0000292}
293
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000294PyDoc_STRVAR(IO_truncate__doc__,
295"truncate(): truncate the file at the current position.");
Jim Fultone60de4d2000-10-06 19:24:23 +0000296
297static PyObject *
298IO_truncate(IOobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299 Py_ssize_t pos = -1;
Martin v. Löwiscffcc8b2006-11-19 10:41:41 +0000300
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000301 if (!IO__opencheck(self)) return NULL;
302 if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
Martin v. Löwiscffcc8b2006-11-19 10:41:41 +0000303
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000304 if (PyTuple_Size(args) == 0) {
305 /* No argument passed, truncate to current position */
306 pos = self->pos;
307 }
Jim Fultone60de4d2000-10-06 19:24:23 +0000308
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000309 if (pos < 0) {
310 errno = EINVAL;
311 PyErr_SetFromErrno(PyExc_IOError);
312 return NULL;
313 }
Jim Fultone60de4d2000-10-06 19:24:23 +0000314
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000315 if (self->string_size > pos) self->string_size = pos;
316 self->pos = self->string_size;
317
318 Py_INCREF(Py_None);
319 return Py_None;
Jim Fultone60de4d2000-10-06 19:24:23 +0000320}
321
Raymond Hettinger352f9472003-04-24 15:50:11 +0000322static PyObject *
323IO_iternext(Iobject *self)
324{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000325 PyObject *next;
326 next = IO_readline((IOobject *)self, NULL);
327 if (!next)
328 return NULL;
329 if (!PyString_GET_SIZE(next)) {
330 Py_DECREF(next);
331 PyErr_SetNone(PyExc_StopIteration);
332 return NULL;
333 }
334 return next;
Raymond Hettinger352f9472003-04-24 15:50:11 +0000335}
336
Jim Fultone60de4d2000-10-06 19:24:23 +0000337
338
339
340/* Read-write object methods */
341
Fred Drake577acb42010-10-11 19:13:04 +0000342PyDoc_STRVAR(IO_seek__doc__,
Jim Fultone60de4d2000-10-06 19:24:23 +0000343"seek(position) -- set the current position\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000344"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
Jim Fultone60de4d2000-10-06 19:24:23 +0000345
346static PyObject *
Fred Drake577acb42010-10-11 19:13:04 +0000347IO_seek(Iobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000348 Py_ssize_t position;
349 int mode = 0;
Jim Fultone60de4d2000-10-06 19:24:23 +0000350
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 if (!IO__opencheck(IOOOBJECT(self))) return NULL;
352 if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode))
353 return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000354
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000355 if (mode == 2) {
356 position += self->string_size;
357 }
358 else if (mode == 1) {
359 position += self->pos;
360 }
Jim Fultone60de4d2000-10-06 19:24:23 +0000361
Fred Drake577acb42010-10-11 19:13:04 +0000362 if (position < 0) position=0;
Jim Fultone60de4d2000-10-06 19:24:23 +0000363
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000364 self->pos=position;
Jim Fultone60de4d2000-10-06 19:24:23 +0000365
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000366 Py_INCREF(Py_None);
367 return Py_None;
Martin v. Löwisc912a3a2000-09-19 11:06:46 +0000368}
369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000370PyDoc_STRVAR(O_write__doc__,
Guido van Rossum049cd901996-12-05 23:30:48 +0000371"write(s) -- Write a string to the file"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000372"\n\nNote (hack:) writing None resets the buffer");
Guido van Rossum049cd901996-12-05 23:30:48 +0000373
374
375static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000376O_cwrite(PyObject *self, const char *c, Py_ssize_t l) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000377 Py_ssize_t newl;
378 Oobject *oself;
379 char *newbuf;
Guido van Rossum55702f81997-01-06 22:57:52 +0000380
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000381 if (!IO__opencheck(IOOOBJECT(self))) return -1;
382 oself = (Oobject *)self;
Guido van Rossum049cd901996-12-05 23:30:48 +0000383
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000384 newl = oself->pos+l;
385 if (newl >= oself->buf_size) {
386 oself->buf_size *= 2;
387 if (oself->buf_size <= newl) {
388 assert(newl + 1 < INT_MAX);
389 oself->buf_size = (int)(newl+1);
Guido van Rossum2f098122001-12-07 20:20:28 +0000390 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000391 newbuf = (char*)realloc(oself->buf, oself->buf_size);
392 if (!newbuf) {
393 PyErr_SetString(PyExc_MemoryError,"out of memory");
394 free(oself->buf);
395 oself->buf = 0;
396 oself->buf_size = oself->pos = 0;
397 return -1;
398 }
399 oself->buf = newbuf;
400 }
Jim Fultone60de4d2000-10-06 19:24:23 +0000401
Fred Drake577acb42010-10-11 19:13:04 +0000402 if (oself->string_size < oself->pos) {
403 /* In case of overseek, pad with null bytes the buffer region between
404 the end of stream and the current position.
405
406 0 lo string_size hi
407 | |<---used--->|<----------available----------->|
408 | | <--to pad-->|<---to write---> |
409 0 buf position
410 */
411 memset(oself->buf + oself->string_size, '\0',
412 (oself->pos - oself->string_size) * sizeof(char));
413 }
414
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000415 memcpy(oself->buf+oself->pos,c,l);
416
417 assert(oself->pos + l < INT_MAX);
418 oself->pos += (int)l;
419
420 if (oself->string_size < oself->pos) {
421 oself->string_size = oself->pos;
422 }
423
424 return (int)l;
Guido van Rossum049cd901996-12-05 23:30:48 +0000425}
426
427static PyObject *
Guido van Rossum154417e1997-04-09 17:35:33 +0000428O_write(Oobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000429 char *c;
430 int l;
Guido van Rossum049cd901996-12-05 23:30:48 +0000431
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000432 if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
Guido van Rossum049cd901996-12-05 23:30:48 +0000433
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000434 if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
Guido van Rossum049cd901996-12-05 23:30:48 +0000435
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000436 Py_INCREF(Py_None);
437 return Py_None;
Guido van Rossum049cd901996-12-05 23:30:48 +0000438}
439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000440PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
Guido van Rossum049cd901996-12-05 23:30:48 +0000441
442static PyObject *
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000443O_close(Oobject *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000444 if (self->buf != NULL) free(self->buf);
445 self->buf = NULL;
Guido van Rossum049cd901996-12-05 23:30:48 +0000446
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000447 self->pos = self->string_size = self->buf_size = 0;
Guido van Rossum049cd901996-12-05 23:30:48 +0000448
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000449 Py_INCREF(Py_None);
450 return Py_None;
Guido van Rossum049cd901996-12-05 23:30:48 +0000451}
452
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000453PyDoc_STRVAR(O_writelines__doc__,
Raymond Hettinger6ec09962004-03-08 18:17:31 +0000454"writelines(sequence_of_strings) -> None. Write the strings to the file.\n"
455"\n"
456"Note that newlines are not added. The sequence can be any iterable object\n"
457"producing strings. This is equivalent to calling write() for each string.");
Guido van Rossum049cd901996-12-05 23:30:48 +0000458static PyObject *
Guido van Rossum154417e1997-04-09 17:35:33 +0000459O_writelines(Oobject *self, PyObject *args) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000460 PyObject *it, *s;
461
462 it = PyObject_GetIter(args);
463 if (it == NULL)
464 return NULL;
465 while ((s = PyIter_Next(it)) != NULL) {
466 Py_ssize_t n;
467 char *c;
468 if (PyString_AsStringAndSize(s, &c, &n) == -1) {
469 Py_DECREF(it);
470 Py_DECREF(s);
471 return NULL;
472 }
473 if (O_cwrite((PyObject *)self, c, n) == -1) {
474 Py_DECREF(it);
475 Py_DECREF(s);
476 return NULL;
477 }
478 Py_DECREF(s);
Michael W. Hudson10402a32005-09-22 09:19:01 +0000479 }
Guido van Rossum049cd901996-12-05 23:30:48 +0000480
Michael W. Hudson10402a32005-09-22 09:19:01 +0000481 Py_DECREF(it);
482
483 /* See if PyIter_Next failed */
484 if (PyErr_Occurred())
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000485 return NULL;
Michael W. Hudson10402a32005-09-22 09:19:01 +0000486
487 Py_RETURN_NONE;
488}
Guido van Rossum049cd901996-12-05 23:30:48 +0000489static struct PyMethodDef O_methods[] = {
Jim Fultone60de4d2000-10-06 19:24:23 +0000490 /* Common methods: */
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000491 {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
Jim Fultone60de4d2000-10-06 19:24:23 +0000492 {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000493 {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000494 {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
495 {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
496 {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
497 {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
Fred Drake577acb42010-10-11 19:13:04 +0000498 {"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000499 {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
Jim Fultone60de4d2000-10-06 19:24:23 +0000500 {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
501
502 /* Read-write StringIO specific methods: */
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000503 {"close", (PyCFunction)O_close, METH_NOARGS, O_close__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000504 {"write", (PyCFunction)O_write, METH_VARARGS, O_write__doc__},
505 {"writelines", (PyCFunction)O_writelines, METH_O, O_writelines__doc__},
506 {NULL, NULL} /* sentinel */
Guido van Rossum049cd901996-12-05 23:30:48 +0000507};
508
Raymond Hettinger352f9472003-04-24 15:50:11 +0000509static PyMemberDef O_memberlist[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000510 {"softspace", T_INT, offsetof(Oobject, softspace), 0,
511 "flag indicating that a space needs to be printed; used by print"},
512 /* getattr(f, "closed") is implemented without this table */
513 {NULL} /* Sentinel */
Raymond Hettinger352f9472003-04-24 15:50:11 +0000514};
515
Guido van Rossum049cd901996-12-05 23:30:48 +0000516static void
Guido van Rossum154417e1997-04-09 17:35:33 +0000517O_dealloc(Oobject *self) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000518 if (self->buf != NULL)
519 free(self->buf);
520 PyObject_Del(self);
Guido van Rossum049cd901996-12-05 23:30:48 +0000521}
522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000523PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
Guido van Rossum049cd901996-12-05 23:30:48 +0000524
525static PyTypeObject Otype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000526 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000527 "cStringIO.StringO", /*tp_name*/
528 sizeof(Oobject), /*tp_basicsize*/
529 0, /*tp_itemsize*/
Guido van Rossum154417e1997-04-09 17:35:33 +0000530 /* methods */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000531 (destructor)O_dealloc, /*tp_dealloc*/
532 0, /*tp_print*/
533 0, /*tp_getattr */
534 0, /*tp_setattr */
535 0, /*tp_compare*/
536 0, /*tp_repr*/
537 0, /*tp_as_number*/
538 0, /*tp_as_sequence*/
539 0, /*tp_as_mapping*/
540 0, /*tp_hash*/
541 0 , /*tp_call*/
542 0, /*tp_str*/
543 0, /*tp_getattro */
544 0, /*tp_setattro */
545 0, /*tp_as_buffer */
546 Py_TPFLAGS_DEFAULT, /*tp_flags*/
547 Otype__doc__, /*tp_doc */
548 0, /*tp_traverse */
549 0, /*tp_clear */
550 0, /*tp_richcompare */
551 0, /*tp_weaklistoffset */
552 PyObject_SelfIter, /*tp_iter */
553 (iternextfunc)IO_iternext, /*tp_iternext */
554 O_methods, /*tp_methods */
555 O_memberlist, /*tp_members */
556 file_getsetlist, /*tp_getset */
Guido van Rossum049cd901996-12-05 23:30:48 +0000557};
558
Guido van Rossum142eeb81997-08-13 03:14:41 +0000559static PyObject *
560newOobject(int size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000561 Oobject *self;
Guido van Rossum142eeb81997-08-13 03:14:41 +0000562
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000563 self = PyObject_New(Oobject, &Otype);
564 if (self == NULL)
565 return NULL;
566 self->pos=0;
567 self->string_size = 0;
568 self->softspace = 0;
Guido van Rossum142eeb81997-08-13 03:14:41 +0000569
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000570 self->buf = (char *)malloc(size);
571 if (!self->buf) {
572 PyErr_SetString(PyExc_MemoryError,"out of memory");
573 self->buf_size = 0;
574 Py_DECREF(self);
575 return NULL;
576 }
Jim Fultone60de4d2000-10-06 19:24:23 +0000577
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000578 self->buf_size=size;
579 return (PyObject*)self;
Guido van Rossum142eeb81997-08-13 03:14:41 +0000580}
581
Skip Montanaroe1388282003-08-11 13:15:11 +0000582/* End of code for StringO objects */
Guido van Rossum049cd901996-12-05 23:30:48 +0000583/* -------------------------------------------------------- */
584
585static PyObject *
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000586I_close(Iobject *self, PyObject *unused) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000587 Py_CLEAR(self->pbuf);
588 self->buf = NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000589
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000590 self->pos = self->string_size = 0;
Jim Fultone60de4d2000-10-06 19:24:23 +0000591
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000592 Py_INCREF(Py_None);
593 return Py_None;
Guido van Rossum476e49f1998-12-15 21:43:15 +0000594}
595
Guido van Rossum049cd901996-12-05 23:30:48 +0000596static struct PyMethodDef I_methods[] = {
Jim Fultone60de4d2000-10-06 19:24:23 +0000597 /* Common methods: */
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000598 {"flush", (PyCFunction)IO_flush, METH_NOARGS, IO_flush__doc__},
Jim Fultone60de4d2000-10-06 19:24:23 +0000599 {"getvalue", (PyCFunction)IO_getval, METH_VARARGS, IO_getval__doc__},
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000600 {"isatty", (PyCFunction)IO_isatty, METH_NOARGS, IO_isatty__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000601 {"read", (PyCFunction)IO_read, METH_VARARGS, IO_read__doc__},
602 {"readline", (PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
603 {"readlines", (PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
604 {"reset", (PyCFunction)IO_reset, METH_NOARGS, IO_reset__doc__},
Fred Drake577acb42010-10-11 19:13:04 +0000605 {"seek", (PyCFunction)IO_seek, METH_VARARGS, IO_seek__doc__},
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000606 {"tell", (PyCFunction)IO_tell, METH_NOARGS, IO_tell__doc__},
Jim Fultone60de4d2000-10-06 19:24:23 +0000607 {"truncate", (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
608
609 /* Read-only StringIO specific methods: */
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000610 {"close", (PyCFunction)I_close, METH_NOARGS, O_close__doc__},
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000611 {NULL, NULL}
Guido van Rossum049cd901996-12-05 23:30:48 +0000612};
613
Guido van Rossum049cd901996-12-05 23:30:48 +0000614static void
Guido van Rossum154417e1997-04-09 17:35:33 +0000615I_dealloc(Iobject *self) {
Guido van Rossum15a40391997-09-03 00:09:26 +0000616 Py_XDECREF(self->pbuf);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000617 PyObject_Del(self);
Guido van Rossum049cd901996-12-05 23:30:48 +0000618}
619
Barry Warsaw3e8be722001-09-22 04:36:49 +0000620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000621PyDoc_STRVAR(Itype__doc__,
622"Simple type for treating strings as input file streams");
Guido van Rossum049cd901996-12-05 23:30:48 +0000623
624static PyTypeObject Itype = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000625 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000626 "cStringIO.StringI", /*tp_name*/
627 sizeof(Iobject), /*tp_basicsize*/
628 0, /*tp_itemsize*/
Guido van Rossum154417e1997-04-09 17:35:33 +0000629 /* methods */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000630 (destructor)I_dealloc, /*tp_dealloc*/
631 0, /*tp_print*/
632 0, /* tp_getattr */
633 0, /*tp_setattr*/
634 0, /*tp_compare*/
635 0, /*tp_repr*/
636 0, /*tp_as_number*/
637 0, /*tp_as_sequence*/
638 0, /*tp_as_mapping*/
639 0, /*tp_hash*/
640 0, /*tp_call*/
641 0, /*tp_str*/
642 0, /* tp_getattro */
643 0, /* tp_setattro */
644 0, /* tp_as_buffer */
645 Py_TPFLAGS_DEFAULT, /* tp_flags */
646 Itype__doc__, /* tp_doc */
647 0, /* tp_traverse */
648 0, /* tp_clear */
649 0, /* tp_richcompare */
650 0, /* tp_weaklistoffset */
651 PyObject_SelfIter, /* tp_iter */
652 (iternextfunc)IO_iternext, /* tp_iternext */
653 I_methods, /* tp_methods */
654 0, /* tp_members */
655 file_getsetlist, /* tp_getset */
Guido van Rossum049cd901996-12-05 23:30:48 +0000656};
657
Guido van Rossum142eeb81997-08-13 03:14:41 +0000658static PyObject *
659newIobject(PyObject *s) {
660 Iobject *self;
661 char *buf;
Martin v. Löwis18e16552006-02-15 17:27:45 +0000662 Py_ssize_t size;
Jeremy Hylton127b2ef2000-04-12 22:04:01 +0000663
Antoine Pitrou5a77fe92011-10-22 21:26:01 +0200664 if (PyUnicode_Check(s)) {
665 if (PyObject_AsCharBuffer(s, (const char **)&buf, &size) != 0)
666 return NULL;
667 }
668 else if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
Georg Brandl96164442007-08-08 13:03:41 +0000669 PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
670 s->ob_type->tp_name);
671 return NULL;
672 }
Georg Brandl5597e262006-10-12 09:47:12 +0000673
Martin v. Löwis5df2e612006-03-01 23:10:49 +0000674 self = PyObject_New(Iobject, &Itype);
675 if (!self) return NULL;
Guido van Rossum142eeb81997-08-13 03:14:41 +0000676 Py_INCREF(s);
677 self->buf=buf;
678 self->string_size=size;
679 self->pbuf=s;
680 self->pos=0;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000681
Guido van Rossum142eeb81997-08-13 03:14:41 +0000682 return (PyObject*)self;
683}
684
Guido van Rossum049cd901996-12-05 23:30:48 +0000685/* End of code for StringI objects */
686/* -------------------------------------------------------- */
687
688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000689PyDoc_STRVAR(IO_StringIO__doc__,
690"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
Guido van Rossum049cd901996-12-05 23:30:48 +0000691
692static PyObject *
Guido van Rossum154417e1997-04-09 17:35:33 +0000693IO_StringIO(PyObject *self, PyObject *args) {
Guido van Rossum049cd901996-12-05 23:30:48 +0000694 PyObject *s=0;
695
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000696 if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
Jim Fultone60de4d2000-10-06 19:24:23 +0000697
698 if (s) return newIobject(s);
Guido van Rossum154417e1997-04-09 17:35:33 +0000699 return newOobject(128);
Guido van Rossum049cd901996-12-05 23:30:48 +0000700}
701
702/* List of methods defined in the module */
703
704static struct PyMethodDef IO_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000705 {"StringIO", (PyCFunction)IO_StringIO,
706 METH_VARARGS, IO_StringIO__doc__},
707 {NULL, NULL} /* sentinel */
Guido van Rossum049cd901996-12-05 23:30:48 +0000708};
709
710
711/* Initialization function for the module (*must* be called initcStringIO) */
712
Guido van Rossum154417e1997-04-09 17:35:33 +0000713static struct PycStringIO_CAPI CAPI = {
Jim Fultone60de4d2000-10-06 19:24:23 +0000714 IO_cread,
715 IO_creadline,
Guido van Rossum154417e1997-04-09 17:35:33 +0000716 O_cwrite,
Jim Fultone60de4d2000-10-06 19:24:23 +0000717 IO_cgetval,
Guido van Rossum154417e1997-04-09 17:35:33 +0000718 newOobject,
719 newIobject,
720 &Itype,
721 &Otype,
722};
723
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000724#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000725#define PyMODINIT_FUNC void
Guido van Rossum476e49f1998-12-15 21:43:15 +0000726#endif
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000727PyMODINIT_FUNC
Thomas Wouters58d05102000-07-24 14:43:35 +0000728initcStringIO(void) {
Guido van Rossum9efe8ef1997-09-03 18:19:40 +0000729 PyObject *m, *d, *v;
Guido van Rossum049cd901996-12-05 23:30:48 +0000730
Guido van Rossum154417e1997-04-09 17:35:33 +0000731
Guido van Rossum049cd901996-12-05 23:30:48 +0000732 /* Create the module and add the functions */
733 m = Py_InitModule4("cStringIO", IO_methods,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000734 cStringIO_module_documentation,
735 (PyObject*)NULL,PYTHON_API_VERSION);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000736 if (m == NULL) return;
Guido van Rossum049cd901996-12-05 23:30:48 +0000737
738 /* Add some symbolic constants to the module */
739 d = PyModule_GetDict(m);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000740
Guido van Rossum55702f81997-01-06 22:57:52 +0000741 /* Export C API */
Christian Heimese93237d2007-12-19 02:37:44 +0000742 Py_TYPE(&Itype)=&PyType_Type;
743 Py_TYPE(&Otype)=&PyType_Type;
Raymond Hettinger352f9472003-04-24 15:50:11 +0000744 if (PyType_Ready(&Otype) < 0) return;
745 if (PyType_Ready(&Itype) < 0) return;
Larry Hastings402b73f2010-03-25 00:54:54 +0000746 v = PyCapsule_New(&CAPI, PycStringIO_CAPSULE_NAME, NULL);
747 PyDict_SetItemString(d,"cStringIO_CAPI", v);
Guido van Rossum9efe8ef1997-09-03 18:19:40 +0000748 Py_XDECREF(v);
Guido van Rossum154417e1997-04-09 17:35:33 +0000749
750 /* Export Types */
Guido van Rossum049cd901996-12-05 23:30:48 +0000751 PyDict_SetItemString(d,"InputType", (PyObject*)&Itype);
752 PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
Guido van Rossum142eeb81997-08-13 03:14:41 +0000753
754 /* Maybe make certain warnings go away */
Jim Fultone60de4d2000-10-06 19:24:23 +0000755 if (0) PycString_IMPORT;
Guido van Rossum049cd901996-12-05 23:30:48 +0000756}