blob: 21c2b19a407d7b25bc3ee7ec315af19a42261995 [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
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000699 /* Parse the newline argument. This used to be done with the 'z'
700 specifier, however this allowed any object with the buffer interface to
701 be converted. Thus we have to parse it manually since we only want to
702 allow unicode objects or None. */
703 if (newline_obj == Py_None) {
704 newline = NULL;
705 }
706 else if (newline_obj) {
707 if (!PyUnicode_Check(newline_obj)) {
708 PyErr_Format(PyExc_TypeError,
709 "newline must be str or None, not %.200s",
710 Py_TYPE(newline_obj)->tp_name);
711 return -1;
712 }
713 newline = _PyUnicode_AsString(newline_obj);
714 if (newline == NULL)
715 return -1;
716 }
717
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000718 if (newline && newline[0] != '\0'
719 && !(newline[0] == '\n' && newline[1] == '\0')
720 && !(newline[0] == '\r' && newline[1] == '\0')
721 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
722 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000723 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000724 return -1;
725 }
726 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000727 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000728 "initial_value must be str or None, not %.200s",
729 Py_TYPE(value)->tp_name);
730 return -1;
731 }
732
733 self->ok = 0;
734
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100735 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000736 Py_CLEAR(self->readnl);
737 Py_CLEAR(self->writenl);
738 Py_CLEAR(self->decoder);
739
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000740 assert((newline != NULL && newline_obj != Py_None) ||
741 (newline == NULL && newline_obj == Py_None));
742
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000743 if (newline) {
744 self->readnl = PyUnicode_FromString(newline);
745 if (self->readnl == NULL)
746 return -1;
747 }
748 self->readuniversal = (newline == NULL || newline[0] == '\0');
749 self->readtranslate = (newline == NULL);
750 /* If newline == "", we don't translate anything.
751 If newline == "\n" or newline == None, we translate to "\n", which is
752 a no-op.
Martin Panter9955a372015-10-07 10:26:23 +0000753 (for newline == None, TextIOWrapper translates to os.linesep, but it
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 is pointless for StringIO)
755 */
756 if (newline != NULL && newline[0] == '\r') {
757 self->writenl = self->readnl;
758 Py_INCREF(self->writenl);
759 }
760
761 if (self->readuniversal) {
762 self->decoder = PyObject_CallFunction(
763 (PyObject *)&PyIncrementalNewlineDecoder_Type,
764 "Oi", Py_None, (int) self->readtranslate);
765 if (self->decoder == NULL)
766 return -1;
767 }
768
769 /* Now everything is set up, resize buffer to size of initial value,
770 and copy it */
771 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100772 if (value && value != Py_None)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100773 value_len = PyUnicode_GetLength(value);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100774 else
775 value_len = 0;
776 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000777 /* This is a heuristic, for newline translation might change
778 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100779 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000780 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100781 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000782 self->pos = 0;
783 if (write_str(self, value) < 0)
784 return -1;
785 }
786 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100787 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000788 if (resize_buffer(self, 0) < 0)
789 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100790 if (_PyAccu_Init(&self->accu))
791 return -1;
792 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000793 }
794 self->pos = 0;
795
796 self->closed = 0;
797 self->ok = 1;
798 return 0;
799}
800
801/* Properties and pseudo-properties */
Antoine Pitrou1d857452012-09-05 20:11:49 +0200802
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300803/*[clinic input]
804_io.StringIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200805
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300806Returns True if the IO object can be read.
807[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200808
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000809static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300810_io_StringIO_readable_impl(stringio *self)
811/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000812{
813 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200814 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000815 Py_RETURN_TRUE;
816}
817
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300818/*[clinic input]
819_io.StringIO.writable
820
821Returns True if the IO object can be written.
822[clinic start generated code]*/
823
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000824static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300825_io_StringIO_writable_impl(stringio *self)
826/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000827{
828 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200829 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000830 Py_RETURN_TRUE;
831}
832
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300833/*[clinic input]
834_io.StringIO.seekable
835
836Returns True if the IO object can be seeked.
837[clinic start generated code]*/
838
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000839static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300840_io_StringIO_seekable_impl(stringio *self)
841/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000842{
843 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200844 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000845 Py_RETURN_TRUE;
846}
847
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000848/* Pickling support.
849
850 The implementation of __getstate__ is similar to the one for BytesIO,
851 except that we also save the newline parameter. For __setstate__ and unlike
852 BytesIO, we call __init__ to restore the object's state. Doing so allows us
853 to avoid decoding the complex newline state while keeping the object
854 representation compact.
855
856 See comment in bytesio.c regarding why only pickle protocols and onward are
857 supported.
858*/
859
860static PyObject *
861stringio_getstate(stringio *self)
862{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300863 PyObject *initvalue = _io_StringIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000864 PyObject *dict;
865 PyObject *state;
866
867 if (initvalue == NULL)
868 return NULL;
869 if (self->dict == NULL) {
870 Py_INCREF(Py_None);
871 dict = Py_None;
872 }
873 else {
874 dict = PyDict_Copy(self->dict);
875 if (dict == NULL)
876 return NULL;
877 }
878
879 state = Py_BuildValue("(OOnN)", initvalue,
880 self->readnl ? self->readnl : Py_None,
881 self->pos, dict);
882 Py_DECREF(initvalue);
883 return state;
884}
885
886static PyObject *
887stringio_setstate(stringio *self, PyObject *state)
888{
889 PyObject *initarg;
890 PyObject *position_obj;
891 PyObject *dict;
892 Py_ssize_t pos;
893
894 assert(state != NULL);
895 CHECK_CLOSED(self);
896
897 /* We allow the state tuple to be longer than 4, because we may need
898 someday to extend the object's state without breaking
899 backward-compatibility. */
900 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
901 PyErr_Format(PyExc_TypeError,
902 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
903 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
904 return NULL;
905 }
906
907 /* Initialize the object's state. */
908 initarg = PyTuple_GetSlice(state, 0, 2);
909 if (initarg == NULL)
910 return NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300911 if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000912 Py_DECREF(initarg);
913 return NULL;
914 }
915 Py_DECREF(initarg);
916
917 /* Restore the buffer state. Even if __init__ did initialize the buffer,
918 we have to initialize it again since __init__ may translates the
919 newlines in the inital_value string. We clearly do not want that
920 because the string value in the state tuple has already been translated
921 once by __init__. So we do not take any chance and replace object's
922 buffer completely. */
923 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200924 PyObject *item;
925 Py_UCS4 *buf;
926 Py_ssize_t bufsize;
927
928 item = PyTuple_GET_ITEM(state, 0);
929 buf = PyUnicode_AsUCS4Copy(item);
930 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000931 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200932 bufsize = PyUnicode_GET_LENGTH(item);
933
934 if (resize_buffer(self, bufsize) < 0) {
935 PyMem_Free(buf);
936 return NULL;
937 }
938 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
939 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000940 self->string_size = bufsize;
941 }
942
943 /* Set carefully the position value. Alternatively, we could use the seek
944 method instead of modifying self->pos directly to better protect the
945 object internal state against errneous (or malicious) inputs. */
946 position_obj = PyTuple_GET_ITEM(state, 2);
947 if (!PyLong_Check(position_obj)) {
948 PyErr_Format(PyExc_TypeError,
949 "third item of state must be an integer, got %.200s",
950 Py_TYPE(position_obj)->tp_name);
951 return NULL;
952 }
953 pos = PyLong_AsSsize_t(position_obj);
954 if (pos == -1 && PyErr_Occurred())
955 return NULL;
956 if (pos < 0) {
957 PyErr_SetString(PyExc_ValueError,
958 "position value cannot be negative");
959 return NULL;
960 }
961 self->pos = pos;
962
963 /* Set the dictionary of the instance variables. */
964 dict = PyTuple_GET_ITEM(state, 3);
965 if (dict != Py_None) {
966 if (!PyDict_Check(dict)) {
967 PyErr_Format(PyExc_TypeError,
968 "fourth item of state should be a dict, got a %.200s",
969 Py_TYPE(dict)->tp_name);
970 return NULL;
971 }
972 if (self->dict) {
973 /* Alternatively, we could replace the internal dictionary
974 completely. However, it seems more practical to just update it. */
975 if (PyDict_Update(self->dict, dict) < 0)
976 return NULL;
977 }
978 else {
979 Py_INCREF(dict);
980 self->dict = dict;
981 }
982 }
983
984 Py_RETURN_NONE;
985}
986
987
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000988static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000989stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990{
991 CHECK_INITIALIZED(self);
992 return PyBool_FromLong(self->closed);
993}
994
995static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000996stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997{
998 CHECK_INITIALIZED(self);
999 CHECK_CLOSED(self);
1000 Py_RETURN_FALSE;
1001}
1002
1003static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001004stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001005{
1006 CHECK_INITIALIZED(self);
1007 CHECK_CLOSED(self);
1008 if (self->decoder == NULL)
1009 Py_RETURN_NONE;
1010 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
1011}
1012
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001013#include "clinic/stringio.c.h"
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001014
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001015static struct PyMethodDef stringio_methods[] = {
1016 _IO_STRINGIO_CLOSE_METHODDEF
1017 _IO_STRINGIO_GETVALUE_METHODDEF
1018 _IO_STRINGIO_READ_METHODDEF
1019 _IO_STRINGIO_READLINE_METHODDEF
1020 _IO_STRINGIO_TELL_METHODDEF
1021 _IO_STRINGIO_TRUNCATE_METHODDEF
1022 _IO_STRINGIO_SEEK_METHODDEF
1023 _IO_STRINGIO_WRITE_METHODDEF
1024
1025 _IO_STRINGIO_SEEKABLE_METHODDEF
1026 _IO_STRINGIO_READABLE_METHODDEF
1027 _IO_STRINGIO_WRITABLE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001028
1029 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
1030 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001031 {NULL, NULL} /* sentinel */
1032};
1033
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001034static PyGetSetDef stringio_getset[] = {
1035 {"closed", (getter)stringio_closed, NULL, NULL},
1036 {"newlines", (getter)stringio_newlines, NULL, NULL},
1037 /* (following comments straight off of the original Python wrapper:)
1038 XXX Cruft to support the TextIOWrapper API. This would only
1039 be meaningful if StringIO supported the buffer attribute.
1040 Hopefully, a better solution, than adding these pseudo-attributes,
1041 will be found.
1042 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001043 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001044 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001045};
1046
1047PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001048 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001049 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001050 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001051 0, /*tp_itemsize*/
1052 (destructor)stringio_dealloc, /*tp_dealloc*/
1053 0, /*tp_print*/
1054 0, /*tp_getattr*/
1055 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001056 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001057 0, /*tp_repr*/
1058 0, /*tp_as_number*/
1059 0, /*tp_as_sequence*/
1060 0, /*tp_as_mapping*/
1061 0, /*tp_hash*/
1062 0, /*tp_call*/
1063 0, /*tp_str*/
1064 0, /*tp_getattro*/
1065 0, /*tp_setattro*/
1066 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001067 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1068 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001069 _io_StringIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001070 (traverseproc)stringio_traverse, /*tp_traverse*/
1071 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001072 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001073 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001074 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001076 stringio_methods, /*tp_methods*/
1077 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001078 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001079 0, /*tp_base*/
1080 0, /*tp_dict*/
1081 0, /*tp_descr_get*/
1082 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001083 offsetof(stringio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001084 _io_StringIO___init__, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001085 0, /*tp_alloc*/
1086 stringio_new, /*tp_new*/
1087};