blob: ef450328fa37b644e0600e21efa8d23dade8c555 [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
Oren Milman00425102017-03-13 00:37:05 +0200461 if (PyIndex_Check(arg)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Oren Milman00425102017-03-13 00:37:05 +0200463 if (size == -1 && PyErr_Occurred()) {
Benjamin Petersonc9e435e2008-09-30 02:22:04 +0000464 return NULL;
Oren Milman00425102017-03-13 00:37:05 +0200465 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000466 }
467 else if (arg == Py_None) {
468 /* Truncate to current position if no argument is passed. */
469 size = self->pos;
470 }
471 else {
Oren Milman00425102017-03-13 00:37:05 +0200472 PyErr_Format(PyExc_TypeError,
473 "argument should be integer or None, not '%.200s'",
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000474 Py_TYPE(arg)->tp_name);
475 return NULL;
476 }
477
478 if (size < 0) {
479 PyErr_Format(PyExc_ValueError,
480 "Negative size value %zd", size);
481 return NULL;
482 }
483
484 if (size < self->string_size) {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100485 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000486 if (resize_buffer(self, size) < 0)
487 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000488 self->string_size = size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000489 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000490
491 return PyLong_FromSsize_t(size);
492}
493
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300494/*[clinic input]
495_io.StringIO.seek
496 pos: Py_ssize_t
497 whence: int = 0
498 /
499
500Change stream position.
501
502Seek to character offset pos relative to position indicated by whence:
503 0 Start of stream (the default). pos should be >= 0;
504 1 Current position - pos must be 0;
505 2 End of stream - pos must be 0.
506Returns the new absolute position.
507[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000508
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000509static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300510_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence)
511/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000512{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000513 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000514 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000515
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300516 if (whence != 0 && whence != 1 && whence != 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000517 PyErr_Format(PyExc_ValueError,
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300518 "Invalid whence (%i, should be 0, 1 or 2)", whence);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000519 return NULL;
520 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300521 else if (pos < 0 && whence == 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000522 PyErr_Format(PyExc_ValueError,
523 "Negative seek position %zd", pos);
524 return NULL;
525 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300526 else if (whence != 0 && pos != 0) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000527 PyErr_SetString(PyExc_IOError,
528 "Can't do nonzero cur-relative seeks");
529 return NULL;
530 }
531
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300532 /* whence = 0: offset relative to beginning of the string.
533 whence = 1: no change to current position.
534 whence = 2: change position to end of file. */
535 if (whence == 1) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000536 pos = self->pos;
537 }
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300538 else if (whence == 2) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000539 pos = self->string_size;
540 }
541
542 self->pos = pos;
543
544 return PyLong_FromSsize_t(self->pos);
545}
546
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300547/*[clinic input]
548_io.StringIO.write
549 s as obj: object
550 /
551
552Write string to file.
553
554Returns the number of characters written, which is always equal to
555the length of the string.
556[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000557
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000558static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300559_io_StringIO_write(stringio *self, PyObject *obj)
560/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000561{
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000562 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000563
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000564 CHECK_INITIALIZED(self);
565 if (!PyUnicode_Check(obj)) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000566 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
567 Py_TYPE(obj)->tp_name);
568 return NULL;
569 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200570 if (PyUnicode_READY(obj))
571 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572 CHECK_CLOSED(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200573 size = PyUnicode_GET_LENGTH(obj);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000574
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575 if (size > 0 && write_str(self, obj) < 0)
576 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000577
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578 return PyLong_FromSsize_t(size);
579}
580
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300581/*[clinic input]
582_io.StringIO.close
583
584Close the IO object.
585
586Attempting any further operation after the object is closed
587will raise a ValueError.
588
589This method has no effect if the file is already closed.
590[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000591
592static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300593_io_StringIO_close_impl(stringio *self)
594/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000595{
596 self->closed = 1;
597 /* Free up some memory */
598 if (resize_buffer(self, 0) < 0)
599 return NULL;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100600 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601 Py_CLEAR(self->readnl);
602 Py_CLEAR(self->writenl);
603 Py_CLEAR(self->decoder);
604 Py_RETURN_NONE;
605}
606
607static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000608stringio_traverse(stringio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609{
610 Py_VISIT(self->dict);
611 return 0;
612}
613
614static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000615stringio_clear(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616{
617 Py_CLEAR(self->dict);
618 return 0;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000619}
620
621static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000622stringio_dealloc(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000623{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000624 _PyObject_GC_UNTRACK(self);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000625 self->ok = 0;
626 if (self->buf) {
627 PyMem_Free(self->buf);
628 self->buf = NULL;
629 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100630 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000631 Py_CLEAR(self->readnl);
632 Py_CLEAR(self->writenl);
633 Py_CLEAR(self->decoder);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000634 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635 if (self->weakreflist != NULL)
636 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000637 Py_TYPE(self)->tp_free(self);
638}
639
640static PyObject *
641stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
642{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000643 stringio *self;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000644
645 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000646 self = (stringio *)type->tp_alloc(type, 0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000647 if (self == NULL)
648 return NULL;
649
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000650 /* tp_alloc initializes all the fields to zero. So we don't have to
651 initialize them here. */
652
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200653 self->buf = (Py_UCS4 *)PyMem_Malloc(0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000654 if (self->buf == NULL) {
655 Py_DECREF(self);
656 return PyErr_NoMemory();
657 }
658
659 return (PyObject *)self;
660}
661
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300662/*[clinic input]
663_io.StringIO.__init__
664 initial_value as value: object(c_default="NULL") = ''
665 newline as newline_obj: object(c_default="NULL") = '\n'
666
667Text I/O implementation using an in-memory buffer.
668
669The initial_value argument sets the value of object. The newline
670argument is like the one of TextIOWrapper's constructor.
671[clinic start generated code]*/
672
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000673static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300674_io_StringIO___init___impl(stringio *self, PyObject *value,
675 PyObject *newline_obj)
676/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000677{
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200678 const char *newline = "\n";
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100679 Py_ssize_t value_len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000680
Martin Panterf2644162015-10-10 10:17:57 +0000681 /* Parse the newline argument. We only want to allow unicode objects or
682 None. */
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000683 if (newline_obj == Py_None) {
684 newline = NULL;
685 }
686 else if (newline_obj) {
687 if (!PyUnicode_Check(newline_obj)) {
688 PyErr_Format(PyExc_TypeError,
689 "newline must be str or None, not %.200s",
690 Py_TYPE(newline_obj)->tp_name);
691 return -1;
692 }
Serhiy Storchaka06515832016-11-20 09:13:07 +0200693 newline = PyUnicode_AsUTF8(newline_obj);
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000694 if (newline == NULL)
695 return -1;
696 }
697
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000698 if (newline && newline[0] != '\0'
699 && !(newline[0] == '\n' && newline[1] == '\0')
700 && !(newline[0] == '\r' && newline[1] == '\0')
701 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
702 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000703 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000704 return -1;
705 }
706 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000707 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708 "initial_value must be str or None, not %.200s",
709 Py_TYPE(value)->tp_name);
710 return -1;
711 }
712
713 self->ok = 0;
714
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100715 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000716 Py_CLEAR(self->readnl);
717 Py_CLEAR(self->writenl);
718 Py_CLEAR(self->decoder);
719
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000720 assert((newline != NULL && newline_obj != Py_None) ||
721 (newline == NULL && newline_obj == Py_None));
722
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723 if (newline) {
724 self->readnl = PyUnicode_FromString(newline);
725 if (self->readnl == NULL)
726 return -1;
727 }
728 self->readuniversal = (newline == NULL || newline[0] == '\0');
729 self->readtranslate = (newline == NULL);
730 /* If newline == "", we don't translate anything.
731 If newline == "\n" or newline == None, we translate to "\n", which is
732 a no-op.
Martin Panter9955a372015-10-07 10:26:23 +0000733 (for newline == None, TextIOWrapper translates to os.linesep, but it
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000734 is pointless for StringIO)
735 */
736 if (newline != NULL && newline[0] == '\r') {
737 self->writenl = self->readnl;
738 Py_INCREF(self->writenl);
739 }
740
741 if (self->readuniversal) {
742 self->decoder = PyObject_CallFunction(
743 (PyObject *)&PyIncrementalNewlineDecoder_Type,
744 "Oi", Py_None, (int) self->readtranslate);
745 if (self->decoder == NULL)
746 return -1;
747 }
748
749 /* Now everything is set up, resize buffer to size of initial value,
750 and copy it */
751 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100752 if (value && value != Py_None)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100753 value_len = PyUnicode_GetLength(value);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100754 else
755 value_len = 0;
756 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000757 /* This is a heuristic, for newline translation might change
758 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100759 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000760 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100761 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000762 self->pos = 0;
763 if (write_str(self, value) < 0)
764 return -1;
765 }
766 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100767 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000768 if (resize_buffer(self, 0) < 0)
769 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100770 if (_PyAccu_Init(&self->accu))
771 return -1;
772 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773 }
774 self->pos = 0;
775
776 self->closed = 0;
777 self->ok = 1;
778 return 0;
779}
780
781/* Properties and pseudo-properties */
Antoine Pitrou1d857452012-09-05 20:11:49 +0200782
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300783/*[clinic input]
784_io.StringIO.readable
Antoine Pitrou1d857452012-09-05 20:11:49 +0200785
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300786Returns True if the IO object can be read.
787[clinic start generated code]*/
Antoine Pitrou1d857452012-09-05 20:11:49 +0200788
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000789static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300790_io_StringIO_readable_impl(stringio *self)
791/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000792{
793 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200794 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000795 Py_RETURN_TRUE;
796}
797
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300798/*[clinic input]
799_io.StringIO.writable
800
801Returns True if the IO object can be written.
802[clinic start generated code]*/
803
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000804static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300805_io_StringIO_writable_impl(stringio *self)
806/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000807{
808 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200809 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000810 Py_RETURN_TRUE;
811}
812
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300813/*[clinic input]
814_io.StringIO.seekable
815
816Returns True if the IO object can be seeked.
817[clinic start generated code]*/
818
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300820_io_StringIO_seekable_impl(stringio *self)
821/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822{
823 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200824 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000825 Py_RETURN_TRUE;
826}
827
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000828/* Pickling support.
829
830 The implementation of __getstate__ is similar to the one for BytesIO,
831 except that we also save the newline parameter. For __setstate__ and unlike
832 BytesIO, we call __init__ to restore the object's state. Doing so allows us
833 to avoid decoding the complex newline state while keeping the object
834 representation compact.
835
836 See comment in bytesio.c regarding why only pickle protocols and onward are
837 supported.
838*/
839
840static PyObject *
841stringio_getstate(stringio *self)
842{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300843 PyObject *initvalue = _io_StringIO_getvalue_impl(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000844 PyObject *dict;
845 PyObject *state;
846
847 if (initvalue == NULL)
848 return NULL;
849 if (self->dict == NULL) {
850 Py_INCREF(Py_None);
851 dict = Py_None;
852 }
853 else {
854 dict = PyDict_Copy(self->dict);
855 if (dict == NULL)
856 return NULL;
857 }
858
859 state = Py_BuildValue("(OOnN)", initvalue,
860 self->readnl ? self->readnl : Py_None,
861 self->pos, dict);
862 Py_DECREF(initvalue);
863 return state;
864}
865
866static PyObject *
867stringio_setstate(stringio *self, PyObject *state)
868{
869 PyObject *initarg;
870 PyObject *position_obj;
871 PyObject *dict;
872 Py_ssize_t pos;
873
874 assert(state != NULL);
875 CHECK_CLOSED(self);
876
877 /* We allow the state tuple to be longer than 4, because we may need
878 someday to extend the object's state without breaking
879 backward-compatibility. */
Serhiy Storchakafff9a312017-03-21 08:53:25 +0200880 if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 4) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000881 PyErr_Format(PyExc_TypeError,
882 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
883 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
884 return NULL;
885 }
886
887 /* Initialize the object's state. */
888 initarg = PyTuple_GetSlice(state, 0, 2);
889 if (initarg == NULL)
890 return NULL;
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300891 if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000892 Py_DECREF(initarg);
893 return NULL;
894 }
895 Py_DECREF(initarg);
896
897 /* Restore the buffer state. Even if __init__ did initialize the buffer,
Martin Panter8f265652016-04-19 04:03:41 +0000898 we have to initialize it again since __init__ may translate the
899 newlines in the initial_value string. We clearly do not want that
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000900 because the string value in the state tuple has already been translated
901 once by __init__. So we do not take any chance and replace object's
902 buffer completely. */
903 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200904 PyObject *item;
905 Py_UCS4 *buf;
906 Py_ssize_t bufsize;
907
908 item = PyTuple_GET_ITEM(state, 0);
909 buf = PyUnicode_AsUCS4Copy(item);
910 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000911 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200912 bufsize = PyUnicode_GET_LENGTH(item);
913
914 if (resize_buffer(self, bufsize) < 0) {
915 PyMem_Free(buf);
916 return NULL;
917 }
918 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
919 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000920 self->string_size = bufsize;
921 }
922
923 /* Set carefully the position value. Alternatively, we could use the seek
924 method instead of modifying self->pos directly to better protect the
925 object internal state against errneous (or malicious) inputs. */
926 position_obj = PyTuple_GET_ITEM(state, 2);
927 if (!PyLong_Check(position_obj)) {
928 PyErr_Format(PyExc_TypeError,
929 "third item of state must be an integer, got %.200s",
930 Py_TYPE(position_obj)->tp_name);
931 return NULL;
932 }
933 pos = PyLong_AsSsize_t(position_obj);
934 if (pos == -1 && PyErr_Occurred())
935 return NULL;
936 if (pos < 0) {
937 PyErr_SetString(PyExc_ValueError,
938 "position value cannot be negative");
939 return NULL;
940 }
941 self->pos = pos;
942
943 /* Set the dictionary of the instance variables. */
944 dict = PyTuple_GET_ITEM(state, 3);
945 if (dict != Py_None) {
946 if (!PyDict_Check(dict)) {
947 PyErr_Format(PyExc_TypeError,
948 "fourth item of state should be a dict, got a %.200s",
949 Py_TYPE(dict)->tp_name);
950 return NULL;
951 }
952 if (self->dict) {
953 /* Alternatively, we could replace the internal dictionary
954 completely. However, it seems more practical to just update it. */
955 if (PyDict_Update(self->dict, dict) < 0)
956 return NULL;
957 }
958 else {
959 Py_INCREF(dict);
960 self->dict = dict;
961 }
962 }
963
964 Py_RETURN_NONE;
965}
966
967
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000969stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000970{
971 CHECK_INITIALIZED(self);
972 return PyBool_FromLong(self->closed);
973}
974
975static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000976stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000977{
978 CHECK_INITIALIZED(self);
979 CHECK_CLOSED(self);
980 Py_RETURN_FALSE;
981}
982
983static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000984stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000985{
986 CHECK_INITIALIZED(self);
987 CHECK_CLOSED(self);
988 if (self->decoder == NULL)
989 Py_RETURN_NONE;
990 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
991}
992
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300993#include "clinic/stringio.c.h"
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000994
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300995static struct PyMethodDef stringio_methods[] = {
996 _IO_STRINGIO_CLOSE_METHODDEF
997 _IO_STRINGIO_GETVALUE_METHODDEF
998 _IO_STRINGIO_READ_METHODDEF
999 _IO_STRINGIO_READLINE_METHODDEF
1000 _IO_STRINGIO_TELL_METHODDEF
1001 _IO_STRINGIO_TRUNCATE_METHODDEF
1002 _IO_STRINGIO_SEEK_METHODDEF
1003 _IO_STRINGIO_WRITE_METHODDEF
1004
1005 _IO_STRINGIO_SEEKABLE_METHODDEF
1006 _IO_STRINGIO_READABLE_METHODDEF
1007 _IO_STRINGIO_WRITABLE_METHODDEF
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +00001008
1009 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
1010 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001011 {NULL, NULL} /* sentinel */
1012};
1013
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014static PyGetSetDef stringio_getset[] = {
1015 {"closed", (getter)stringio_closed, NULL, NULL},
1016 {"newlines", (getter)stringio_newlines, NULL, NULL},
1017 /* (following comments straight off of the original Python wrapper:)
1018 XXX Cruft to support the TextIOWrapper API. This would only
1019 be meaningful if StringIO supported the buffer attribute.
1020 Hopefully, a better solution, than adding these pseudo-attributes,
1021 will be found.
1022 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001023 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00001024 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001025};
1026
1027PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001028 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001029 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001030 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001031 0, /*tp_itemsize*/
1032 (destructor)stringio_dealloc, /*tp_dealloc*/
1033 0, /*tp_print*/
1034 0, /*tp_getattr*/
1035 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001036 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001037 0, /*tp_repr*/
1038 0, /*tp_as_number*/
1039 0, /*tp_as_sequence*/
1040 0, /*tp_as_mapping*/
1041 0, /*tp_hash*/
1042 0, /*tp_call*/
1043 0, /*tp_str*/
1044 0, /*tp_getattro*/
1045 0, /*tp_setattro*/
1046 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1048 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001049 _io_StringIO___init____doc__, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001050 (traverseproc)stringio_traverse, /*tp_traverse*/
1051 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001052 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001053 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001054 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001055 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001056 stringio_methods, /*tp_methods*/
1057 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001058 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001059 0, /*tp_base*/
1060 0, /*tp_dict*/
1061 0, /*tp_descr_get*/
1062 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001063 offsetof(stringio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001064 _io_StringIO___init__, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001065 0, /*tp_alloc*/
1066 stringio_new, /*tp_new*/
1067};