blob: 793fa1ee150b7a0461603d5323829e3d79aa1d70 [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"
Victor Stinnere281f7d2018-11-01 02:30:36 +01004#include "pycore_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
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300304 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300305 /
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 *
orenmn74002542017-03-11 00:52:01 +0200314_io_StringIO_read_impl(stringio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300315/*[clinic end generated code: output=ae8cf6002f71626c input=0921093383dfb92d]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000316{
orenmn74002542017-03-11 00:52:01 +0200317 Py_ssize_t 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
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000323 /* adjust invalid sizes */
324 n = self->string_size - self->pos;
325 if (size < 0 || size > n) {
326 size = n;
327 if (size < 0)
328 size = 0;
329 }
330
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100331 /* Optimization for seek(0); read() */
332 if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) {
333 PyObject *result = make_intermediate(self);
334 self->pos = self->string_size;
335 return result;
336 }
337
338 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000339 output = self->buf + self->pos;
340 self->pos += size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200341 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000342}
343
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000344/* Internal helper, used by stringio_readline and stringio_iternext */
345static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000346_stringio_readline(stringio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000347{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200348 Py_UCS4 *start, *end, old_char;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000349 Py_ssize_t len, consumed;
350
351 /* In case of overseek, return the empty string */
352 if (self->pos >= self->string_size)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200353 return PyUnicode_New(0, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354
355 start = self->buf + self->pos;
356 if (limit < 0 || limit > self->string_size - self->pos)
357 limit = self->string_size - self->pos;
358
359 end = start + limit;
360 old_char = *end;
361 *end = '\0';
362 len = _PyIO_find_line_ending(
363 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200364 PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000365 *end = old_char;
366 /* If we haven't found any line ending, we just return everything
367 (`consumed` is ignored). */
368 if (len < 0)
369 len = limit;
370 self->pos += len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200371 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000372}
373
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300374/*[clinic input]
375_io.StringIO.readline
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300376 size: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300377 /
378
379Read until newline or EOF.
380
381Returns an empty string if EOF is hit immediately.
382[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000383
384static PyObject *
orenmn74002542017-03-11 00:52:01 +0200385_io_StringIO_readline_impl(stringio *self, Py_ssize_t size)
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300386/*[clinic end generated code: output=cabd6452f1b7e85d input=a5bd70bf682aa276]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000387{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000389 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100390 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000391
orenmn74002542017-03-11 00:52:01 +0200392 return _stringio_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000393}
394
395static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000396stringio_iternext(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000397{
398 PyObject *line;
399
400 CHECK_INITIALIZED(self);
401 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100402 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000403
404 if (Py_TYPE(self) == &PyStringIO_Type) {
405 /* Skip method call overhead for speed */
406 line = _stringio_readline(self, -1);
407 }
408 else {
409 /* XXX is subclassing StringIO really supported? */
410 line = PyObject_CallMethodObjArgs((PyObject *)self,
411 _PyIO_str_readline, NULL);
412 if (line && !PyUnicode_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300413 PyErr_Format(PyExc_OSError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +0300414 "readline() should have returned a str object, "
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000415 "not '%.200s'", Py_TYPE(line)->tp_name);
416 Py_DECREF(line);
417 return NULL;
418 }
419 }
420
421 if (line == NULL)
422 return NULL;
423
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200424 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425 /* Reached EOF */
426 Py_DECREF(line);
427 return NULL;
428 }
429
430 return line;
431}
432
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300433/*[clinic input]
434_io.StringIO.truncate
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300435 pos as size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300436 /
437
438Truncate size to pos.
439
440The pos argument defaults to the current file position, as
441returned by tell(). The current file position is unchanged.
442Returns the new absolute position.
443[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000444
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000445static PyObject *
Serhiy Storchaka762bf402017-03-30 09:15:31 +0300446_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size)
447/*[clinic end generated code: output=eb3aef8e06701365 input=5505cff90ca48b96]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000448{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000449 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000450 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000451
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000452 if (size < 0) {
453 PyErr_Format(PyExc_ValueError,
454 "Negative size value %zd", size);
455 return NULL;
456 }
457
458 if (size < self->string_size) {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100459 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000460 if (resize_buffer(self, size) < 0)
461 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462 self->string_size = size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000463 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000464
465 return PyLong_FromSsize_t(size);
466}
467
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300468/*[clinic input]
469_io.StringIO.seek
470 pos: Py_ssize_t
471 whence: int = 0
472 /
473
474Change stream position.
475
476Seek to character offset pos relative to position indicated by whence:
477 0 Start of stream (the default). pos should be >= 0;
478 1 Current position - pos must be 0;
479 2 End of stream - pos must be 0.
480Returns the new absolute position.
481[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000483static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300484_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence)
485/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000486{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000488 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000489
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300490 if (whence != 0 && whence != 1 && whence != 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000491 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300492 "Invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000493 return NULL;
494 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300495 else if (pos < 0 && whence == 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000496 PyErr_Format(PyExc_ValueError,
497 "Negative seek position %zd", pos);
498 return NULL;
499 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300500 else if (whence != 0 && pos != 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300501 PyErr_SetString(PyExc_OSError,
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000502 "Can't do nonzero cur-relative seeks");
503 return NULL;
504 }
505
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300506 /* whence = 0: offset relative to beginning of the string.
507 whence = 1: no change to current position.
508 whence = 2: change position to end of file. */
509 if (whence == 1) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000510 pos = self->pos;
511 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300512 else if (whence == 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000513 pos = self->string_size;
514 }
515
516 self->pos = pos;
517
518 return PyLong_FromSsize_t(self->pos);
519}
520
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300521/*[clinic input]
522_io.StringIO.write
523 s as obj: object
524 /
525
526Write string to file.
527
528Returns the number of characters written, which is always equal to
529the length of the string.
530[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000531
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000532static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300533_io_StringIO_write(stringio *self, PyObject *obj)
534/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000535{
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000536 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000537
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000538 CHECK_INITIALIZED(self);
539 if (!PyUnicode_Check(obj)) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000540 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
541 Py_TYPE(obj)->tp_name);
542 return NULL;
543 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200544 if (PyUnicode_READY(obj))
545 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000546 CHECK_CLOSED(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200547 size = PyUnicode_GET_LENGTH(obj);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000548
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000549 if (size > 0 && write_str(self, obj) < 0)
550 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000551
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000552 return PyLong_FromSsize_t(size);
553}
554
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300555/*[clinic input]
556_io.StringIO.close
557
558Close the IO object.
559
560Attempting any further operation after the object is closed
561will raise a ValueError.
562
563This method has no effect if the file is already closed.
564[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565
566static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300567_io_StringIO_close_impl(stringio *self)
568/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 self->closed = 1;
571 /* Free up some memory */
572 if (resize_buffer(self, 0) < 0)
573 return NULL;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100574 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575 Py_CLEAR(self->readnl);
576 Py_CLEAR(self->writenl);
577 Py_CLEAR(self->decoder);
578 Py_RETURN_NONE;
579}
580
581static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000582stringio_traverse(stringio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000583{
584 Py_VISIT(self->dict);
585 return 0;
586}
587
588static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000589stringio_clear(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000590{
591 Py_CLEAR(self->dict);
592 return 0;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000593}
594
595static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000596stringio_dealloc(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000597{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000598 _PyObject_GC_UNTRACK(self);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000599 self->ok = 0;
600 if (self->buf) {
601 PyMem_Free(self->buf);
602 self->buf = NULL;
603 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100604 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000605 Py_CLEAR(self->readnl);
606 Py_CLEAR(self->writenl);
607 Py_CLEAR(self->decoder);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000608 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609 if (self->weakreflist != NULL)
610 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000611 Py_TYPE(self)->tp_free(self);
612}
613
614static PyObject *
615stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
616{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000617 stringio *self;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000618
619 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620 self = (stringio *)type->tp_alloc(type, 0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000621 if (self == NULL)
622 return NULL;
623
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000624 /* tp_alloc initializes all the fields to zero. So we don't have to
625 initialize them here. */
626
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200627 self->buf = (Py_UCS4 *)PyMem_Malloc(0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000628 if (self->buf == NULL) {
629 Py_DECREF(self);
630 return PyErr_NoMemory();
631 }
632
633 return (PyObject *)self;
634}
635
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300636/*[clinic input]
637_io.StringIO.__init__
638 initial_value as value: object(c_default="NULL") = ''
639 newline as newline_obj: object(c_default="NULL") = '\n'
640
641Text I/O implementation using an in-memory buffer.
642
643The initial_value argument sets the value of object. The newline
644argument is like the one of TextIOWrapper's constructor.
645[clinic start generated code]*/
646
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300648_io_StringIO___init___impl(stringio *self, PyObject *value,
649 PyObject *newline_obj)
650/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000651{
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200652 const char *newline = "\n";
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100653 Py_ssize_t value_len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654
Martin Panterf2644162015-10-10 10:17:57 +0000655 /* Parse the newline argument. We only want to allow unicode objects or
656 None. */
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000657 if (newline_obj == Py_None) {
658 newline = NULL;
659 }
660 else if (newline_obj) {
661 if (!PyUnicode_Check(newline_obj)) {
662 PyErr_Format(PyExc_TypeError,
663 "newline must be str or None, not %.200s",
664 Py_TYPE(newline_obj)->tp_name);
665 return -1;
666 }
Serhiy Storchaka06515832016-11-20 09:13:07 +0200667 newline = PyUnicode_AsUTF8(newline_obj);
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000668 if (newline == NULL)
669 return -1;
670 }
671
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000672 if (newline && newline[0] != '\0'
673 && !(newline[0] == '\n' && newline[1] == '\0')
674 && !(newline[0] == '\r' && newline[1] == '\0')
675 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
676 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000677 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678 return -1;
679 }
680 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000681 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682 "initial_value must be str or None, not %.200s",
683 Py_TYPE(value)->tp_name);
684 return -1;
685 }
686
687 self->ok = 0;
688
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100689 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000690 Py_CLEAR(self->readnl);
691 Py_CLEAR(self->writenl);
692 Py_CLEAR(self->decoder);
693
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000694 assert((newline != NULL && newline_obj != Py_None) ||
695 (newline == NULL && newline_obj == Py_None));
696
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000697 if (newline) {
698 self->readnl = PyUnicode_FromString(newline);
699 if (self->readnl == NULL)
700 return -1;
701 }
702 self->readuniversal = (newline == NULL || newline[0] == '\0');
703 self->readtranslate = (newline == NULL);
704 /* If newline == "", we don't translate anything.
705 If newline == "\n" or newline == None, we translate to "\n", which is
706 a no-op.
Martin Panter9955a372015-10-07 10:26:23 +0000707 (for newline == None, TextIOWrapper translates to os.linesep, but it
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708 is pointless for StringIO)
709 */
710 if (newline != NULL && newline[0] == '\r') {
711 self->writenl = self->readnl;
712 Py_INCREF(self->writenl);
713 }
714
715 if (self->readuniversal) {
716 self->decoder = PyObject_CallFunction(
717 (PyObject *)&PyIncrementalNewlineDecoder_Type,
718 "Oi", Py_None, (int) self->readtranslate);
719 if (self->decoder == NULL)
720 return -1;
721 }
722
723 /* Now everything is set up, resize buffer to size of initial value,
724 and copy it */
725 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100726 if (value && value != Py_None)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100727 value_len = PyUnicode_GetLength(value);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100728 else
729 value_len = 0;
730 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731 /* This is a heuristic, for newline translation might change
732 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100733 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000734 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100735 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000736 self->pos = 0;
737 if (write_str(self, value) < 0)
738 return -1;
739 }
740 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100741 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000742 if (resize_buffer(self, 0) < 0)
743 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100744 if (_PyAccu_Init(&self->accu))
745 return -1;
746 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000747 }
748 self->pos = 0;
749
750 self->closed = 0;
751 self->ok = 1;
752 return 0;
753}
754
755/* Properties and pseudo-properties */
Antoine Pitrou1d857452012-09-05 20:11:49 +0200756
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300757/*[clinic input]
758_io.StringIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200759
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300760Returns True if the IO object can be read.
761[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200762
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000763static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300764_io_StringIO_readable_impl(stringio *self)
765/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766{
767 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200768 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000769 Py_RETURN_TRUE;
770}
771
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300772/*[clinic input]
773_io.StringIO.writable
774
775Returns True if the IO object can be written.
776[clinic start generated code]*/
777
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300779_io_StringIO_writable_impl(stringio *self)
780/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000781{
782 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200783 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000784 Py_RETURN_TRUE;
785}
786
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300787/*[clinic input]
788_io.StringIO.seekable
789
790Returns True if the IO object can be seeked.
791[clinic start generated code]*/
792
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000793static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300794_io_StringIO_seekable_impl(stringio *self)
795/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000796{
797 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200798 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000799 Py_RETURN_TRUE;
800}
801
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000802/* Pickling support.
803
804 The implementation of __getstate__ is similar to the one for BytesIO,
805 except that we also save the newline parameter. For __setstate__ and unlike
806 BytesIO, we call __init__ to restore the object's state. Doing so allows us
807 to avoid decoding the complex newline state while keeping the object
808 representation compact.
809
810 See comment in bytesio.c regarding why only pickle protocols and onward are
811 supported.
812*/
813
814static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530815stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored))
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000816{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300817 PyObject *initvalue = _io_StringIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000818 PyObject *dict;
819 PyObject *state;
820
821 if (initvalue == NULL)
822 return NULL;
823 if (self->dict == NULL) {
824 Py_INCREF(Py_None);
825 dict = Py_None;
826 }
827 else {
828 dict = PyDict_Copy(self->dict);
Serhiy Storchakafdb5a502018-06-30 20:57:50 +0300829 if (dict == NULL) {
830 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000831 return NULL;
Serhiy Storchakafdb5a502018-06-30 20:57:50 +0300832 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000833 }
834
835 state = Py_BuildValue("(OOnN)", initvalue,
836 self->readnl ? self->readnl : Py_None,
837 self->pos, dict);
838 Py_DECREF(initvalue);
839 return state;
840}
841
842static PyObject *
843stringio_setstate(stringio *self, PyObject *state)
844{
845 PyObject *initarg;
846 PyObject *position_obj;
847 PyObject *dict;
848 Py_ssize_t pos;
849
850 assert(state != NULL);
851 CHECK_CLOSED(self);
852
853 /* We allow the state tuple to be longer than 4, because we may need
854 someday to extend the object's state without breaking
855 backward-compatibility. */
Serhiy Storchakafff9a312017-03-21 08:53:25 +0200856 if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 4) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000857 PyErr_Format(PyExc_TypeError,
858 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
859 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
860 return NULL;
861 }
862
863 /* Initialize the object's state. */
864 initarg = PyTuple_GetSlice(state, 0, 2);
865 if (initarg == NULL)
866 return NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300867 if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000868 Py_DECREF(initarg);
869 return NULL;
870 }
871 Py_DECREF(initarg);
872
873 /* Restore the buffer state. Even if __init__ did initialize the buffer,
Martin Panter8f265652016-04-19 04:03:41 +0000874 we have to initialize it again since __init__ may translate the
875 newlines in the initial_value string. We clearly do not want that
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000876 because the string value in the state tuple has already been translated
877 once by __init__. So we do not take any chance and replace object's
878 buffer completely. */
879 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200880 PyObject *item;
881 Py_UCS4 *buf;
882 Py_ssize_t bufsize;
883
884 item = PyTuple_GET_ITEM(state, 0);
885 buf = PyUnicode_AsUCS4Copy(item);
886 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000887 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200888 bufsize = PyUnicode_GET_LENGTH(item);
889
890 if (resize_buffer(self, bufsize) < 0) {
891 PyMem_Free(buf);
892 return NULL;
893 }
894 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
895 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000896 self->string_size = bufsize;
897 }
898
899 /* Set carefully the position value. Alternatively, we could use the seek
900 method instead of modifying self->pos directly to better protect the
901 object internal state against errneous (or malicious) inputs. */
902 position_obj = PyTuple_GET_ITEM(state, 2);
903 if (!PyLong_Check(position_obj)) {
904 PyErr_Format(PyExc_TypeError,
905 "third item of state must be an integer, got %.200s",
906 Py_TYPE(position_obj)->tp_name);
907 return NULL;
908 }
909 pos = PyLong_AsSsize_t(position_obj);
910 if (pos == -1 && PyErr_Occurred())
911 return NULL;
912 if (pos < 0) {
913 PyErr_SetString(PyExc_ValueError,
914 "position value cannot be negative");
915 return NULL;
916 }
917 self->pos = pos;
918
919 /* Set the dictionary of the instance variables. */
920 dict = PyTuple_GET_ITEM(state, 3);
921 if (dict != Py_None) {
922 if (!PyDict_Check(dict)) {
923 PyErr_Format(PyExc_TypeError,
924 "fourth item of state should be a dict, got a %.200s",
925 Py_TYPE(dict)->tp_name);
926 return NULL;
927 }
928 if (self->dict) {
929 /* Alternatively, we could replace the internal dictionary
930 completely. However, it seems more practical to just update it. */
931 if (PyDict_Update(self->dict, dict) < 0)
932 return NULL;
933 }
934 else {
935 Py_INCREF(dict);
936 self->dict = dict;
937 }
938 }
939
940 Py_RETURN_NONE;
941}
942
943
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000944static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000945stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000946{
947 CHECK_INITIALIZED(self);
948 return PyBool_FromLong(self->closed);
949}
950
951static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000952stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000953{
954 CHECK_INITIALIZED(self);
955 CHECK_CLOSED(self);
956 Py_RETURN_FALSE;
957}
958
959static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000960stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000961{
962 CHECK_INITIALIZED(self);
963 CHECK_CLOSED(self);
964 if (self->decoder == NULL)
965 Py_RETURN_NONE;
966 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
967}
968
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300969#include "clinic/stringio.c.h"
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000970
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300971static struct PyMethodDef stringio_methods[] = {
972 _IO_STRINGIO_CLOSE_METHODDEF
973 _IO_STRINGIO_GETVALUE_METHODDEF
974 _IO_STRINGIO_READ_METHODDEF
975 _IO_STRINGIO_READLINE_METHODDEF
976 _IO_STRINGIO_TELL_METHODDEF
977 _IO_STRINGIO_TRUNCATE_METHODDEF
978 _IO_STRINGIO_SEEK_METHODDEF
979 _IO_STRINGIO_WRITE_METHODDEF
980
981 _IO_STRINGIO_SEEKABLE_METHODDEF
982 _IO_STRINGIO_READABLE_METHODDEF
983 _IO_STRINGIO_WRITABLE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000984
985 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
986 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000987 {NULL, NULL} /* sentinel */
988};
989
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990static PyGetSetDef stringio_getset[] = {
991 {"closed", (getter)stringio_closed, NULL, NULL},
992 {"newlines", (getter)stringio_newlines, NULL, NULL},
993 /* (following comments straight off of the original Python wrapper:)
994 XXX Cruft to support the TextIOWrapper API. This would only
995 be meaningful if StringIO supported the buffer attribute.
996 Hopefully, a better solution, than adding these pseudo-attributes,
997 will be found.
998 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000999 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001000 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001001};
1002
1003PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001004 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001005 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001006 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001007 0, /*tp_itemsize*/
1008 (destructor)stringio_dealloc, /*tp_dealloc*/
1009 0, /*tp_print*/
1010 0, /*tp_getattr*/
1011 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001012 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001013 0, /*tp_repr*/
1014 0, /*tp_as_number*/
1015 0, /*tp_as_sequence*/
1016 0, /*tp_as_mapping*/
1017 0, /*tp_hash*/
1018 0, /*tp_call*/
1019 0, /*tp_str*/
1020 0, /*tp_getattro*/
1021 0, /*tp_setattro*/
1022 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001023 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1024 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001025 _io_StringIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001026 (traverseproc)stringio_traverse, /*tp_traverse*/
1027 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001028 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001029 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001030 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001031 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001032 stringio_methods, /*tp_methods*/
1033 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001034 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001035 0, /*tp_base*/
1036 0, /*tp_dict*/
1037 0, /*tp_descr_get*/
1038 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001039 offsetof(stringio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001040 _io_StringIO___init__, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001041 0, /*tp_alloc*/
1042 stringio_new, /*tp_new*/
1043};