blob: 73018a539071b032ea3a8beda966776228532d2e [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001#define PY_SSIZE_T_CLEAN
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00002#include "Python.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003#include "structmember.h"
Antoine Pitroud0acb412012-03-22 14:42:18 +01004#include "accu.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00005#include "_iomodule.h"
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00007/* Implementation note: the buffer is always at least one character longer
8 than the enclosed string, for proper functioning of _PyIO_find_line_ending.
9*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000010
Antoine Pitroude20b0b2011-11-10 21:47:38 +010011#define STATE_REALIZED 1
12#define STATE_ACCUMULATING 2
13
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030014/*[clinic input]
15module _io
16class _io.StringIO "stringio *" "&PyStringIO_Type"
17[clinic start generated code]*/
18/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c17bc0f42165cd7d]*/
19
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000020typedef struct {
21 PyObject_HEAD
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020022 Py_UCS4 *buf;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000023 Py_ssize_t pos;
24 Py_ssize_t string_size;
25 size_t buf_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000026
Antoine Pitroude20b0b2011-11-10 21:47:38 +010027 /* The stringio object can be in two states: accumulating or realized.
28 In accumulating state, the internal buffer contains nothing and
29 the contents are given by the embedded _PyAccu structure.
30 In realized state, the internal buffer is meaningful and the
31 _PyAccu is destroyed.
32 */
33 int state;
34 _PyAccu accu;
35
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000036 char ok; /* initialized? */
37 char closed;
38 char readuniversal;
39 char readtranslate;
40 PyObject *decoder;
41 PyObject *readnl;
42 PyObject *writenl;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020043
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000044 PyObject *dict;
45 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000046} stringio;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000047
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030048static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs);
49
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000050#define CHECK_INITIALIZED(self) \
51 if (self->ok <= 0) { \
52 PyErr_SetString(PyExc_ValueError, \
53 "I/O operation on uninitialized object"); \
54 return NULL; \
55 }
56
57#define CHECK_CLOSED(self) \
58 if (self->closed) { \
59 PyErr_SetString(PyExc_ValueError, \
60 "I/O operation on closed file"); \
61 return NULL; \
62 }
63
Antoine Pitroude20b0b2011-11-10 21:47:38 +010064#define ENSURE_REALIZED(self) \
65 if (realize(self) < 0) { \
66 return NULL; \
67 }
68
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000069
70/* Internal routine for changing the size, in terms of characters, of the
71 buffer of StringIO objects. The caller should ensure that the 'size'
72 argument is non-negative. Returns 0 on success, -1 otherwise. */
73static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000074resize_buffer(stringio *self, size_t size)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000075{
76 /* Here, unsigned types are used to avoid dealing with signed integer
77 overflow, which is undefined in C. */
78 size_t alloc = self->buf_size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020079 Py_UCS4 *new_buf = NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000080
81 assert(self->buf != NULL);
82
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000083 /* Reserve one more char for line ending detection. */
84 size = size + 1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000085 /* For simplicity, stay in the range of the signed type. Anyway, Python
86 doesn't allow strings to be longer than this. */
87 if (size > PY_SSIZE_T_MAX)
88 goto overflow;
89
90 if (size < alloc / 2) {
91 /* Major downsize; resize down to exact size. */
92 alloc = size + 1;
93 }
94 else if (size < alloc) {
95 /* Within allocated size; quick exit */
96 return 0;
97 }
98 else if (size <= alloc * 1.125) {
99 /* Moderate upsize; overallocate similar to list_resize() */
100 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
101 }
102 else {
103 /* Major upsize; resize up to exact size */
104 alloc = size + 1;
105 }
106
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200107 if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4))
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000108 goto overflow;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200109 new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000110 if (new_buf == NULL) {
111 PyErr_NoMemory();
112 return -1;
113 }
114 self->buf_size = alloc;
115 self->buf = new_buf;
116
117 return 0;
118
119 overflow:
120 PyErr_SetString(PyExc_OverflowError,
121 "new buffer size too large");
122 return -1;
123}
124
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100125static PyObject *
126make_intermediate(stringio *self)
127{
128 PyObject *intermediate = _PyAccu_Finish(&self->accu);
129 self->state = STATE_REALIZED;
130 if (intermediate == NULL)
131 return NULL;
132 if (_PyAccu_Init(&self->accu) ||
133 _PyAccu_Accumulate(&self->accu, intermediate)) {
134 Py_DECREF(intermediate);
135 return NULL;
136 }
137 self->state = STATE_ACCUMULATING;
138 return intermediate;
139}
140
141static int
142realize(stringio *self)
143{
144 Py_ssize_t len;
145 PyObject *intermediate;
146
147 if (self->state == STATE_REALIZED)
148 return 0;
149 assert(self->state == STATE_ACCUMULATING);
150 self->state = STATE_REALIZED;
151
152 intermediate = _PyAccu_Finish(&self->accu);
153 if (intermediate == NULL)
154 return -1;
155
156 /* Append the intermediate string to the internal buffer.
157 The length should be equal to the current cursor position.
158 */
159 len = PyUnicode_GET_LENGTH(intermediate);
160 if (resize_buffer(self, len) < 0) {
161 Py_DECREF(intermediate);
162 return -1;
163 }
164 if (!PyUnicode_AsUCS4(intermediate, self->buf, len, 0)) {
165 Py_DECREF(intermediate);
166 return -1;
167 }
168
169 Py_DECREF(intermediate);
170 return 0;
171}
172
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000173/* Internal routine for writing a whole PyUnicode object to the buffer of a
174 StringIO object. Returns 0 on success, or -1 on error. */
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000175static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000176write_str(stringio *self, PyObject *obj)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000177{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000178 Py_ssize_t len;
179 PyObject *decoded = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200180
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000181 assert(self->buf != NULL);
182 assert(self->pos >= 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000183
184 if (self->decoder != NULL) {
185 decoded = _PyIncrementalNewlineDecoder_decode(
186 self->decoder, obj, 1 /* always final */);
187 }
188 else {
189 decoded = obj;
190 Py_INCREF(decoded);
191 }
192 if (self->writenl) {
193 PyObject *translated = PyUnicode_Replace(
194 decoded, _PyIO_str_nl, self->writenl, -1);
195 Py_DECREF(decoded);
196 decoded = translated;
197 }
198 if (decoded == NULL)
199 return -1;
200
201 assert(PyUnicode_Check(decoded));
Victor Stinnere1335c72011-10-04 20:53:03 +0200202 if (PyUnicode_READY(decoded)) {
203 Py_DECREF(decoded);
204 return -1;
205 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200206 len = PyUnicode_GET_LENGTH(decoded);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000207 assert(len >= 0);
208
209 /* This overflow check is not strictly necessary. However, it avoids us to
210 deal with funky things like comparing an unsigned and a signed
211 integer. */
212 if (self->pos > PY_SSIZE_T_MAX - len) {
213 PyErr_SetString(PyExc_OverflowError,
214 "new position too large");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000215 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000216 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100217
218 if (self->state == STATE_ACCUMULATING) {
219 if (self->string_size == self->pos) {
220 if (_PyAccu_Accumulate(&self->accu, decoded))
221 goto fail;
222 goto success;
223 }
224 if (realize(self))
225 goto fail;
226 }
227
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000228 if (self->pos + len > self->string_size) {
229 if (resize_buffer(self, self->pos + len) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000230 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000231 }
232
233 if (self->pos > self->string_size) {
234 /* In case of overseek, pad with null bytes the buffer region between
235 the end of stream and the current position.
236
237 0 lo string_size hi
238 | |<---used--->|<----------available----------->|
239 | | <--to pad-->|<---to write---> |
Ezio Melotti13925002011-03-16 11:05:33 +0200240 0 buf position
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000241
242 */
243 memset(self->buf + self->string_size, '\0',
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200244 (self->pos - self->string_size) * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000245 }
246
247 /* Copy the data to the internal buffer, overwriting some of the
248 existing data if self->pos < self->string_size. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200249 if (!PyUnicode_AsUCS4(decoded,
250 self->buf + self->pos,
251 self->buf_size - self->pos,
252 0))
253 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000254
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100255success:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000256 /* Set the new length of the internal string if it has changed. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200257 self->pos += len;
258 if (self->string_size < self->pos)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000259 self->string_size = self->pos;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000260
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000261 Py_DECREF(decoded);
262 return 0;
263
264fail:
265 Py_XDECREF(decoded);
266 return -1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000267}
268
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300269/*[clinic input]
270_io.StringIO.getvalue
271
272Retrieve the entire contents of the object.
273[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000274
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000275static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300276_io_StringIO_getvalue_impl(stringio *self)
277/*[clinic end generated code: output=27b6a7bfeaebce01 input=d23cb81d6791cf88]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000278{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000279 CHECK_INITIALIZED(self);
280 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100281 if (self->state == STATE_ACCUMULATING)
282 return make_intermediate(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200283 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, self->buf,
284 self->string_size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000285}
286
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300287/*[clinic input]
288_io.StringIO.tell
289
290Tell the current file position.
291[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000292
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000293static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300294_io_StringIO_tell_impl(stringio *self)
295/*[clinic end generated code: output=2e87ac67b116c77b input=ec866ebaff02f405]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000296{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000297 CHECK_INITIALIZED(self);
298 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000299 return PyLong_FromSsize_t(self->pos);
300}
301
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300302/*[clinic input]
303_io.StringIO.read
304 size as arg: object = None
305 /
306
307Read at most size characters, returned as a string.
308
309If the argument is negative or omitted, read until EOF
310is reached. Return an empty string at EOF.
311[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000312
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000313static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300314_io_StringIO_read_impl(stringio *self, PyObject *arg)
315/*[clinic end generated code: output=3676864773746f68 input=9a319015f6f3965c]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000316{
317 Py_ssize_t size, n;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200318 Py_UCS4 *output;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000319
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000320 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000321 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000322
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000323 if (PyNumber_Check(arg)) {
324 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Amaury Forgeot d'Arc58fb9052008-09-30 20:22:44 +0000325 if (size == -1 && PyErr_Occurred())
326 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000327 }
328 else if (arg == Py_None) {
329 /* Read until EOF is reached, by default. */
330 size = -1;
331 }
332 else {
333 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
334 Py_TYPE(arg)->tp_name);
335 return NULL;
336 }
337
338 /* adjust invalid sizes */
339 n = self->string_size - self->pos;
340 if (size < 0 || size > n) {
341 size = n;
342 if (size < 0)
343 size = 0;
344 }
345
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100346 /* Optimization for seek(0); read() */
347 if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) {
348 PyObject *result = make_intermediate(self);
349 self->pos = self->string_size;
350 return result;
351 }
352
353 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000354 output = self->buf + self->pos;
355 self->pos += size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200356 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000357}
358
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000359/* Internal helper, used by stringio_readline and stringio_iternext */
360static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000361_stringio_readline(stringio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000362{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200363 Py_UCS4 *start, *end, old_char;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000364 Py_ssize_t len, consumed;
365
366 /* In case of overseek, return the empty string */
367 if (self->pos >= self->string_size)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200368 return PyUnicode_New(0, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000369
370 start = self->buf + self->pos;
371 if (limit < 0 || limit > self->string_size - self->pos)
372 limit = self->string_size - self->pos;
373
374 end = start + limit;
375 old_char = *end;
376 *end = '\0';
377 len = _PyIO_find_line_ending(
378 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200379 PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000380 *end = old_char;
381 /* If we haven't found any line ending, we just return everything
382 (`consumed` is ignored). */
383 if (len < 0)
384 len = limit;
385 self->pos += len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200386 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387}
388
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300389/*[clinic input]
390_io.StringIO.readline
391 size as arg: object = None
392 /
393
394Read until newline or EOF.
395
396Returns an empty string if EOF is hit immediately.
397[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000398
399static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300400_io_StringIO_readline_impl(stringio *self, PyObject *arg)
401/*[clinic end generated code: output=99fdcac03a3dee81 input=e0e0ed4042040176]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000402{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000403 Py_ssize_t limit = -1;
404
405 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000406 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100407 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000408
409 if (PyNumber_Check(arg)) {
410 limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
411 if (limit == -1 && PyErr_Occurred())
412 return NULL;
413 }
414 else if (arg != Py_None) {
415 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
416 Py_TYPE(arg)->tp_name);
417 return NULL;
418 }
419 return _stringio_readline(self, limit);
420}
421
422static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000423stringio_iternext(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000424{
425 PyObject *line;
426
427 CHECK_INITIALIZED(self);
428 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100429 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000430
431 if (Py_TYPE(self) == &PyStringIO_Type) {
432 /* Skip method call overhead for speed */
433 line = _stringio_readline(self, -1);
434 }
435 else {
436 /* XXX is subclassing StringIO really supported? */
437 line = PyObject_CallMethodObjArgs((PyObject *)self,
438 _PyIO_str_readline, NULL);
439 if (line && !PyUnicode_Check(line)) {
440 PyErr_Format(PyExc_IOError,
441 "readline() should have returned an str object, "
442 "not '%.200s'", Py_TYPE(line)->tp_name);
443 Py_DECREF(line);
444 return NULL;
445 }
446 }
447
448 if (line == NULL)
449 return NULL;
450
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200451 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000452 /* Reached EOF */
453 Py_DECREF(line);
454 return NULL;
455 }
456
457 return line;
458}
459
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300460/*[clinic input]
461_io.StringIO.truncate
462 pos as arg: object = None
463 /
464
465Truncate size to pos.
466
467The pos argument defaults to the current file position, as
468returned by tell(). The current file position is unchanged.
469Returns the new absolute position.
470[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000471
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000472static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300473_io_StringIO_truncate_impl(stringio *self, PyObject *arg)
474/*[clinic end generated code: output=6072439c2b01d306 input=748619a494ba53ad]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000475{
476 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000477
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000478 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000479 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000480
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000481 if (PyNumber_Check(arg)) {
482 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Benjamin Petersonc9e435e2008-09-30 02:22:04 +0000483 if (size == -1 && PyErr_Occurred())
484 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000485 }
486 else if (arg == Py_None) {
487 /* Truncate to current position if no argument is passed. */
488 size = self->pos;
489 }
490 else {
491 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
492 Py_TYPE(arg)->tp_name);
493 return NULL;
494 }
495
496 if (size < 0) {
497 PyErr_Format(PyExc_ValueError,
498 "Negative size value %zd", size);
499 return NULL;
500 }
501
502 if (size < self->string_size) {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100503 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000504 if (resize_buffer(self, size) < 0)
505 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506 self->string_size = size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000507 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000508
509 return PyLong_FromSsize_t(size);
510}
511
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300512/*[clinic input]
513_io.StringIO.seek
514 pos: Py_ssize_t
515 whence: int = 0
516 /
517
518Change stream position.
519
520Seek to character offset pos relative to position indicated by whence:
521 0 Start of stream (the default). pos should be >= 0;
522 1 Current position - pos must be 0;
523 2 End of stream - pos must be 0.
524Returns the new absolute position.
525[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000526
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000527static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300528_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence)
529/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000530{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000531 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000532 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000533
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300534 if (whence != 0 && whence != 1 && whence != 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000535 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300536 "Invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000537 return NULL;
538 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300539 else if (pos < 0 && whence == 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000540 PyErr_Format(PyExc_ValueError,
541 "Negative seek position %zd", pos);
542 return NULL;
543 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300544 else if (whence != 0 && pos != 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000545 PyErr_SetString(PyExc_IOError,
546 "Can't do nonzero cur-relative seeks");
547 return NULL;
548 }
549
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300550 /* whence = 0: offset relative to beginning of the string.
551 whence = 1: no change to current position.
552 whence = 2: change position to end of file. */
553 if (whence == 1) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000554 pos = self->pos;
555 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300556 else if (whence == 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000557 pos = self->string_size;
558 }
559
560 self->pos = pos;
561
562 return PyLong_FromSsize_t(self->pos);
563}
564
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300565/*[clinic input]
566_io.StringIO.write
567 s as obj: object
568 /
569
570Write string to file.
571
572Returns the number of characters written, which is always equal to
573the length of the string.
574[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000576static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300577_io_StringIO_write(stringio *self, PyObject *obj)
578/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000579{
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000580 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000581
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582 CHECK_INITIALIZED(self);
583 if (!PyUnicode_Check(obj)) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000584 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
585 Py_TYPE(obj)->tp_name);
586 return NULL;
587 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200588 if (PyUnicode_READY(obj))
589 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590 CHECK_CLOSED(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200591 size = PyUnicode_GET_LENGTH(obj);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000592
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593 if (size > 0 && write_str(self, obj) < 0)
594 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000595
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000596 return PyLong_FromSsize_t(size);
597}
598
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300599/*[clinic input]
600_io.StringIO.close
601
602Close the IO object.
603
604Attempting any further operation after the object is closed
605will raise a ValueError.
606
607This method has no effect if the file is already closed.
608[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609
610static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300611_io_StringIO_close_impl(stringio *self)
612/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000613{
614 self->closed = 1;
615 /* Free up some memory */
616 if (resize_buffer(self, 0) < 0)
617 return NULL;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100618 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619 Py_CLEAR(self->readnl);
620 Py_CLEAR(self->writenl);
621 Py_CLEAR(self->decoder);
622 Py_RETURN_NONE;
623}
624
625static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000626stringio_traverse(stringio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000627{
628 Py_VISIT(self->dict);
629 return 0;
630}
631
632static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000633stringio_clear(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000634{
635 Py_CLEAR(self->dict);
636 return 0;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000637}
638
639static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000640stringio_dealloc(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000641{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000642 _PyObject_GC_UNTRACK(self);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000643 self->ok = 0;
644 if (self->buf) {
645 PyMem_Free(self->buf);
646 self->buf = NULL;
647 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100648 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649 Py_CLEAR(self->readnl);
650 Py_CLEAR(self->writenl);
651 Py_CLEAR(self->decoder);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000652 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653 if (self->weakreflist != NULL)
654 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000655 Py_TYPE(self)->tp_free(self);
656}
657
658static PyObject *
659stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
660{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000661 stringio *self;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000662
663 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000664 self = (stringio *)type->tp_alloc(type, 0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000665 if (self == NULL)
666 return NULL;
667
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000668 /* tp_alloc initializes all the fields to zero. So we don't have to
669 initialize them here. */
670
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200671 self->buf = (Py_UCS4 *)PyMem_Malloc(0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000672 if (self->buf == NULL) {
673 Py_DECREF(self);
674 return PyErr_NoMemory();
675 }
676
677 return (PyObject *)self;
678}
679
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300680/*[clinic input]
681_io.StringIO.__init__
682 initial_value as value: object(c_default="NULL") = ''
683 newline as newline_obj: object(c_default="NULL") = '\n'
684
685Text I/O implementation using an in-memory buffer.
686
687The initial_value argument sets the value of object. The newline
688argument is like the one of TextIOWrapper's constructor.
689[clinic start generated code]*/
690
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000691static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300692_io_StringIO___init___impl(stringio *self, PyObject *value,
693 PyObject *newline_obj)
694/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000695{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696 char *newline = "\n";
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100697 Py_ssize_t value_len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698
Martin Panterf2644162015-10-10 10:17:57 +0000699 /* Parse the newline argument. We only want to allow unicode objects or
700 None. */
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000701 if (newline_obj == Py_None) {
702 newline = NULL;
703 }
704 else if (newline_obj) {
705 if (!PyUnicode_Check(newline_obj)) {
706 PyErr_Format(PyExc_TypeError,
707 "newline must be str or None, not %.200s",
708 Py_TYPE(newline_obj)->tp_name);
709 return -1;
710 }
711 newline = _PyUnicode_AsString(newline_obj);
712 if (newline == NULL)
713 return -1;
714 }
715
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716 if (newline && newline[0] != '\0'
717 && !(newline[0] == '\n' && newline[1] == '\0')
718 && !(newline[0] == '\r' && newline[1] == '\0')
719 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
720 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000721 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000722 return -1;
723 }
724 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000725 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000726 "initial_value must be str or None, not %.200s",
727 Py_TYPE(value)->tp_name);
728 return -1;
729 }
730
731 self->ok = 0;
732
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100733 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000734 Py_CLEAR(self->readnl);
735 Py_CLEAR(self->writenl);
736 Py_CLEAR(self->decoder);
737
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000738 assert((newline != NULL && newline_obj != Py_None) ||
739 (newline == NULL && newline_obj == Py_None));
740
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 if (newline) {
742 self->readnl = PyUnicode_FromString(newline);
743 if (self->readnl == NULL)
744 return -1;
745 }
746 self->readuniversal = (newline == NULL || newline[0] == '\0');
747 self->readtranslate = (newline == NULL);
748 /* If newline == "", we don't translate anything.
749 If newline == "\n" or newline == None, we translate to "\n", which is
750 a no-op.
Martin Panter9955a372015-10-07 10:26:23 +0000751 (for newline == None, TextIOWrapper translates to os.linesep, but it
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000752 is pointless for StringIO)
753 */
754 if (newline != NULL && newline[0] == '\r') {
755 self->writenl = self->readnl;
756 Py_INCREF(self->writenl);
757 }
758
759 if (self->readuniversal) {
760 self->decoder = PyObject_CallFunction(
761 (PyObject *)&PyIncrementalNewlineDecoder_Type,
762 "Oi", Py_None, (int) self->readtranslate);
763 if (self->decoder == NULL)
764 return -1;
765 }
766
767 /* Now everything is set up, resize buffer to size of initial value,
768 and copy it */
769 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100770 if (value && value != Py_None)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100771 value_len = PyUnicode_GetLength(value);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100772 else
773 value_len = 0;
774 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000775 /* This is a heuristic, for newline translation might change
776 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100777 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100779 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000780 self->pos = 0;
781 if (write_str(self, value) < 0)
782 return -1;
783 }
784 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100785 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000786 if (resize_buffer(self, 0) < 0)
787 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100788 if (_PyAccu_Init(&self->accu))
789 return -1;
790 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000791 }
792 self->pos = 0;
793
794 self->closed = 0;
795 self->ok = 1;
796 return 0;
797}
798
799/* Properties and pseudo-properties */
Antoine Pitrou1d857452012-09-05 20:11:49 +0200800
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300801/*[clinic input]
802_io.StringIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200803
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300804Returns True if the IO object can be read.
805[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200806
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000807static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300808_io_StringIO_readable_impl(stringio *self)
809/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000810{
811 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200812 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000813 Py_RETURN_TRUE;
814}
815
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300816/*[clinic input]
817_io.StringIO.writable
818
819Returns True if the IO object can be written.
820[clinic start generated code]*/
821
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300823_io_StringIO_writable_impl(stringio *self)
824/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000825{
826 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200827 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000828 Py_RETURN_TRUE;
829}
830
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300831/*[clinic input]
832_io.StringIO.seekable
833
834Returns True if the IO object can be seeked.
835[clinic start generated code]*/
836
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000837static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300838_io_StringIO_seekable_impl(stringio *self)
839/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000840{
841 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200842 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000843 Py_RETURN_TRUE;
844}
845
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000846/* Pickling support.
847
848 The implementation of __getstate__ is similar to the one for BytesIO,
849 except that we also save the newline parameter. For __setstate__ and unlike
850 BytesIO, we call __init__ to restore the object's state. Doing so allows us
851 to avoid decoding the complex newline state while keeping the object
852 representation compact.
853
854 See comment in bytesio.c regarding why only pickle protocols and onward are
855 supported.
856*/
857
858static PyObject *
859stringio_getstate(stringio *self)
860{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300861 PyObject *initvalue = _io_StringIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000862 PyObject *dict;
863 PyObject *state;
864
865 if (initvalue == NULL)
866 return NULL;
867 if (self->dict == NULL) {
868 Py_INCREF(Py_None);
869 dict = Py_None;
870 }
871 else {
872 dict = PyDict_Copy(self->dict);
873 if (dict == NULL)
874 return NULL;
875 }
876
877 state = Py_BuildValue("(OOnN)", initvalue,
878 self->readnl ? self->readnl : Py_None,
879 self->pos, dict);
880 Py_DECREF(initvalue);
881 return state;
882}
883
884static PyObject *
885stringio_setstate(stringio *self, PyObject *state)
886{
887 PyObject *initarg;
888 PyObject *position_obj;
889 PyObject *dict;
890 Py_ssize_t pos;
891
892 assert(state != NULL);
893 CHECK_CLOSED(self);
894
895 /* We allow the state tuple to be longer than 4, because we may need
896 someday to extend the object's state without breaking
897 backward-compatibility. */
898 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
899 PyErr_Format(PyExc_TypeError,
900 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
901 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
902 return NULL;
903 }
904
905 /* Initialize the object's state. */
906 initarg = PyTuple_GetSlice(state, 0, 2);
907 if (initarg == NULL)
908 return NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300909 if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000910 Py_DECREF(initarg);
911 return NULL;
912 }
913 Py_DECREF(initarg);
914
915 /* Restore the buffer state. Even if __init__ did initialize the buffer,
916 we have to initialize it again since __init__ may translates the
917 newlines in the inital_value string. We clearly do not want that
918 because the string value in the state tuple has already been translated
919 once by __init__. So we do not take any chance and replace object's
920 buffer completely. */
921 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200922 PyObject *item;
923 Py_UCS4 *buf;
924 Py_ssize_t bufsize;
925
926 item = PyTuple_GET_ITEM(state, 0);
927 buf = PyUnicode_AsUCS4Copy(item);
928 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000929 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200930 bufsize = PyUnicode_GET_LENGTH(item);
931
932 if (resize_buffer(self, bufsize) < 0) {
933 PyMem_Free(buf);
934 return NULL;
935 }
936 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
937 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000938 self->string_size = bufsize;
939 }
940
941 /* Set carefully the position value. Alternatively, we could use the seek
942 method instead of modifying self->pos directly to better protect the
943 object internal state against errneous (or malicious) inputs. */
944 position_obj = PyTuple_GET_ITEM(state, 2);
945 if (!PyLong_Check(position_obj)) {
946 PyErr_Format(PyExc_TypeError,
947 "third item of state must be an integer, got %.200s",
948 Py_TYPE(position_obj)->tp_name);
949 return NULL;
950 }
951 pos = PyLong_AsSsize_t(position_obj);
952 if (pos == -1 && PyErr_Occurred())
953 return NULL;
954 if (pos < 0) {
955 PyErr_SetString(PyExc_ValueError,
956 "position value cannot be negative");
957 return NULL;
958 }
959 self->pos = pos;
960
961 /* Set the dictionary of the instance variables. */
962 dict = PyTuple_GET_ITEM(state, 3);
963 if (dict != Py_None) {
964 if (!PyDict_Check(dict)) {
965 PyErr_Format(PyExc_TypeError,
966 "fourth item of state should be a dict, got a %.200s",
967 Py_TYPE(dict)->tp_name);
968 return NULL;
969 }
970 if (self->dict) {
971 /* Alternatively, we could replace the internal dictionary
972 completely. However, it seems more practical to just update it. */
973 if (PyDict_Update(self->dict, dict) < 0)
974 return NULL;
975 }
976 else {
977 Py_INCREF(dict);
978 self->dict = dict;
979 }
980 }
981
982 Py_RETURN_NONE;
983}
984
985
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000986static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000987stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000988{
989 CHECK_INITIALIZED(self);
990 return PyBool_FromLong(self->closed);
991}
992
993static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000994stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000995{
996 CHECK_INITIALIZED(self);
997 CHECK_CLOSED(self);
998 Py_RETURN_FALSE;
999}
1000
1001static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001002stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001003{
1004 CHECK_INITIALIZED(self);
1005 CHECK_CLOSED(self);
1006 if (self->decoder == NULL)
1007 Py_RETURN_NONE;
1008 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
1009}
1010
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001011#include "clinic/stringio.c.h"
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001012
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001013static struct PyMethodDef stringio_methods[] = {
1014 _IO_STRINGIO_CLOSE_METHODDEF
1015 _IO_STRINGIO_GETVALUE_METHODDEF
1016 _IO_STRINGIO_READ_METHODDEF
1017 _IO_STRINGIO_READLINE_METHODDEF
1018 _IO_STRINGIO_TELL_METHODDEF
1019 _IO_STRINGIO_TRUNCATE_METHODDEF
1020 _IO_STRINGIO_SEEK_METHODDEF
1021 _IO_STRINGIO_WRITE_METHODDEF
1022
1023 _IO_STRINGIO_SEEKABLE_METHODDEF
1024 _IO_STRINGIO_READABLE_METHODDEF
1025 _IO_STRINGIO_WRITABLE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001026
1027 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
1028 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001029 {NULL, NULL} /* sentinel */
1030};
1031
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001032static PyGetSetDef stringio_getset[] = {
1033 {"closed", (getter)stringio_closed, NULL, NULL},
1034 {"newlines", (getter)stringio_newlines, NULL, NULL},
1035 /* (following comments straight off of the original Python wrapper:)
1036 XXX Cruft to support the TextIOWrapper API. This would only
1037 be meaningful if StringIO supported the buffer attribute.
1038 Hopefully, a better solution, than adding these pseudo-attributes,
1039 will be found.
1040 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001041 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001042 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001043};
1044
1045PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001046 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001048 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001049 0, /*tp_itemsize*/
1050 (destructor)stringio_dealloc, /*tp_dealloc*/
1051 0, /*tp_print*/
1052 0, /*tp_getattr*/
1053 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001054 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001055 0, /*tp_repr*/
1056 0, /*tp_as_number*/
1057 0, /*tp_as_sequence*/
1058 0, /*tp_as_mapping*/
1059 0, /*tp_hash*/
1060 0, /*tp_call*/
1061 0, /*tp_str*/
1062 0, /*tp_getattro*/
1063 0, /*tp_setattro*/
1064 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001065 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1066 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001067 _io_StringIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001068 (traverseproc)stringio_traverse, /*tp_traverse*/
1069 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001070 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001071 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001072 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001073 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001074 stringio_methods, /*tp_methods*/
1075 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001076 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001077 0, /*tp_base*/
1078 0, /*tp_dict*/
1079 0, /*tp_descr_get*/
1080 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001081 offsetof(stringio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001082 _io_StringIO___init__, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001083 0, /*tp_alloc*/
1084 stringio_new, /*tp_new*/
1085};