blob: 788dcb198458963bac6cf84826a66b9e00a864b1 [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
orenmn74002542017-03-11 00:52:01 +020020/*[python input]
21class io_ssize_t_converter(CConverter):
22 type = 'Py_ssize_t'
23 converter = '_PyIO_ConvertSsize_t'
24[python start generated code]*/
25/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
26
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000027typedef struct {
28 PyObject_HEAD
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020029 Py_UCS4 *buf;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000030 Py_ssize_t pos;
31 Py_ssize_t string_size;
32 size_t buf_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000033
Antoine Pitroude20b0b2011-11-10 21:47:38 +010034 /* The stringio object can be in two states: accumulating or realized.
35 In accumulating state, the internal buffer contains nothing and
36 the contents are given by the embedded _PyAccu structure.
37 In realized state, the internal buffer is meaningful and the
38 _PyAccu is destroyed.
39 */
40 int state;
41 _PyAccu accu;
42
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000043 char ok; /* initialized? */
44 char closed;
45 char readuniversal;
46 char readtranslate;
47 PyObject *decoder;
48 PyObject *readnl;
49 PyObject *writenl;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020050
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000051 PyObject *dict;
52 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000053} stringio;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000054
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030055static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs);
56
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000057#define CHECK_INITIALIZED(self) \
58 if (self->ok <= 0) { \
59 PyErr_SetString(PyExc_ValueError, \
60 "I/O operation on uninitialized object"); \
61 return NULL; \
62 }
63
64#define CHECK_CLOSED(self) \
65 if (self->closed) { \
66 PyErr_SetString(PyExc_ValueError, \
67 "I/O operation on closed file"); \
68 return NULL; \
69 }
70
Antoine Pitroude20b0b2011-11-10 21:47:38 +010071#define ENSURE_REALIZED(self) \
72 if (realize(self) < 0) { \
73 return NULL; \
74 }
75
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000076
77/* Internal routine for changing the size, in terms of characters, of the
78 buffer of StringIO objects. The caller should ensure that the 'size'
79 argument is non-negative. Returns 0 on success, -1 otherwise. */
80static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000081resize_buffer(stringio *self, size_t size)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000082{
83 /* Here, unsigned types are used to avoid dealing with signed integer
84 overflow, which is undefined in C. */
85 size_t alloc = self->buf_size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020086 Py_UCS4 *new_buf = NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000087
88 assert(self->buf != NULL);
89
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000090 /* Reserve one more char for line ending detection. */
91 size = size + 1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000092 /* For simplicity, stay in the range of the signed type. Anyway, Python
93 doesn't allow strings to be longer than this. */
94 if (size > PY_SSIZE_T_MAX)
95 goto overflow;
96
97 if (size < alloc / 2) {
98 /* Major downsize; resize down to exact size. */
99 alloc = size + 1;
100 }
101 else if (size < alloc) {
102 /* Within allocated size; quick exit */
103 return 0;
104 }
105 else if (size <= alloc * 1.125) {
106 /* Moderate upsize; overallocate similar to list_resize() */
107 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
108 }
109 else {
110 /* Major upsize; resize up to exact size */
111 alloc = size + 1;
112 }
113
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200114 if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4))
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000115 goto overflow;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200116 new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000117 if (new_buf == NULL) {
118 PyErr_NoMemory();
119 return -1;
120 }
121 self->buf_size = alloc;
122 self->buf = new_buf;
123
124 return 0;
125
126 overflow:
127 PyErr_SetString(PyExc_OverflowError,
128 "new buffer size too large");
129 return -1;
130}
131
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100132static PyObject *
133make_intermediate(stringio *self)
134{
135 PyObject *intermediate = _PyAccu_Finish(&self->accu);
136 self->state = STATE_REALIZED;
137 if (intermediate == NULL)
138 return NULL;
139 if (_PyAccu_Init(&self->accu) ||
140 _PyAccu_Accumulate(&self->accu, intermediate)) {
141 Py_DECREF(intermediate);
142 return NULL;
143 }
144 self->state = STATE_ACCUMULATING;
145 return intermediate;
146}
147
148static int
149realize(stringio *self)
150{
151 Py_ssize_t len;
152 PyObject *intermediate;
153
154 if (self->state == STATE_REALIZED)
155 return 0;
156 assert(self->state == STATE_ACCUMULATING);
157 self->state = STATE_REALIZED;
158
159 intermediate = _PyAccu_Finish(&self->accu);
160 if (intermediate == NULL)
161 return -1;
162
163 /* Append the intermediate string to the internal buffer.
164 The length should be equal to the current cursor position.
165 */
166 len = PyUnicode_GET_LENGTH(intermediate);
167 if (resize_buffer(self, len) < 0) {
168 Py_DECREF(intermediate);
169 return -1;
170 }
171 if (!PyUnicode_AsUCS4(intermediate, self->buf, len, 0)) {
172 Py_DECREF(intermediate);
173 return -1;
174 }
175
176 Py_DECREF(intermediate);
177 return 0;
178}
179
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180/* Internal routine for writing a whole PyUnicode object to the buffer of a
181 StringIO object. Returns 0 on success, or -1 on error. */
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000182static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000183write_str(stringio *self, PyObject *obj)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000184{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000185 Py_ssize_t len;
186 PyObject *decoded = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200187
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000188 assert(self->buf != NULL);
189 assert(self->pos >= 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000190
191 if (self->decoder != NULL) {
192 decoded = _PyIncrementalNewlineDecoder_decode(
193 self->decoder, obj, 1 /* always final */);
194 }
195 else {
196 decoded = obj;
197 Py_INCREF(decoded);
198 }
199 if (self->writenl) {
200 PyObject *translated = PyUnicode_Replace(
201 decoded, _PyIO_str_nl, self->writenl, -1);
202 Py_DECREF(decoded);
203 decoded = translated;
204 }
205 if (decoded == NULL)
206 return -1;
207
208 assert(PyUnicode_Check(decoded));
Victor Stinnere1335c72011-10-04 20:53:03 +0200209 if (PyUnicode_READY(decoded)) {
210 Py_DECREF(decoded);
211 return -1;
212 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200213 len = PyUnicode_GET_LENGTH(decoded);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000214 assert(len >= 0);
215
216 /* This overflow check is not strictly necessary. However, it avoids us to
217 deal with funky things like comparing an unsigned and a signed
218 integer. */
219 if (self->pos > PY_SSIZE_T_MAX - len) {
220 PyErr_SetString(PyExc_OverflowError,
221 "new position too large");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000222 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000223 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100224
225 if (self->state == STATE_ACCUMULATING) {
226 if (self->string_size == self->pos) {
227 if (_PyAccu_Accumulate(&self->accu, decoded))
228 goto fail;
229 goto success;
230 }
231 if (realize(self))
232 goto fail;
233 }
234
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000235 if (self->pos + len > self->string_size) {
236 if (resize_buffer(self, self->pos + len) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000237 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000238 }
239
240 if (self->pos > self->string_size) {
241 /* In case of overseek, pad with null bytes the buffer region between
242 the end of stream and the current position.
243
244 0 lo string_size hi
245 | |<---used--->|<----------available----------->|
246 | | <--to pad-->|<---to write---> |
Ezio Melotti13925002011-03-16 11:05:33 +0200247 0 buf position
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000248
249 */
250 memset(self->buf + self->string_size, '\0',
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200251 (self->pos - self->string_size) * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000252 }
253
254 /* Copy the data to the internal buffer, overwriting some of the
255 existing data if self->pos < self->string_size. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200256 if (!PyUnicode_AsUCS4(decoded,
257 self->buf + self->pos,
258 self->buf_size - self->pos,
259 0))
260 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000261
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100262success:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000263 /* Set the new length of the internal string if it has changed. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200264 self->pos += len;
265 if (self->string_size < self->pos)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000266 self->string_size = self->pos;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000267
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000268 Py_DECREF(decoded);
269 return 0;
270
271fail:
272 Py_XDECREF(decoded);
273 return -1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000274}
275
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300276/*[clinic input]
277_io.StringIO.getvalue
278
279Retrieve the entire contents of the object.
280[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000281
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000282static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300283_io_StringIO_getvalue_impl(stringio *self)
284/*[clinic end generated code: output=27b6a7bfeaebce01 input=d23cb81d6791cf88]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000285{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000286 CHECK_INITIALIZED(self);
287 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100288 if (self->state == STATE_ACCUMULATING)
289 return make_intermediate(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200290 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, self->buf,
291 self->string_size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000292}
293
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300294/*[clinic input]
295_io.StringIO.tell
296
297Tell the current file position.
298[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000299
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000300static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300301_io_StringIO_tell_impl(stringio *self)
302/*[clinic end generated code: output=2e87ac67b116c77b input=ec866ebaff02f405]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000303{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000304 CHECK_INITIALIZED(self);
305 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000306 return PyLong_FromSsize_t(self->pos);
307}
308
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300309/*[clinic input]
310_io.StringIO.read
orenmn74002542017-03-11 00:52:01 +0200311 size: io_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300312 /
313
314Read at most size characters, returned as a string.
315
316If the argument is negative or omitted, read until EOF
317is reached. Return an empty string at EOF.
318[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000319
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000320static PyObject *
orenmn74002542017-03-11 00:52:01 +0200321_io_StringIO_read_impl(stringio *self, Py_ssize_t size)
322/*[clinic end generated code: output=ae8cf6002f71626c input=bbd84248eb4ab957]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000323{
orenmn74002542017-03-11 00:52:01 +0200324 Py_ssize_t n;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200325 Py_UCS4 *output;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000326
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000327 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000328 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000329
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000330 /* adjust invalid sizes */
331 n = self->string_size - self->pos;
332 if (size < 0 || size > n) {
333 size = n;
334 if (size < 0)
335 size = 0;
336 }
337
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100338 /* Optimization for seek(0); read() */
339 if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) {
340 PyObject *result = make_intermediate(self);
341 self->pos = self->string_size;
342 return result;
343 }
344
345 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000346 output = self->buf + self->pos;
347 self->pos += size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200348 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000349}
350
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000351/* Internal helper, used by stringio_readline and stringio_iternext */
352static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000353_stringio_readline(stringio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000354{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200355 Py_UCS4 *start, *end, old_char;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000356 Py_ssize_t len, consumed;
357
358 /* In case of overseek, return the empty string */
359 if (self->pos >= self->string_size)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200360 return PyUnicode_New(0, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000361
362 start = self->buf + self->pos;
363 if (limit < 0 || limit > self->string_size - self->pos)
364 limit = self->string_size - self->pos;
365
366 end = start + limit;
367 old_char = *end;
368 *end = '\0';
369 len = _PyIO_find_line_ending(
370 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200371 PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000372 *end = old_char;
373 /* If we haven't found any line ending, we just return everything
374 (`consumed` is ignored). */
375 if (len < 0)
376 len = limit;
377 self->pos += len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200378 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000379}
380
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300381/*[clinic input]
382_io.StringIO.readline
orenmn74002542017-03-11 00:52:01 +0200383 size: io_ssize_t = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300384 /
385
386Read until newline or EOF.
387
388Returns an empty string if EOF is hit immediately.
389[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000390
391static PyObject *
orenmn74002542017-03-11 00:52:01 +0200392_io_StringIO_readline_impl(stringio *self, Py_ssize_t size)
393/*[clinic end generated code: output=cabd6452f1b7e85d input=04de7535f732cb3d]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000394{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000395 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000396 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100397 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000398
orenmn74002542017-03-11 00:52:01 +0200399 return _stringio_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000400}
401
402static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000403stringio_iternext(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000404{
405 PyObject *line;
406
407 CHECK_INITIALIZED(self);
408 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100409 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000410
411 if (Py_TYPE(self) == &PyStringIO_Type) {
412 /* Skip method call overhead for speed */
413 line = _stringio_readline(self, -1);
414 }
415 else {
416 /* XXX is subclassing StringIO really supported? */
417 line = PyObject_CallMethodObjArgs((PyObject *)self,
418 _PyIO_str_readline, NULL);
419 if (line && !PyUnicode_Check(line)) {
420 PyErr_Format(PyExc_IOError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +0300421 "readline() should have returned a str object, "
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000422 "not '%.200s'", Py_TYPE(line)->tp_name);
423 Py_DECREF(line);
424 return NULL;
425 }
426 }
427
428 if (line == NULL)
429 return NULL;
430
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200431 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000432 /* Reached EOF */
433 Py_DECREF(line);
434 return NULL;
435 }
436
437 return line;
438}
439
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300440/*[clinic input]
441_io.StringIO.truncate
442 pos as arg: object = None
443 /
444
445Truncate size to pos.
446
447The pos argument defaults to the current file position, as
448returned by tell(). The current file position is unchanged.
449Returns the new absolute position.
450[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000451
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000452static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300453_io_StringIO_truncate_impl(stringio *self, PyObject *arg)
454/*[clinic end generated code: output=6072439c2b01d306 input=748619a494ba53ad]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000455{
456 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000457
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000458 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000459 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000460
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461 if (PyNumber_Check(arg)) {
462 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Benjamin Petersonc9e435e2008-09-30 02:22:04 +0000463 if (size == -1 && PyErr_Occurred())
464 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000465 }
466 else if (arg == Py_None) {
467 /* Truncate to current position if no argument is passed. */
468 size = self->pos;
469 }
470 else {
471 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
472 Py_TYPE(arg)->tp_name);
473 return NULL;
474 }
475
476 if (size < 0) {
477 PyErr_Format(PyExc_ValueError,
478 "Negative size value %zd", size);
479 return NULL;
480 }
481
482 if (size < self->string_size) {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100483 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000484 if (resize_buffer(self, size) < 0)
485 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000486 self->string_size = size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000487 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000488
489 return PyLong_FromSsize_t(size);
490}
491
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300492/*[clinic input]
493_io.StringIO.seek
494 pos: Py_ssize_t
495 whence: int = 0
496 /
497
498Change stream position.
499
500Seek to character offset pos relative to position indicated by whence:
501 0 Start of stream (the default). pos should be >= 0;
502 1 Current position - pos must be 0;
503 2 End of stream - pos must be 0.
504Returns the new absolute position.
505[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000507static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300508_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence)
509/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000510{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000512 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000513
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300514 if (whence != 0 && whence != 1 && whence != 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000515 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300516 "Invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000517 return NULL;
518 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300519 else if (pos < 0 && whence == 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000520 PyErr_Format(PyExc_ValueError,
521 "Negative seek position %zd", pos);
522 return NULL;
523 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300524 else if (whence != 0 && pos != 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000525 PyErr_SetString(PyExc_IOError,
526 "Can't do nonzero cur-relative seeks");
527 return NULL;
528 }
529
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300530 /* whence = 0: offset relative to beginning of the string.
531 whence = 1: no change to current position.
532 whence = 2: change position to end of file. */
533 if (whence == 1) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000534 pos = self->pos;
535 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300536 else if (whence == 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000537 pos = self->string_size;
538 }
539
540 self->pos = pos;
541
542 return PyLong_FromSsize_t(self->pos);
543}
544
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300545/*[clinic input]
546_io.StringIO.write
547 s as obj: object
548 /
549
550Write string to file.
551
552Returns the number of characters written, which is always equal to
553the length of the string.
554[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000555
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000556static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300557_io_StringIO_write(stringio *self, PyObject *obj)
558/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000559{
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000560 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000561
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562 CHECK_INITIALIZED(self);
563 if (!PyUnicode_Check(obj)) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000564 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
565 Py_TYPE(obj)->tp_name);
566 return NULL;
567 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200568 if (PyUnicode_READY(obj))
569 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570 CHECK_CLOSED(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200571 size = PyUnicode_GET_LENGTH(obj);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000572
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000573 if (size > 0 && write_str(self, obj) < 0)
574 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000575
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576 return PyLong_FromSsize_t(size);
577}
578
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300579/*[clinic input]
580_io.StringIO.close
581
582Close the IO object.
583
584Attempting any further operation after the object is closed
585will raise a ValueError.
586
587This method has no effect if the file is already closed.
588[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589
590static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300591_io_StringIO_close_impl(stringio *self)
592/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593{
594 self->closed = 1;
595 /* Free up some memory */
596 if (resize_buffer(self, 0) < 0)
597 return NULL;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100598 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000599 Py_CLEAR(self->readnl);
600 Py_CLEAR(self->writenl);
601 Py_CLEAR(self->decoder);
602 Py_RETURN_NONE;
603}
604
605static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000606stringio_traverse(stringio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000607{
608 Py_VISIT(self->dict);
609 return 0;
610}
611
612static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000613stringio_clear(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000614{
615 Py_CLEAR(self->dict);
616 return 0;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000617}
618
619static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000620stringio_dealloc(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000621{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000622 _PyObject_GC_UNTRACK(self);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000623 self->ok = 0;
624 if (self->buf) {
625 PyMem_Free(self->buf);
626 self->buf = NULL;
627 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100628 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000629 Py_CLEAR(self->readnl);
630 Py_CLEAR(self->writenl);
631 Py_CLEAR(self->decoder);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000632 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633 if (self->weakreflist != NULL)
634 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000635 Py_TYPE(self)->tp_free(self);
636}
637
638static PyObject *
639stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
640{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000641 stringio *self;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000642
643 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000644 self = (stringio *)type->tp_alloc(type, 0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000645 if (self == NULL)
646 return NULL;
647
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000648 /* tp_alloc initializes all the fields to zero. So we don't have to
649 initialize them here. */
650
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200651 self->buf = (Py_UCS4 *)PyMem_Malloc(0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000652 if (self->buf == NULL) {
653 Py_DECREF(self);
654 return PyErr_NoMemory();
655 }
656
657 return (PyObject *)self;
658}
659
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300660/*[clinic input]
661_io.StringIO.__init__
662 initial_value as value: object(c_default="NULL") = ''
663 newline as newline_obj: object(c_default="NULL") = '\n'
664
665Text I/O implementation using an in-memory buffer.
666
667The initial_value argument sets the value of object. The newline
668argument is like the one of TextIOWrapper's constructor.
669[clinic start generated code]*/
670
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300672_io_StringIO___init___impl(stringio *self, PyObject *value,
673 PyObject *newline_obj)
674/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675{
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200676 const char *newline = "\n";
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100677 Py_ssize_t value_len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678
Martin Panterf2644162015-10-10 10:17:57 +0000679 /* Parse the newline argument. We only want to allow unicode objects or
680 None. */
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000681 if (newline_obj == Py_None) {
682 newline = NULL;
683 }
684 else if (newline_obj) {
685 if (!PyUnicode_Check(newline_obj)) {
686 PyErr_Format(PyExc_TypeError,
687 "newline must be str or None, not %.200s",
688 Py_TYPE(newline_obj)->tp_name);
689 return -1;
690 }
Serhiy Storchaka06515832016-11-20 09:13:07 +0200691 newline = PyUnicode_AsUTF8(newline_obj);
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000692 if (newline == NULL)
693 return -1;
694 }
695
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696 if (newline && newline[0] != '\0'
697 && !(newline[0] == '\n' && newline[1] == '\0')
698 && !(newline[0] == '\r' && newline[1] == '\0')
699 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
700 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000701 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702 return -1;
703 }
704 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000705 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000706 "initial_value must be str or None, not %.200s",
707 Py_TYPE(value)->tp_name);
708 return -1;
709 }
710
711 self->ok = 0;
712
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100713 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000714 Py_CLEAR(self->readnl);
715 Py_CLEAR(self->writenl);
716 Py_CLEAR(self->decoder);
717
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000718 assert((newline != NULL && newline_obj != Py_None) ||
719 (newline == NULL && newline_obj == Py_None));
720
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000721 if (newline) {
722 self->readnl = PyUnicode_FromString(newline);
723 if (self->readnl == NULL)
724 return -1;
725 }
726 self->readuniversal = (newline == NULL || newline[0] == '\0');
727 self->readtranslate = (newline == NULL);
728 /* If newline == "", we don't translate anything.
729 If newline == "\n" or newline == None, we translate to "\n", which is
730 a no-op.
Martin Panter9955a372015-10-07 10:26:23 +0000731 (for newline == None, TextIOWrapper translates to os.linesep, but it
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000732 is pointless for StringIO)
733 */
734 if (newline != NULL && newline[0] == '\r') {
735 self->writenl = self->readnl;
736 Py_INCREF(self->writenl);
737 }
738
739 if (self->readuniversal) {
740 self->decoder = PyObject_CallFunction(
741 (PyObject *)&PyIncrementalNewlineDecoder_Type,
742 "Oi", Py_None, (int) self->readtranslate);
743 if (self->decoder == NULL)
744 return -1;
745 }
746
747 /* Now everything is set up, resize buffer to size of initial value,
748 and copy it */
749 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100750 if (value && value != Py_None)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100751 value_len = PyUnicode_GetLength(value);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100752 else
753 value_len = 0;
754 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000755 /* This is a heuristic, for newline translation might change
756 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100757 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000758 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100759 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000760 self->pos = 0;
761 if (write_str(self, value) < 0)
762 return -1;
763 }
764 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100765 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766 if (resize_buffer(self, 0) < 0)
767 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100768 if (_PyAccu_Init(&self->accu))
769 return -1;
770 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000771 }
772 self->pos = 0;
773
774 self->closed = 0;
775 self->ok = 1;
776 return 0;
777}
778
779/* Properties and pseudo-properties */
Antoine Pitrou1d857452012-09-05 20:11:49 +0200780
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300781/*[clinic input]
782_io.StringIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200783
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300784Returns True if the IO object can be read.
785[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200786
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000787static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300788_io_StringIO_readable_impl(stringio *self)
789/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000790{
791 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200792 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000793 Py_RETURN_TRUE;
794}
795
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300796/*[clinic input]
797_io.StringIO.writable
798
799Returns True if the IO object can be written.
800[clinic start generated code]*/
801
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000802static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300803_io_StringIO_writable_impl(stringio *self)
804/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000805{
806 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200807 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000808 Py_RETURN_TRUE;
809}
810
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300811/*[clinic input]
812_io.StringIO.seekable
813
814Returns True if the IO object can be seeked.
815[clinic start generated code]*/
816
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000817static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300818_io_StringIO_seekable_impl(stringio *self)
819/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000820{
821 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200822 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000823 Py_RETURN_TRUE;
824}
825
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000826/* Pickling support.
827
828 The implementation of __getstate__ is similar to the one for BytesIO,
829 except that we also save the newline parameter. For __setstate__ and unlike
830 BytesIO, we call __init__ to restore the object's state. Doing so allows us
831 to avoid decoding the complex newline state while keeping the object
832 representation compact.
833
834 See comment in bytesio.c regarding why only pickle protocols and onward are
835 supported.
836*/
837
838static PyObject *
839stringio_getstate(stringio *self)
840{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300841 PyObject *initvalue = _io_StringIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000842 PyObject *dict;
843 PyObject *state;
844
845 if (initvalue == NULL)
846 return NULL;
847 if (self->dict == NULL) {
848 Py_INCREF(Py_None);
849 dict = Py_None;
850 }
851 else {
852 dict = PyDict_Copy(self->dict);
853 if (dict == NULL)
854 return NULL;
855 }
856
857 state = Py_BuildValue("(OOnN)", initvalue,
858 self->readnl ? self->readnl : Py_None,
859 self->pos, dict);
860 Py_DECREF(initvalue);
861 return state;
862}
863
864static PyObject *
865stringio_setstate(stringio *self, PyObject *state)
866{
867 PyObject *initarg;
868 PyObject *position_obj;
869 PyObject *dict;
870 Py_ssize_t pos;
871
872 assert(state != NULL);
873 CHECK_CLOSED(self);
874
875 /* We allow the state tuple to be longer than 4, because we may need
876 someday to extend the object's state without breaking
877 backward-compatibility. */
878 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
879 PyErr_Format(PyExc_TypeError,
880 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
881 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
882 return NULL;
883 }
884
885 /* Initialize the object's state. */
886 initarg = PyTuple_GetSlice(state, 0, 2);
887 if (initarg == NULL)
888 return NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300889 if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000890 Py_DECREF(initarg);
891 return NULL;
892 }
893 Py_DECREF(initarg);
894
895 /* Restore the buffer state. Even if __init__ did initialize the buffer,
Martin Panter8f265652016-04-19 04:03:41 +0000896 we have to initialize it again since __init__ may translate the
897 newlines in the initial_value string. We clearly do not want that
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000898 because the string value in the state tuple has already been translated
899 once by __init__. So we do not take any chance and replace object's
900 buffer completely. */
901 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200902 PyObject *item;
903 Py_UCS4 *buf;
904 Py_ssize_t bufsize;
905
906 item = PyTuple_GET_ITEM(state, 0);
907 buf = PyUnicode_AsUCS4Copy(item);
908 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000909 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200910 bufsize = PyUnicode_GET_LENGTH(item);
911
912 if (resize_buffer(self, bufsize) < 0) {
913 PyMem_Free(buf);
914 return NULL;
915 }
916 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
917 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000918 self->string_size = bufsize;
919 }
920
921 /* Set carefully the position value. Alternatively, we could use the seek
922 method instead of modifying self->pos directly to better protect the
923 object internal state against errneous (or malicious) inputs. */
924 position_obj = PyTuple_GET_ITEM(state, 2);
925 if (!PyLong_Check(position_obj)) {
926 PyErr_Format(PyExc_TypeError,
927 "third item of state must be an integer, got %.200s",
928 Py_TYPE(position_obj)->tp_name);
929 return NULL;
930 }
931 pos = PyLong_AsSsize_t(position_obj);
932 if (pos == -1 && PyErr_Occurred())
933 return NULL;
934 if (pos < 0) {
935 PyErr_SetString(PyExc_ValueError,
936 "position value cannot be negative");
937 return NULL;
938 }
939 self->pos = pos;
940
941 /* Set the dictionary of the instance variables. */
942 dict = PyTuple_GET_ITEM(state, 3);
943 if (dict != Py_None) {
944 if (!PyDict_Check(dict)) {
945 PyErr_Format(PyExc_TypeError,
946 "fourth item of state should be a dict, got a %.200s",
947 Py_TYPE(dict)->tp_name);
948 return NULL;
949 }
950 if (self->dict) {
951 /* Alternatively, we could replace the internal dictionary
952 completely. However, it seems more practical to just update it. */
953 if (PyDict_Update(self->dict, dict) < 0)
954 return NULL;
955 }
956 else {
957 Py_INCREF(dict);
958 self->dict = dict;
959 }
960 }
961
962 Py_RETURN_NONE;
963}
964
965
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000966static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000967stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968{
969 CHECK_INITIALIZED(self);
970 return PyBool_FromLong(self->closed);
971}
972
973static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000974stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000975{
976 CHECK_INITIALIZED(self);
977 CHECK_CLOSED(self);
978 Py_RETURN_FALSE;
979}
980
981static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000982stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983{
984 CHECK_INITIALIZED(self);
985 CHECK_CLOSED(self);
986 if (self->decoder == NULL)
987 Py_RETURN_NONE;
988 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
989}
990
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300991#include "clinic/stringio.c.h"
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000992
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300993static struct PyMethodDef stringio_methods[] = {
994 _IO_STRINGIO_CLOSE_METHODDEF
995 _IO_STRINGIO_GETVALUE_METHODDEF
996 _IO_STRINGIO_READ_METHODDEF
997 _IO_STRINGIO_READLINE_METHODDEF
998 _IO_STRINGIO_TELL_METHODDEF
999 _IO_STRINGIO_TRUNCATE_METHODDEF
1000 _IO_STRINGIO_SEEK_METHODDEF
1001 _IO_STRINGIO_WRITE_METHODDEF
1002
1003 _IO_STRINGIO_SEEKABLE_METHODDEF
1004 _IO_STRINGIO_READABLE_METHODDEF
1005 _IO_STRINGIO_WRITABLE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001006
1007 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
1008 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001009 {NULL, NULL} /* sentinel */
1010};
1011
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012static PyGetSetDef stringio_getset[] = {
1013 {"closed", (getter)stringio_closed, NULL, NULL},
1014 {"newlines", (getter)stringio_newlines, NULL, NULL},
1015 /* (following comments straight off of the original Python wrapper:)
1016 XXX Cruft to support the TextIOWrapper API. This would only
1017 be meaningful if StringIO supported the buffer attribute.
1018 Hopefully, a better solution, than adding these pseudo-attributes,
1019 will be found.
1020 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001022 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001023};
1024
1025PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001026 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001027 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001028 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001029 0, /*tp_itemsize*/
1030 (destructor)stringio_dealloc, /*tp_dealloc*/
1031 0, /*tp_print*/
1032 0, /*tp_getattr*/
1033 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001034 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001035 0, /*tp_repr*/
1036 0, /*tp_as_number*/
1037 0, /*tp_as_sequence*/
1038 0, /*tp_as_mapping*/
1039 0, /*tp_hash*/
1040 0, /*tp_call*/
1041 0, /*tp_str*/
1042 0, /*tp_getattro*/
1043 0, /*tp_setattro*/
1044 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001045 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1046 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001047 _io_StringIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001048 (traverseproc)stringio_traverse, /*tp_traverse*/
1049 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001050 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001051 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001052 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001053 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001054 stringio_methods, /*tp_methods*/
1055 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001056 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001057 0, /*tp_base*/
1058 0, /*tp_dict*/
1059 0, /*tp_descr_get*/
1060 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001061 offsetof(stringio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001062 _io_StringIO___init__, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001063 0, /*tp_alloc*/
1064 stringio_new, /*tp_new*/
1065};