blob: a1c31c08567b3c23d77da40f1ad6c8f2ad492ec3 [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 */
763static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000764stringio_seekable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000765{
766 CHECK_INITIALIZED(self);
767 Py_RETURN_TRUE;
768}
769
770static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000771stringio_readable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000772{
773 CHECK_INITIALIZED(self);
774 Py_RETURN_TRUE;
775}
776
777static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000778stringio_writable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000779{
780 CHECK_INITIALIZED(self);
781 Py_RETURN_TRUE;
782}
783
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000784/* Pickling support.
785
786 The implementation of __getstate__ is similar to the one for BytesIO,
787 except that we also save the newline parameter. For __setstate__ and unlike
788 BytesIO, we call __init__ to restore the object's state. Doing so allows us
789 to avoid decoding the complex newline state while keeping the object
790 representation compact.
791
792 See comment in bytesio.c regarding why only pickle protocols and onward are
793 supported.
794*/
795
796static PyObject *
797stringio_getstate(stringio *self)
798{
799 PyObject *initvalue = stringio_getvalue(self);
800 PyObject *dict;
801 PyObject *state;
802
803 if (initvalue == NULL)
804 return NULL;
805 if (self->dict == NULL) {
806 Py_INCREF(Py_None);
807 dict = Py_None;
808 }
809 else {
810 dict = PyDict_Copy(self->dict);
811 if (dict == NULL)
812 return NULL;
813 }
814
815 state = Py_BuildValue("(OOnN)", initvalue,
816 self->readnl ? self->readnl : Py_None,
817 self->pos, dict);
818 Py_DECREF(initvalue);
819 return state;
820}
821
822static PyObject *
823stringio_setstate(stringio *self, PyObject *state)
824{
825 PyObject *initarg;
826 PyObject *position_obj;
827 PyObject *dict;
828 Py_ssize_t pos;
829
830 assert(state != NULL);
831 CHECK_CLOSED(self);
832
833 /* We allow the state tuple to be longer than 4, because we may need
834 someday to extend the object's state without breaking
835 backward-compatibility. */
836 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
837 PyErr_Format(PyExc_TypeError,
838 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
839 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
840 return NULL;
841 }
842
843 /* Initialize the object's state. */
844 initarg = PyTuple_GetSlice(state, 0, 2);
845 if (initarg == NULL)
846 return NULL;
847 if (stringio_init(self, initarg, NULL) < 0) {
848 Py_DECREF(initarg);
849 return NULL;
850 }
851 Py_DECREF(initarg);
852
853 /* Restore the buffer state. Even if __init__ did initialize the buffer,
854 we have to initialize it again since __init__ may translates the
855 newlines in the inital_value string. We clearly do not want that
856 because the string value in the state tuple has already been translated
857 once by __init__. So we do not take any chance and replace object's
858 buffer completely. */
859 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200860 PyObject *item;
861 Py_UCS4 *buf;
862 Py_ssize_t bufsize;
863
864 item = PyTuple_GET_ITEM(state, 0);
865 buf = PyUnicode_AsUCS4Copy(item);
866 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000867 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200868 bufsize = PyUnicode_GET_LENGTH(item);
869
870 if (resize_buffer(self, bufsize) < 0) {
871 PyMem_Free(buf);
872 return NULL;
873 }
874 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
875 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000876 self->string_size = bufsize;
877 }
878
879 /* Set carefully the position value. Alternatively, we could use the seek
880 method instead of modifying self->pos directly to better protect the
881 object internal state against errneous (or malicious) inputs. */
882 position_obj = PyTuple_GET_ITEM(state, 2);
883 if (!PyLong_Check(position_obj)) {
884 PyErr_Format(PyExc_TypeError,
885 "third item of state must be an integer, got %.200s",
886 Py_TYPE(position_obj)->tp_name);
887 return NULL;
888 }
889 pos = PyLong_AsSsize_t(position_obj);
890 if (pos == -1 && PyErr_Occurred())
891 return NULL;
892 if (pos < 0) {
893 PyErr_SetString(PyExc_ValueError,
894 "position value cannot be negative");
895 return NULL;
896 }
897 self->pos = pos;
898
899 /* Set the dictionary of the instance variables. */
900 dict = PyTuple_GET_ITEM(state, 3);
901 if (dict != Py_None) {
902 if (!PyDict_Check(dict)) {
903 PyErr_Format(PyExc_TypeError,
904 "fourth item of state should be a dict, got a %.200s",
905 Py_TYPE(dict)->tp_name);
906 return NULL;
907 }
908 if (self->dict) {
909 /* Alternatively, we could replace the internal dictionary
910 completely. However, it seems more practical to just update it. */
911 if (PyDict_Update(self->dict, dict) < 0)
912 return NULL;
913 }
914 else {
915 Py_INCREF(dict);
916 self->dict = dict;
917 }
918 }
919
920 Py_RETURN_NONE;
921}
922
923
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000925stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000926{
927 CHECK_INITIALIZED(self);
928 return PyBool_FromLong(self->closed);
929}
930
931static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000932stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000933{
934 CHECK_INITIALIZED(self);
935 CHECK_CLOSED(self);
936 Py_RETURN_FALSE;
937}
938
939static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000940stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000941{
942 CHECK_INITIALIZED(self);
943 CHECK_CLOSED(self);
944 if (self->decoder == NULL)
945 Py_RETURN_NONE;
946 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
947}
948
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000949static struct PyMethodDef stringio_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000950 {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
Antoine Pitroud5c3f6c2010-09-02 19:48:07 +0000951 {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000952 {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
953 {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
954 {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
955 {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc},
956 {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc},
957 {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000958
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000959 {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS},
960 {"readable", (PyCFunction)stringio_readable, METH_NOARGS},
961 {"writable", (PyCFunction)stringio_writable, METH_NOARGS},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000962
963 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
964 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000965 {NULL, NULL} /* sentinel */
966};
967
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000968static PyGetSetDef stringio_getset[] = {
969 {"closed", (getter)stringio_closed, NULL, NULL},
970 {"newlines", (getter)stringio_newlines, NULL, NULL},
971 /* (following comments straight off of the original Python wrapper:)
972 XXX Cruft to support the TextIOWrapper API. This would only
973 be meaningful if StringIO supported the buffer attribute.
974 Hopefully, a better solution, than adding these pseudo-attributes,
975 will be found.
976 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000977 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000978 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000979};
980
981PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000982 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000983 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000984 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000985 0, /*tp_itemsize*/
986 (destructor)stringio_dealloc, /*tp_dealloc*/
987 0, /*tp_print*/
988 0, /*tp_getattr*/
989 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000990 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000991 0, /*tp_repr*/
992 0, /*tp_as_number*/
993 0, /*tp_as_sequence*/
994 0, /*tp_as_mapping*/
995 0, /*tp_hash*/
996 0, /*tp_call*/
997 0, /*tp_str*/
998 0, /*tp_getattro*/
999 0, /*tp_setattro*/
1000 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001001 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1002 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1003 stringio_doc, /*tp_doc*/
1004 (traverseproc)stringio_traverse, /*tp_traverse*/
1005 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001006 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001007 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001008 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001009 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001010 stringio_methods, /*tp_methods*/
1011 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001013 0, /*tp_base*/
1014 0, /*tp_dict*/
1015 0, /*tp_descr_get*/
1016 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001017 offsetof(stringio, dict), /*tp_dictoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 (initproc)stringio_init, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001019 0, /*tp_alloc*/
1020 stringio_new, /*tp_new*/
1021};