blob: 9d73884f731758d21f2531224d5ed852dd298671 [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
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000014typedef struct {
15 PyObject_HEAD
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020016 Py_UCS4 *buf;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000017 Py_ssize_t pos;
18 Py_ssize_t string_size;
19 size_t buf_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000020
Antoine Pitroude20b0b2011-11-10 21:47:38 +010021 /* The stringio object can be in two states: accumulating or realized.
22 In accumulating state, the internal buffer contains nothing and
23 the contents are given by the embedded _PyAccu structure.
24 In realized state, the internal buffer is meaningful and the
25 _PyAccu is destroyed.
26 */
27 int state;
28 _PyAccu accu;
29
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000030 char ok; /* initialized? */
31 char closed;
32 char readuniversal;
33 char readtranslate;
34 PyObject *decoder;
35 PyObject *readnl;
36 PyObject *writenl;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020037
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000038 PyObject *dict;
39 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000040} stringio;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042#define CHECK_INITIALIZED(self) \
43 if (self->ok <= 0) { \
44 PyErr_SetString(PyExc_ValueError, \
45 "I/O operation on uninitialized object"); \
46 return NULL; \
47 }
48
49#define CHECK_CLOSED(self) \
50 if (self->closed) { \
51 PyErr_SetString(PyExc_ValueError, \
52 "I/O operation on closed file"); \
53 return NULL; \
54 }
55
Antoine Pitroude20b0b2011-11-10 21:47:38 +010056#define ENSURE_REALIZED(self) \
57 if (realize(self) < 0) { \
58 return NULL; \
59 }
60
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000061PyDoc_STRVAR(stringio_doc,
62 "Text I/O implementation using an in-memory buffer.\n"
63 "\n"
64 "The initial_value argument sets the value of object. The newline\n"
65 "argument is like the one of TextIOWrapper's constructor.");
66
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000067
68/* Internal routine for changing the size, in terms of characters, of the
69 buffer of StringIO objects. The caller should ensure that the 'size'
70 argument is non-negative. Returns 0 on success, -1 otherwise. */
71static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000072resize_buffer(stringio *self, size_t size)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000073{
74 /* Here, unsigned types are used to avoid dealing with signed integer
75 overflow, which is undefined in C. */
76 size_t alloc = self->buf_size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020077 Py_UCS4 *new_buf = NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000078
79 assert(self->buf != NULL);
80
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000081 /* Reserve one more char for line ending detection. */
82 size = size + 1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000083 /* For simplicity, stay in the range of the signed type. Anyway, Python
84 doesn't allow strings to be longer than this. */
85 if (size > PY_SSIZE_T_MAX)
86 goto overflow;
87
88 if (size < alloc / 2) {
89 /* Major downsize; resize down to exact size. */
90 alloc = size + 1;
91 }
92 else if (size < alloc) {
93 /* Within allocated size; quick exit */
94 return 0;
95 }
96 else if (size <= alloc * 1.125) {
97 /* Moderate upsize; overallocate similar to list_resize() */
98 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
99 }
100 else {
101 /* Major upsize; resize up to exact size */
102 alloc = size + 1;
103 }
104
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200105 if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4))
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000106 goto overflow;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200107 new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000108 if (new_buf == NULL) {
109 PyErr_NoMemory();
110 return -1;
111 }
112 self->buf_size = alloc;
113 self->buf = new_buf;
114
115 return 0;
116
117 overflow:
118 PyErr_SetString(PyExc_OverflowError,
119 "new buffer size too large");
120 return -1;
121}
122
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100123static PyObject *
124make_intermediate(stringio *self)
125{
126 PyObject *intermediate = _PyAccu_Finish(&self->accu);
127 self->state = STATE_REALIZED;
128 if (intermediate == NULL)
129 return NULL;
130 if (_PyAccu_Init(&self->accu) ||
131 _PyAccu_Accumulate(&self->accu, intermediate)) {
132 Py_DECREF(intermediate);
133 return NULL;
134 }
135 self->state = STATE_ACCUMULATING;
136 return intermediate;
137}
138
139static int
140realize(stringio *self)
141{
142 Py_ssize_t len;
143 PyObject *intermediate;
144
145 if (self->state == STATE_REALIZED)
146 return 0;
147 assert(self->state == STATE_ACCUMULATING);
148 self->state = STATE_REALIZED;
149
150 intermediate = _PyAccu_Finish(&self->accu);
151 if (intermediate == NULL)
152 return -1;
153
154 /* Append the intermediate string to the internal buffer.
155 The length should be equal to the current cursor position.
156 */
157 len = PyUnicode_GET_LENGTH(intermediate);
158 if (resize_buffer(self, len) < 0) {
159 Py_DECREF(intermediate);
160 return -1;
161 }
162 if (!PyUnicode_AsUCS4(intermediate, self->buf, len, 0)) {
163 Py_DECREF(intermediate);
164 return -1;
165 }
166
167 Py_DECREF(intermediate);
168 return 0;
169}
170
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000171/* Internal routine for writing a whole PyUnicode object to the buffer of a
172 StringIO object. Returns 0 on success, or -1 on error. */
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000173static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000174write_str(stringio *self, PyObject *obj)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000175{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000176 Py_ssize_t len;
177 PyObject *decoded = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200178
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000179 assert(self->buf != NULL);
180 assert(self->pos >= 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000181
182 if (self->decoder != NULL) {
183 decoded = _PyIncrementalNewlineDecoder_decode(
184 self->decoder, obj, 1 /* always final */);
185 }
186 else {
187 decoded = obj;
188 Py_INCREF(decoded);
189 }
190 if (self->writenl) {
191 PyObject *translated = PyUnicode_Replace(
192 decoded, _PyIO_str_nl, self->writenl, -1);
193 Py_DECREF(decoded);
194 decoded = translated;
195 }
196 if (decoded == NULL)
197 return -1;
198
199 assert(PyUnicode_Check(decoded));
Victor Stinnere1335c72011-10-04 20:53:03 +0200200 if (PyUnicode_READY(decoded)) {
201 Py_DECREF(decoded);
202 return -1;
203 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200204 len = PyUnicode_GET_LENGTH(decoded);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000205 assert(len >= 0);
206
207 /* This overflow check is not strictly necessary. However, it avoids us to
208 deal with funky things like comparing an unsigned and a signed
209 integer. */
210 if (self->pos > PY_SSIZE_T_MAX - len) {
211 PyErr_SetString(PyExc_OverflowError,
212 "new position too large");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000213 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000214 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100215
216 if (self->state == STATE_ACCUMULATING) {
217 if (self->string_size == self->pos) {
218 if (_PyAccu_Accumulate(&self->accu, decoded))
219 goto fail;
220 goto success;
221 }
222 if (realize(self))
223 goto fail;
224 }
225
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000226 if (self->pos + len > self->string_size) {
227 if (resize_buffer(self, self->pos + len) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000228 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000229 }
230
231 if (self->pos > self->string_size) {
232 /* In case of overseek, pad with null bytes the buffer region between
233 the end of stream and the current position.
234
235 0 lo string_size hi
236 | |<---used--->|<----------available----------->|
237 | | <--to pad-->|<---to write---> |
Ezio Melotti13925002011-03-16 11:05:33 +0200238 0 buf position
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000239
240 */
241 memset(self->buf + self->string_size, '\0',
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200242 (self->pos - self->string_size) * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000243 }
244
245 /* Copy the data to the internal buffer, overwriting some of the
246 existing data if self->pos < self->string_size. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200247 if (!PyUnicode_AsUCS4(decoded,
248 self->buf + self->pos,
249 self->buf_size - self->pos,
250 0))
251 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000252
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100253success:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000254 /* Set the new length of the internal string if it has changed. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200255 self->pos += len;
256 if (self->string_size < self->pos)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000257 self->string_size = self->pos;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000258
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000259 Py_DECREF(decoded);
260 return 0;
261
262fail:
263 Py_XDECREF(decoded);
264 return -1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000265}
266
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000267PyDoc_STRVAR(stringio_getvalue_doc,
268 "Retrieve the entire contents of the object.");
269
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000270static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000271stringio_getvalue(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000272{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000273 CHECK_INITIALIZED(self);
274 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100275 if (self->state == STATE_ACCUMULATING)
276 return make_intermediate(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200277 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, self->buf,
278 self->string_size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000279}
280
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000281PyDoc_STRVAR(stringio_tell_doc,
282 "Tell the current file position.");
283
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000284static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000285stringio_tell(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000286{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000287 CHECK_INITIALIZED(self);
288 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000289 return PyLong_FromSsize_t(self->pos);
290}
291
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000292PyDoc_STRVAR(stringio_read_doc,
293 "Read at most n characters, returned as a string.\n"
294 "\n"
295 "If the argument is negative or omitted, read until EOF\n"
296 "is reached. Return an empty string at EOF.\n");
297
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000298static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000299stringio_read(stringio *self, PyObject *args)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000300{
301 Py_ssize_t size, n;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200302 Py_UCS4 *output;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000303 PyObject *arg = Py_None;
304
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000305 CHECK_INITIALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000306 if (!PyArg_ParseTuple(args, "|O:read", &arg))
307 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000308 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000309
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000310 if (PyNumber_Check(arg)) {
311 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Amaury Forgeot d'Arc58fb9052008-09-30 20:22:44 +0000312 if (size == -1 && PyErr_Occurred())
313 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000314 }
315 else if (arg == Py_None) {
316 /* Read until EOF is reached, by default. */
317 size = -1;
318 }
319 else {
320 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
321 Py_TYPE(arg)->tp_name);
322 return NULL;
323 }
324
325 /* adjust invalid sizes */
326 n = self->string_size - self->pos;
327 if (size < 0 || size > n) {
328 size = n;
329 if (size < 0)
330 size = 0;
331 }
332
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100333 /* Optimization for seek(0); read() */
334 if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) {
335 PyObject *result = make_intermediate(self);
336 self->pos = self->string_size;
337 return result;
338 }
339
340 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000341 output = self->buf + self->pos;
342 self->pos += size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200343 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000344}
345
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000346/* Internal helper, used by stringio_readline and stringio_iternext */
347static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000348_stringio_readline(stringio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000349{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200350 Py_UCS4 *start, *end, old_char;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000351 Py_ssize_t len, consumed;
352
353 /* In case of overseek, return the empty string */
354 if (self->pos >= self->string_size)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200355 return PyUnicode_New(0, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000356
357 start = self->buf + self->pos;
358 if (limit < 0 || limit > self->string_size - self->pos)
359 limit = self->string_size - self->pos;
360
361 end = start + limit;
362 old_char = *end;
363 *end = '\0';
364 len = _PyIO_find_line_ending(
365 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200366 PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000367 *end = old_char;
368 /* If we haven't found any line ending, we just return everything
369 (`consumed` is ignored). */
370 if (len < 0)
371 len = limit;
372 self->pos += len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200373 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000374}
375
376PyDoc_STRVAR(stringio_readline_doc,
377 "Read until newline or EOF.\n"
378 "\n"
379 "Returns an empty string if EOF is hit immediately.\n");
380
381static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000382stringio_readline(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000383{
384 PyObject *arg = Py_None;
385 Py_ssize_t limit = -1;
386
387 CHECK_INITIALIZED(self);
388 if (!PyArg_ParseTuple(args, "|O:readline", &arg))
389 return NULL;
390 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100391 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000392
393 if (PyNumber_Check(arg)) {
394 limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
395 if (limit == -1 && PyErr_Occurred())
396 return NULL;
397 }
398 else if (arg != Py_None) {
399 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
400 Py_TYPE(arg)->tp_name);
401 return NULL;
402 }
403 return _stringio_readline(self, limit);
404}
405
406static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000407stringio_iternext(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000408{
409 PyObject *line;
410
411 CHECK_INITIALIZED(self);
412 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100413 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000414
415 if (Py_TYPE(self) == &PyStringIO_Type) {
416 /* Skip method call overhead for speed */
417 line = _stringio_readline(self, -1);
418 }
419 else {
420 /* XXX is subclassing StringIO really supported? */
421 line = PyObject_CallMethodObjArgs((PyObject *)self,
422 _PyIO_str_readline, NULL);
423 if (line && !PyUnicode_Check(line)) {
424 PyErr_Format(PyExc_IOError,
425 "readline() should have returned an str object, "
426 "not '%.200s'", Py_TYPE(line)->tp_name);
427 Py_DECREF(line);
428 return NULL;
429 }
430 }
431
432 if (line == NULL)
433 return NULL;
434
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200435 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000436 /* Reached EOF */
437 Py_DECREF(line);
438 return NULL;
439 }
440
441 return line;
442}
443
444PyDoc_STRVAR(stringio_truncate_doc,
445 "Truncate size to pos.\n"
446 "\n"
447 "The pos argument defaults to the current file position, as\n"
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000448 "returned by tell(). The current file position is unchanged.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000449 "Returns the new absolute position.\n");
450
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000451static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000452stringio_truncate(stringio *self, PyObject *args)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000453{
454 Py_ssize_t size;
455 PyObject *arg = Py_None;
456
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000457 CHECK_INITIALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000458 if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
459 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000460 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000461
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462 if (PyNumber_Check(arg)) {
463 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Benjamin Petersonc9e435e2008-09-30 02:22:04 +0000464 if (size == -1 && PyErr_Occurred())
465 return NULL;
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 {
472 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
473 Py_TYPE(arg)->tp_name);
474 return NULL;
475 }
476
477 if (size < 0) {
478 PyErr_Format(PyExc_ValueError,
479 "Negative size value %zd", size);
480 return NULL;
481 }
482
483 if (size < self->string_size) {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100484 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000485 if (resize_buffer(self, size) < 0)
486 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487 self->string_size = size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000488 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000489
490 return PyLong_FromSsize_t(size);
491}
492
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000493PyDoc_STRVAR(stringio_seek_doc,
494 "Change stream position.\n"
495 "\n"
496 "Seek to character offset pos relative to position indicated by whence:\n"
497 " 0 Start of stream (the default). pos should be >= 0;\n"
498 " 1 Current position - pos must be 0;\n"
499 " 2 End of stream - pos must be 0.\n"
500 "Returns the new absolute position.\n");
501
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000502static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000503stringio_seek(stringio *self, PyObject *args)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000504{
505 Py_ssize_t pos;
506 int mode = 0;
507
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000508 CHECK_INITIALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000509 if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
510 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000511 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000512
513 if (mode != 0 && mode != 1 && mode != 2) {
514 PyErr_Format(PyExc_ValueError,
515 "Invalid whence (%i, should be 0, 1 or 2)", mode);
516 return NULL;
517 }
518 else if (pos < 0 && mode == 0) {
519 PyErr_Format(PyExc_ValueError,
520 "Negative seek position %zd", pos);
521 return NULL;
522 }
523 else if (mode != 0 && pos != 0) {
524 PyErr_SetString(PyExc_IOError,
525 "Can't do nonzero cur-relative seeks");
526 return NULL;
527 }
528
529 /* mode 0: offset relative to beginning of the string.
530 mode 1: no change to current position.
531 mode 2: change position to end of file. */
532 if (mode == 1) {
533 pos = self->pos;
534 }
535 else if (mode == 2) {
536 pos = self->string_size;
537 }
538
539 self->pos = pos;
540
541 return PyLong_FromSsize_t(self->pos);
542}
543
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000544PyDoc_STRVAR(stringio_write_doc,
545 "Write string to file.\n"
546 "\n"
547 "Returns the number of characters written, which is always equal to\n"
548 "the length of the string.\n");
549
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000550static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000551stringio_write(stringio *self, PyObject *obj)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000552{
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000553 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000554
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000555 CHECK_INITIALIZED(self);
556 if (!PyUnicode_Check(obj)) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000557 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
558 Py_TYPE(obj)->tp_name);
559 return NULL;
560 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200561 if (PyUnicode_READY(obj))
562 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000563 CHECK_CLOSED(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200564 size = PyUnicode_GET_LENGTH(obj);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000565
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000566 if (size > 0 && write_str(self, obj) < 0)
567 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000568
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569 return PyLong_FromSsize_t(size);
570}
571
572PyDoc_STRVAR(stringio_close_doc,
573 "Close the IO object. Attempting any further operation after the\n"
574 "object is closed will raise a ValueError.\n"
575 "\n"
576 "This method has no effect if the file is already closed.\n");
577
578static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000579stringio_close(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000580{
581 self->closed = 1;
582 /* Free up some memory */
583 if (resize_buffer(self, 0) < 0)
584 return NULL;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100585 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000586 Py_CLEAR(self->readnl);
587 Py_CLEAR(self->writenl);
588 Py_CLEAR(self->decoder);
589 Py_RETURN_NONE;
590}
591
592static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000593stringio_traverse(stringio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594{
595 Py_VISIT(self->dict);
596 return 0;
597}
598
599static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000600stringio_clear(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601{
602 Py_CLEAR(self->dict);
603 return 0;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000604}
605
606static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000607stringio_dealloc(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000608{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609 _PyObject_GC_UNTRACK(self);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000610 self->ok = 0;
611 if (self->buf) {
612 PyMem_Free(self->buf);
613 self->buf = NULL;
614 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100615 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000616 Py_CLEAR(self->readnl);
617 Py_CLEAR(self->writenl);
618 Py_CLEAR(self->decoder);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000619 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620 if (self->weakreflist != NULL)
621 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000622 Py_TYPE(self)->tp_free(self);
623}
624
625static PyObject *
626stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
627{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000628 stringio *self;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000629
630 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000631 self = (stringio *)type->tp_alloc(type, 0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000632 if (self == NULL)
633 return NULL;
634
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000635 /* tp_alloc initializes all the fields to zero. So we don't have to
636 initialize them here. */
637
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200638 self->buf = (Py_UCS4 *)PyMem_Malloc(0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000639 if (self->buf == NULL) {
640 Py_DECREF(self);
641 return PyErr_NoMemory();
642 }
643
644 return (PyObject *)self;
645}
646
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000648stringio_init(stringio *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649{
650 char *kwlist[] = {"initial_value", "newline", NULL};
651 PyObject *value = NULL;
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000652 PyObject *newline_obj = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653 char *newline = "\n";
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100654 Py_ssize_t value_len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000655
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000656 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:__init__", kwlist,
657 &value, &newline_obj))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658 return -1;
659
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000660 /* Parse the newline argument. This used to be done with the 'z'
661 specifier, however this allowed any object with the buffer interface to
662 be converted. Thus we have to parse it manually since we only want to
663 allow unicode objects or None. */
664 if (newline_obj == Py_None) {
665 newline = NULL;
666 }
667 else if (newline_obj) {
668 if (!PyUnicode_Check(newline_obj)) {
669 PyErr_Format(PyExc_TypeError,
670 "newline must be str or None, not %.200s",
671 Py_TYPE(newline_obj)->tp_name);
672 return -1;
673 }
674 newline = _PyUnicode_AsString(newline_obj);
675 if (newline == NULL)
676 return -1;
677 }
678
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000679 if (newline && newline[0] != '\0'
680 && !(newline[0] == '\n' && newline[1] == '\0')
681 && !(newline[0] == '\r' && newline[1] == '\0')
682 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
683 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000684 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000685 return -1;
686 }
687 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000688 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689 "initial_value must be str or None, not %.200s",
690 Py_TYPE(value)->tp_name);
691 return -1;
692 }
693
694 self->ok = 0;
695
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100696 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000697 Py_CLEAR(self->readnl);
698 Py_CLEAR(self->writenl);
699 Py_CLEAR(self->decoder);
700
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000701 assert((newline != NULL && newline_obj != Py_None) ||
702 (newline == NULL && newline_obj == Py_None));
703
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000704 if (newline) {
705 self->readnl = PyUnicode_FromString(newline);
706 if (self->readnl == NULL)
707 return -1;
708 }
709 self->readuniversal = (newline == NULL || newline[0] == '\0');
710 self->readtranslate = (newline == NULL);
711 /* If newline == "", we don't translate anything.
712 If newline == "\n" or newline == None, we translate to "\n", which is
713 a no-op.
714 (for newline == None, TextIOWrapper translates to os.sepline, but it
715 is pointless for StringIO)
716 */
717 if (newline != NULL && newline[0] == '\r') {
718 self->writenl = self->readnl;
719 Py_INCREF(self->writenl);
720 }
721
722 if (self->readuniversal) {
723 self->decoder = PyObject_CallFunction(
724 (PyObject *)&PyIncrementalNewlineDecoder_Type,
725 "Oi", Py_None, (int) self->readtranslate);
726 if (self->decoder == NULL)
727 return -1;
728 }
729
730 /* Now everything is set up, resize buffer to size of initial value,
731 and copy it */
732 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100733 if (value && value != Py_None)
Victor Stinner9e30aa52011-11-21 02:49:52 +0100734 value_len = PyUnicode_GetLength(value);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100735 else
736 value_len = 0;
737 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000738 /* This is a heuristic, for newline translation might change
739 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100740 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100742 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000743 self->pos = 0;
744 if (write_str(self, value) < 0)
745 return -1;
746 }
747 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100748 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000749 if (resize_buffer(self, 0) < 0)
750 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100751 if (_PyAccu_Init(&self->accu))
752 return -1;
753 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000754 }
755 self->pos = 0;
756
757 self->closed = 0;
758 self->ok = 1;
759 return 0;
760}
761
762/* Properties and pseudo-properties */
Antoine Pitrou1d857452012-09-05 20:11:49 +0200763
764PyDoc_STRVAR(stringio_readable_doc,
765"readable() -> bool. Returns True if the IO object can be read.");
766
767PyDoc_STRVAR(stringio_writable_doc,
768"writable() -> bool. Returns True if the IO object can be written.");
769
770PyDoc_STRVAR(stringio_seekable_doc,
771"seekable() -> bool. Returns True if the IO object can be seeked.");
772
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000773static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000774stringio_seekable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000775{
776 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200777 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778 Py_RETURN_TRUE;
779}
780
781static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000782stringio_readable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000783{
784 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200785 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000786 Py_RETURN_TRUE;
787}
788
789static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000790stringio_writable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000791{
792 CHECK_INITIALIZED(self);
Antoine Pitrou1d857452012-09-05 20:11:49 +0200793 CHECK_CLOSED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000794 Py_RETURN_TRUE;
795}
796
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000797/* Pickling support.
798
799 The implementation of __getstate__ is similar to the one for BytesIO,
800 except that we also save the newline parameter. For __setstate__ and unlike
801 BytesIO, we call __init__ to restore the object's state. Doing so allows us
802 to avoid decoding the complex newline state while keeping the object
803 representation compact.
804
805 See comment in bytesio.c regarding why only pickle protocols and onward are
806 supported.
807*/
808
809static PyObject *
810stringio_getstate(stringio *self)
811{
812 PyObject *initvalue = stringio_getvalue(self);
813 PyObject *dict;
814 PyObject *state;
815
816 if (initvalue == NULL)
817 return NULL;
818 if (self->dict == NULL) {
819 Py_INCREF(Py_None);
820 dict = Py_None;
821 }
822 else {
823 dict = PyDict_Copy(self->dict);
824 if (dict == NULL)
825 return NULL;
826 }
827
828 state = Py_BuildValue("(OOnN)", initvalue,
829 self->readnl ? self->readnl : Py_None,
830 self->pos, dict);
831 Py_DECREF(initvalue);
832 return state;
833}
834
835static PyObject *
836stringio_setstate(stringio *self, PyObject *state)
837{
838 PyObject *initarg;
839 PyObject *position_obj;
840 PyObject *dict;
841 Py_ssize_t pos;
842
843 assert(state != NULL);
844 CHECK_CLOSED(self);
845
846 /* We allow the state tuple to be longer than 4, because we may need
847 someday to extend the object's state without breaking
848 backward-compatibility. */
849 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
850 PyErr_Format(PyExc_TypeError,
851 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
852 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
853 return NULL;
854 }
855
856 /* Initialize the object's state. */
857 initarg = PyTuple_GetSlice(state, 0, 2);
858 if (initarg == NULL)
859 return NULL;
860 if (stringio_init(self, initarg, NULL) < 0) {
861 Py_DECREF(initarg);
862 return NULL;
863 }
864 Py_DECREF(initarg);
865
866 /* Restore the buffer state. Even if __init__ did initialize the buffer,
867 we have to initialize it again since __init__ may translates the
868 newlines in the inital_value string. We clearly do not want that
869 because the string value in the state tuple has already been translated
870 once by __init__. So we do not take any chance and replace object's
871 buffer completely. */
872 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200873 PyObject *item;
874 Py_UCS4 *buf;
875 Py_ssize_t bufsize;
876
877 item = PyTuple_GET_ITEM(state, 0);
878 buf = PyUnicode_AsUCS4Copy(item);
879 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000880 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200881 bufsize = PyUnicode_GET_LENGTH(item);
882
883 if (resize_buffer(self, bufsize) < 0) {
884 PyMem_Free(buf);
885 return NULL;
886 }
887 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
888 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000889 self->string_size = bufsize;
890 }
891
892 /* Set carefully the position value. Alternatively, we could use the seek
893 method instead of modifying self->pos directly to better protect the
894 object internal state against errneous (or malicious) inputs. */
895 position_obj = PyTuple_GET_ITEM(state, 2);
896 if (!PyLong_Check(position_obj)) {
897 PyErr_Format(PyExc_TypeError,
898 "third item of state must be an integer, got %.200s",
899 Py_TYPE(position_obj)->tp_name);
900 return NULL;
901 }
902 pos = PyLong_AsSsize_t(position_obj);
903 if (pos == -1 && PyErr_Occurred())
904 return NULL;
905 if (pos < 0) {
906 PyErr_SetString(PyExc_ValueError,
907 "position value cannot be negative");
908 return NULL;
909 }
910 self->pos = pos;
911
912 /* Set the dictionary of the instance variables. */
913 dict = PyTuple_GET_ITEM(state, 3);
914 if (dict != Py_None) {
915 if (!PyDict_Check(dict)) {
916 PyErr_Format(PyExc_TypeError,
917 "fourth item of state should be a dict, got a %.200s",
918 Py_TYPE(dict)->tp_name);
919 return NULL;
920 }
921 if (self->dict) {
922 /* Alternatively, we could replace the internal dictionary
923 completely. However, it seems more practical to just update it. */
924 if (PyDict_Update(self->dict, dict) < 0)
925 return NULL;
926 }
927 else {
928 Py_INCREF(dict);
929 self->dict = dict;
930 }
931 }
932
933 Py_RETURN_NONE;
934}
935
936
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000937static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000938stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000939{
940 CHECK_INITIALIZED(self);
941 return PyBool_FromLong(self->closed);
942}
943
944static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000945stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000946{
947 CHECK_INITIALIZED(self);
948 CHECK_CLOSED(self);
949 Py_RETURN_FALSE;
950}
951
952static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000953stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954{
955 CHECK_INITIALIZED(self);
956 CHECK_CLOSED(self);
957 if (self->decoder == NULL)
958 Py_RETURN_NONE;
959 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
960}
961
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000962static struct PyMethodDef stringio_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
Antoine Pitroud5c3f6c2010-09-02 19:48:07 +0000964 {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000965 {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
966 {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
967 {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
968 {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc},
969 {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc},
970 {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000971
Antoine Pitrou1d857452012-09-05 20:11:49 +0200972 {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS, stringio_seekable_doc},
973 {"readable", (PyCFunction)stringio_readable, METH_NOARGS, stringio_readable_doc},
974 {"writable", (PyCFunction)stringio_writable, METH_NOARGS, stringio_writable_doc},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000975
976 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
977 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000978 {NULL, NULL} /* sentinel */
979};
980
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000981static PyGetSetDef stringio_getset[] = {
982 {"closed", (getter)stringio_closed, NULL, NULL},
983 {"newlines", (getter)stringio_newlines, NULL, NULL},
984 /* (following comments straight off of the original Python wrapper:)
985 XXX Cruft to support the TextIOWrapper API. This would only
986 be meaningful if StringIO supported the buffer attribute.
987 Hopefully, a better solution, than adding these pseudo-attributes,
988 will be found.
989 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000990 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000991 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992};
993
994PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000995 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000996 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000997 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000998 0, /*tp_itemsize*/
999 (destructor)stringio_dealloc, /*tp_dealloc*/
1000 0, /*tp_print*/
1001 0, /*tp_getattr*/
1002 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001003 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001004 0, /*tp_repr*/
1005 0, /*tp_as_number*/
1006 0, /*tp_as_sequence*/
1007 0, /*tp_as_mapping*/
1008 0, /*tp_hash*/
1009 0, /*tp_call*/
1010 0, /*tp_str*/
1011 0, /*tp_getattro*/
1012 0, /*tp_setattro*/
1013 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001014 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1015 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1016 stringio_doc, /*tp_doc*/
1017 (traverseproc)stringio_traverse, /*tp_traverse*/
1018 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001019 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001020 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001021 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001022 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001023 stringio_methods, /*tp_methods*/
1024 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001025 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001026 0, /*tp_base*/
1027 0, /*tp_dict*/
1028 0, /*tp_descr_get*/
1029 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001030 offsetof(stringio, dict), /*tp_dictoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001031 (initproc)stringio_init, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001032 0, /*tp_alloc*/
1033 stringio_new, /*tp_new*/
1034};