blob: 774999015c9e172e0b4cd8debe5b0f3122ca6819 [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"
4#include "_iomodule.h"
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00005
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00006/* Implementation note: the buffer is always at least one character longer
7 than the enclosed string, for proper functioning of _PyIO_find_line_ending.
8*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00009
Antoine Pitroude20b0b2011-11-10 21:47:38 +010010#define STATE_REALIZED 1
11#define STATE_ACCUMULATING 2
12
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000013typedef struct {
14 PyObject_HEAD
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020015 Py_UCS4 *buf;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000016 Py_ssize_t pos;
17 Py_ssize_t string_size;
18 size_t buf_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000019
Antoine Pitroude20b0b2011-11-10 21:47:38 +010020 /* The stringio object can be in two states: accumulating or realized.
21 In accumulating state, the internal buffer contains nothing and
22 the contents are given by the embedded _PyAccu structure.
23 In realized state, the internal buffer is meaningful and the
24 _PyAccu is destroyed.
25 */
26 int state;
27 _PyAccu accu;
28
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000029 char ok; /* initialized? */
30 char closed;
31 char readuniversal;
32 char readtranslate;
33 PyObject *decoder;
34 PyObject *readnl;
35 PyObject *writenl;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020036
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000037 PyObject *dict;
38 PyObject *weakreflist;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000039} stringio;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000040
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000041#define CHECK_INITIALIZED(self) \
42 if (self->ok <= 0) { \
43 PyErr_SetString(PyExc_ValueError, \
44 "I/O operation on uninitialized object"); \
45 return NULL; \
46 }
47
48#define CHECK_CLOSED(self) \
49 if (self->closed) { \
50 PyErr_SetString(PyExc_ValueError, \
51 "I/O operation on closed file"); \
52 return NULL; \
53 }
54
Antoine Pitroude20b0b2011-11-10 21:47:38 +010055#define ENSURE_REALIZED(self) \
56 if (realize(self) < 0) { \
57 return NULL; \
58 }
59
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000060PyDoc_STRVAR(stringio_doc,
61 "Text I/O implementation using an in-memory buffer.\n"
62 "\n"
63 "The initial_value argument sets the value of object. The newline\n"
64 "argument is like the one of TextIOWrapper's constructor.");
65
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000066
67/* Internal routine for changing the size, in terms of characters, of the
68 buffer of StringIO objects. The caller should ensure that the 'size'
69 argument is non-negative. Returns 0 on success, -1 otherwise. */
70static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000071resize_buffer(stringio *self, size_t size)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000072{
73 /* Here, unsigned types are used to avoid dealing with signed integer
74 overflow, which is undefined in C. */
75 size_t alloc = self->buf_size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020076 Py_UCS4 *new_buf = NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000077
78 assert(self->buf != NULL);
79
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000080 /* Reserve one more char for line ending detection. */
81 size = size + 1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000082 /* For simplicity, stay in the range of the signed type. Anyway, Python
83 doesn't allow strings to be longer than this. */
84 if (size > PY_SSIZE_T_MAX)
85 goto overflow;
86
87 if (size < alloc / 2) {
88 /* Major downsize; resize down to exact size. */
89 alloc = size + 1;
90 }
91 else if (size < alloc) {
92 /* Within allocated size; quick exit */
93 return 0;
94 }
95 else if (size <= alloc * 1.125) {
96 /* Moderate upsize; overallocate similar to list_resize() */
97 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
98 }
99 else {
100 /* Major upsize; resize up to exact size */
101 alloc = size + 1;
102 }
103
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200104 if (alloc > PY_SIZE_MAX / sizeof(Py_UCS4))
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000105 goto overflow;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200106 new_buf = (Py_UCS4 *)PyMem_Realloc(self->buf, alloc * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000107 if (new_buf == NULL) {
108 PyErr_NoMemory();
109 return -1;
110 }
111 self->buf_size = alloc;
112 self->buf = new_buf;
113
114 return 0;
115
116 overflow:
117 PyErr_SetString(PyExc_OverflowError,
118 "new buffer size too large");
119 return -1;
120}
121
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100122static PyObject *
123make_intermediate(stringio *self)
124{
125 PyObject *intermediate = _PyAccu_Finish(&self->accu);
126 self->state = STATE_REALIZED;
127 if (intermediate == NULL)
128 return NULL;
129 if (_PyAccu_Init(&self->accu) ||
130 _PyAccu_Accumulate(&self->accu, intermediate)) {
131 Py_DECREF(intermediate);
132 return NULL;
133 }
134 self->state = STATE_ACCUMULATING;
135 return intermediate;
136}
137
138static int
139realize(stringio *self)
140{
141 Py_ssize_t len;
142 PyObject *intermediate;
143
144 if (self->state == STATE_REALIZED)
145 return 0;
146 assert(self->state == STATE_ACCUMULATING);
147 self->state = STATE_REALIZED;
148
149 intermediate = _PyAccu_Finish(&self->accu);
150 if (intermediate == NULL)
151 return -1;
152
153 /* Append the intermediate string to the internal buffer.
154 The length should be equal to the current cursor position.
155 */
156 len = PyUnicode_GET_LENGTH(intermediate);
157 if (resize_buffer(self, len) < 0) {
158 Py_DECREF(intermediate);
159 return -1;
160 }
161 if (!PyUnicode_AsUCS4(intermediate, self->buf, len, 0)) {
162 Py_DECREF(intermediate);
163 return -1;
164 }
165
166 Py_DECREF(intermediate);
167 return 0;
168}
169
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000170/* Internal routine for writing a whole PyUnicode object to the buffer of a
171 StringIO object. Returns 0 on success, or -1 on error. */
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000172static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000173write_str(stringio *self, PyObject *obj)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000174{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000175 Py_ssize_t len;
176 PyObject *decoded = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200177
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000178 assert(self->buf != NULL);
179 assert(self->pos >= 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180
181 if (self->decoder != NULL) {
182 decoded = _PyIncrementalNewlineDecoder_decode(
183 self->decoder, obj, 1 /* always final */);
184 }
185 else {
186 decoded = obj;
187 Py_INCREF(decoded);
188 }
189 if (self->writenl) {
190 PyObject *translated = PyUnicode_Replace(
191 decoded, _PyIO_str_nl, self->writenl, -1);
192 Py_DECREF(decoded);
193 decoded = translated;
194 }
195 if (decoded == NULL)
196 return -1;
197
198 assert(PyUnicode_Check(decoded));
Victor Stinnere1335c72011-10-04 20:53:03 +0200199 if (PyUnicode_READY(decoded)) {
200 Py_DECREF(decoded);
201 return -1;
202 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200203 len = PyUnicode_GET_LENGTH(decoded);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000204 assert(len >= 0);
205
206 /* This overflow check is not strictly necessary. However, it avoids us to
207 deal with funky things like comparing an unsigned and a signed
208 integer. */
209 if (self->pos > PY_SSIZE_T_MAX - len) {
210 PyErr_SetString(PyExc_OverflowError,
211 "new position too large");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000212 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000213 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100214
215 if (self->state == STATE_ACCUMULATING) {
216 if (self->string_size == self->pos) {
217 if (_PyAccu_Accumulate(&self->accu, decoded))
218 goto fail;
219 goto success;
220 }
221 if (realize(self))
222 goto fail;
223 }
224
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000225 if (self->pos + len > self->string_size) {
226 if (resize_buffer(self, self->pos + len) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000227 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000228 }
229
230 if (self->pos > self->string_size) {
231 /* In case of overseek, pad with null bytes the buffer region between
232 the end of stream and the current position.
233
234 0 lo string_size hi
235 | |<---used--->|<----------available----------->|
236 | | <--to pad-->|<---to write---> |
Ezio Melotti13925002011-03-16 11:05:33 +0200237 0 buf position
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000238
239 */
240 memset(self->buf + self->string_size, '\0',
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200241 (self->pos - self->string_size) * sizeof(Py_UCS4));
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000242 }
243
244 /* Copy the data to the internal buffer, overwriting some of the
245 existing data if self->pos < self->string_size. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200246 if (!PyUnicode_AsUCS4(decoded,
247 self->buf + self->pos,
248 self->buf_size - self->pos,
249 0))
250 goto fail;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000251
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100252success:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000253 /* Set the new length of the internal string if it has changed. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200254 self->pos += len;
255 if (self->string_size < self->pos)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000256 self->string_size = self->pos;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000257
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000258 Py_DECREF(decoded);
259 return 0;
260
261fail:
262 Py_XDECREF(decoded);
263 return -1;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000264}
265
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000266PyDoc_STRVAR(stringio_getvalue_doc,
267 "Retrieve the entire contents of the object.");
268
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000269static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000270stringio_getvalue(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000271{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000272 CHECK_INITIALIZED(self);
273 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100274 if (self->state == STATE_ACCUMULATING)
275 return make_intermediate(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200276 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, self->buf,
277 self->string_size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000278}
279
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000280PyDoc_STRVAR(stringio_tell_doc,
281 "Tell the current file position.");
282
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000283static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000284stringio_tell(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000285{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000286 CHECK_INITIALIZED(self);
287 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000288 return PyLong_FromSsize_t(self->pos);
289}
290
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000291PyDoc_STRVAR(stringio_read_doc,
292 "Read at most n characters, returned as a string.\n"
293 "\n"
294 "If the argument is negative or omitted, read until EOF\n"
295 "is reached. Return an empty string at EOF.\n");
296
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000297static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000298stringio_read(stringio *self, PyObject *args)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000299{
300 Py_ssize_t size, n;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200301 Py_UCS4 *output;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000302 PyObject *arg = Py_None;
303
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000304 CHECK_INITIALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000305 if (!PyArg_ParseTuple(args, "|O:read", &arg))
306 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000307 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000308
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000309 if (PyNumber_Check(arg)) {
310 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Amaury Forgeot d'Arc58fb9052008-09-30 20:22:44 +0000311 if (size == -1 && PyErr_Occurred())
312 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000313 }
314 else if (arg == Py_None) {
315 /* Read until EOF is reached, by default. */
316 size = -1;
317 }
318 else {
319 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
320 Py_TYPE(arg)->tp_name);
321 return NULL;
322 }
323
324 /* adjust invalid sizes */
325 n = self->string_size - self->pos;
326 if (size < 0 || size > n) {
327 size = n;
328 if (size < 0)
329 size = 0;
330 }
331
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100332 /* Optimization for seek(0); read() */
333 if (self->state == STATE_ACCUMULATING && self->pos == 0 && size == n) {
334 PyObject *result = make_intermediate(self);
335 self->pos = self->string_size;
336 return result;
337 }
338
339 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000340 output = self->buf + self->pos;
341 self->pos += size;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200342 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, size);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000343}
344
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000345/* Internal helper, used by stringio_readline and stringio_iternext */
346static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000347_stringio_readline(stringio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000348{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200349 Py_UCS4 *start, *end, old_char;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000350 Py_ssize_t len, consumed;
351
352 /* In case of overseek, return the empty string */
353 if (self->pos >= self->string_size)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200354 return PyUnicode_New(0, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000355
356 start = self->buf + self->pos;
357 if (limit < 0 || limit > self->string_size - self->pos)
358 limit = self->string_size - self->pos;
359
360 end = start + limit;
361 old_char = *end;
362 *end = '\0';
363 len = _PyIO_find_line_ending(
364 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200365 PyUnicode_4BYTE_KIND, (char*)start, (char*)end, &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000366 *end = old_char;
367 /* If we haven't found any line ending, we just return everything
368 (`consumed` is ignored). */
369 if (len < 0)
370 len = limit;
371 self->pos += len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200372 return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000373}
374
375PyDoc_STRVAR(stringio_readline_doc,
376 "Read until newline or EOF.\n"
377 "\n"
378 "Returns an empty string if EOF is hit immediately.\n");
379
380static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000381stringio_readline(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000382{
383 PyObject *arg = Py_None;
384 Py_ssize_t limit = -1;
385
386 CHECK_INITIALIZED(self);
387 if (!PyArg_ParseTuple(args, "|O:readline", &arg))
388 return NULL;
389 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100390 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000391
392 if (PyNumber_Check(arg)) {
393 limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
394 if (limit == -1 && PyErr_Occurred())
395 return NULL;
396 }
397 else if (arg != Py_None) {
398 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
399 Py_TYPE(arg)->tp_name);
400 return NULL;
401 }
402 return _stringio_readline(self, limit);
403}
404
405static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000406stringio_iternext(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000407{
408 PyObject *line;
409
410 CHECK_INITIALIZED(self);
411 CHECK_CLOSED(self);
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100412 ENSURE_REALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000413
414 if (Py_TYPE(self) == &PyStringIO_Type) {
415 /* Skip method call overhead for speed */
416 line = _stringio_readline(self, -1);
417 }
418 else {
419 /* XXX is subclassing StringIO really supported? */
420 line = PyObject_CallMethodObjArgs((PyObject *)self,
421 _PyIO_str_readline, NULL);
422 if (line && !PyUnicode_Check(line)) {
423 PyErr_Format(PyExc_IOError,
424 "readline() should have returned an str object, "
425 "not '%.200s'", Py_TYPE(line)->tp_name);
426 Py_DECREF(line);
427 return NULL;
428 }
429 }
430
431 if (line == NULL)
432 return NULL;
433
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200434 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435 /* Reached EOF */
436 Py_DECREF(line);
437 return NULL;
438 }
439
440 return line;
441}
442
443PyDoc_STRVAR(stringio_truncate_doc,
444 "Truncate size to pos.\n"
445 "\n"
446 "The pos argument defaults to the current file position, as\n"
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000447 "returned by tell(). The current file position is unchanged.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000448 "Returns the new absolute position.\n");
449
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000450static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000451stringio_truncate(stringio *self, PyObject *args)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000452{
453 Py_ssize_t size;
454 PyObject *arg = Py_None;
455
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000456 CHECK_INITIALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000457 if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
458 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000459 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000460
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000461 if (PyNumber_Check(arg)) {
462 size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
Benjamin Petersonc9e435e2008-09-30 02:22:04 +0000463 if (size == -1 && PyErr_Occurred())
464 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000465 }
466 else if (arg == Py_None) {
467 /* Truncate to current position if no argument is passed. */
468 size = self->pos;
469 }
470 else {
471 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
472 Py_TYPE(arg)->tp_name);
473 return NULL;
474 }
475
476 if (size < 0) {
477 PyErr_Format(PyExc_ValueError,
478 "Negative size value %zd", size);
479 return NULL;
480 }
481
482 if (size < self->string_size) {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100483 ENSURE_REALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000484 if (resize_buffer(self, size) < 0)
485 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000486 self->string_size = size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000487 }
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000488
489 return PyLong_FromSsize_t(size);
490}
491
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000492PyDoc_STRVAR(stringio_seek_doc,
493 "Change stream position.\n"
494 "\n"
495 "Seek to character offset pos relative to position indicated by whence:\n"
496 " 0 Start of stream (the default). pos should be >= 0;\n"
497 " 1 Current position - pos must be 0;\n"
498 " 2 End of stream - pos must be 0.\n"
499 "Returns the new absolute position.\n");
500
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000501static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000502stringio_seek(stringio *self, PyObject *args)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000503{
504 Py_ssize_t pos;
505 int mode = 0;
506
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000507 CHECK_INITIALIZED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000508 if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
509 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000510 CHECK_CLOSED(self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000511
512 if (mode != 0 && mode != 1 && mode != 2) {
513 PyErr_Format(PyExc_ValueError,
514 "Invalid whence (%i, should be 0, 1 or 2)", mode);
515 return NULL;
516 }
517 else if (pos < 0 && mode == 0) {
518 PyErr_Format(PyExc_ValueError,
519 "Negative seek position %zd", pos);
520 return NULL;
521 }
522 else if (mode != 0 && pos != 0) {
523 PyErr_SetString(PyExc_IOError,
524 "Can't do nonzero cur-relative seeks");
525 return NULL;
526 }
527
528 /* mode 0: offset relative to beginning of the string.
529 mode 1: no change to current position.
530 mode 2: change position to end of file. */
531 if (mode == 1) {
532 pos = self->pos;
533 }
534 else if (mode == 2) {
535 pos = self->string_size;
536 }
537
538 self->pos = pos;
539
540 return PyLong_FromSsize_t(self->pos);
541}
542
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543PyDoc_STRVAR(stringio_write_doc,
544 "Write string to file.\n"
545 "\n"
546 "Returns the number of characters written, which is always equal to\n"
547 "the length of the string.\n");
548
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000549static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000550stringio_write(stringio *self, PyObject *obj)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000551{
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000552 Py_ssize_t size;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000553
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000554 CHECK_INITIALIZED(self);
555 if (!PyUnicode_Check(obj)) {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000556 PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
557 Py_TYPE(obj)->tp_name);
558 return NULL;
559 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200560 if (PyUnicode_READY(obj))
561 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000562 CHECK_CLOSED(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200563 size = PyUnicode_GET_LENGTH(obj);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000564
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565 if (size > 0 && write_str(self, obj) < 0)
566 return NULL;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000567
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000568 return PyLong_FromSsize_t(size);
569}
570
571PyDoc_STRVAR(stringio_close_doc,
572 "Close the IO object. Attempting any further operation after the\n"
573 "object is closed will raise a ValueError.\n"
574 "\n"
575 "This method has no effect if the file is already closed.\n");
576
577static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000578stringio_close(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000579{
580 self->closed = 1;
581 /* Free up some memory */
582 if (resize_buffer(self, 0) < 0)
583 return NULL;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100584 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585 Py_CLEAR(self->readnl);
586 Py_CLEAR(self->writenl);
587 Py_CLEAR(self->decoder);
588 Py_RETURN_NONE;
589}
590
591static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000592stringio_traverse(stringio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000593{
594 Py_VISIT(self->dict);
595 return 0;
596}
597
598static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000599stringio_clear(stringio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600{
601 Py_CLEAR(self->dict);
602 return 0;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000603}
604
605static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000606stringio_dealloc(stringio *self)
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000607{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000608 _PyObject_GC_UNTRACK(self);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000609 self->ok = 0;
610 if (self->buf) {
611 PyMem_Free(self->buf);
612 self->buf = NULL;
613 }
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100614 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000615 Py_CLEAR(self->readnl);
616 Py_CLEAR(self->writenl);
617 Py_CLEAR(self->decoder);
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000618 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000619 if (self->weakreflist != NULL)
620 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000621 Py_TYPE(self)->tp_free(self);
622}
623
624static PyObject *
625stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
626{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000627 stringio *self;
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000628
629 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000630 self = (stringio *)type->tp_alloc(type, 0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000631 if (self == NULL)
632 return NULL;
633
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000634 /* tp_alloc initializes all the fields to zero. So we don't have to
635 initialize them here. */
636
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200637 self->buf = (Py_UCS4 *)PyMem_Malloc(0);
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000638 if (self->buf == NULL) {
639 Py_DECREF(self);
640 return PyErr_NoMemory();
641 }
642
643 return (PyObject *)self;
644}
645
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000646static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000647stringio_init(stringio *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000648{
649 char *kwlist[] = {"initial_value", "newline", NULL};
650 PyObject *value = NULL;
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000651 PyObject *newline_obj = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000652 char *newline = "\n";
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100653 Py_ssize_t value_len;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000655 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:__init__", kwlist,
656 &value, &newline_obj))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000657 return -1;
658
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000659 /* Parse the newline argument. This used to be done with the 'z'
660 specifier, however this allowed any object with the buffer interface to
661 be converted. Thus we have to parse it manually since we only want to
662 allow unicode objects or None. */
663 if (newline_obj == Py_None) {
664 newline = NULL;
665 }
666 else if (newline_obj) {
667 if (!PyUnicode_Check(newline_obj)) {
668 PyErr_Format(PyExc_TypeError,
669 "newline must be str or None, not %.200s",
670 Py_TYPE(newline_obj)->tp_name);
671 return -1;
672 }
673 newline = _PyUnicode_AsString(newline_obj);
674 if (newline == NULL)
675 return -1;
676 }
677
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000678 if (newline && newline[0] != '\0'
679 && !(newline[0] == '\n' && newline[1] == '\0')
680 && !(newline[0] == '\r' && newline[1] == '\0')
681 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
682 PyErr_Format(PyExc_ValueError,
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000683 "illegal newline value: %R", newline_obj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000684 return -1;
685 }
686 if (value && value != Py_None && !PyUnicode_Check(value)) {
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000687 PyErr_Format(PyExc_TypeError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000688 "initial_value must be str or None, not %.200s",
689 Py_TYPE(value)->tp_name);
690 return -1;
691 }
692
693 self->ok = 0;
694
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100695 _PyAccu_Destroy(&self->accu);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696 Py_CLEAR(self->readnl);
697 Py_CLEAR(self->writenl);
698 Py_CLEAR(self->decoder);
699
Alexandre Vassalottid2bb18b2009-07-22 03:07:33 +0000700 assert((newline != NULL && newline_obj != Py_None) ||
701 (newline == NULL && newline_obj == Py_None));
702
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000703 if (newline) {
704 self->readnl = PyUnicode_FromString(newline);
705 if (self->readnl == NULL)
706 return -1;
707 }
708 self->readuniversal = (newline == NULL || newline[0] == '\0');
709 self->readtranslate = (newline == NULL);
710 /* If newline == "", we don't translate anything.
711 If newline == "\n" or newline == None, we translate to "\n", which is
712 a no-op.
713 (for newline == None, TextIOWrapper translates to os.sepline, but it
714 is pointless for StringIO)
715 */
716 if (newline != NULL && newline[0] == '\r') {
717 self->writenl = self->readnl;
718 Py_INCREF(self->writenl);
719 }
720
721 if (self->readuniversal) {
722 self->decoder = PyObject_CallFunction(
723 (PyObject *)&PyIncrementalNewlineDecoder_Type,
724 "Oi", Py_None, (int) self->readtranslate);
725 if (self->decoder == NULL)
726 return -1;
727 }
728
729 /* Now everything is set up, resize buffer to size of initial value,
730 and copy it */
731 self->string_size = 0;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100732 if (value && value != Py_None)
733 value_len = PyUnicode_GetSize(value);
734 else
735 value_len = 0;
736 if (value_len > 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000737 /* This is a heuristic, for newline translation might change
738 the string length. */
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100739 if (resize_buffer(self, 0) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000740 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100741 self->state = STATE_REALIZED;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000742 self->pos = 0;
743 if (write_str(self, value) < 0)
744 return -1;
745 }
746 else {
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100747 /* Empty stringio object, we can start by accumulating */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000748 if (resize_buffer(self, 0) < 0)
749 return -1;
Antoine Pitroude20b0b2011-11-10 21:47:38 +0100750 if (_PyAccu_Init(&self->accu))
751 return -1;
752 self->state = STATE_ACCUMULATING;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000753 }
754 self->pos = 0;
755
756 self->closed = 0;
757 self->ok = 1;
758 return 0;
759}
760
761/* Properties and pseudo-properties */
762static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000763stringio_seekable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000764{
765 CHECK_INITIALIZED(self);
766 Py_RETURN_TRUE;
767}
768
769static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000770stringio_readable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000771{
772 CHECK_INITIALIZED(self);
773 Py_RETURN_TRUE;
774}
775
776static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000777stringio_writable(stringio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778{
779 CHECK_INITIALIZED(self);
780 Py_RETURN_TRUE;
781}
782
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000783/* Pickling support.
784
785 The implementation of __getstate__ is similar to the one for BytesIO,
786 except that we also save the newline parameter. For __setstate__ and unlike
787 BytesIO, we call __init__ to restore the object's state. Doing so allows us
788 to avoid decoding the complex newline state while keeping the object
789 representation compact.
790
791 See comment in bytesio.c regarding why only pickle protocols and onward are
792 supported.
793*/
794
795static PyObject *
796stringio_getstate(stringio *self)
797{
798 PyObject *initvalue = stringio_getvalue(self);
799 PyObject *dict;
800 PyObject *state;
801
802 if (initvalue == NULL)
803 return NULL;
804 if (self->dict == NULL) {
805 Py_INCREF(Py_None);
806 dict = Py_None;
807 }
808 else {
809 dict = PyDict_Copy(self->dict);
810 if (dict == NULL)
811 return NULL;
812 }
813
814 state = Py_BuildValue("(OOnN)", initvalue,
815 self->readnl ? self->readnl : Py_None,
816 self->pos, dict);
817 Py_DECREF(initvalue);
818 return state;
819}
820
821static PyObject *
822stringio_setstate(stringio *self, PyObject *state)
823{
824 PyObject *initarg;
825 PyObject *position_obj;
826 PyObject *dict;
827 Py_ssize_t pos;
828
829 assert(state != NULL);
830 CHECK_CLOSED(self);
831
832 /* We allow the state tuple to be longer than 4, because we may need
833 someday to extend the object's state without breaking
834 backward-compatibility. */
835 if (!PyTuple_Check(state) || Py_SIZE(state) < 4) {
836 PyErr_Format(PyExc_TypeError,
837 "%.200s.__setstate__ argument should be 4-tuple, got %.200s",
838 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
839 return NULL;
840 }
841
842 /* Initialize the object's state. */
843 initarg = PyTuple_GetSlice(state, 0, 2);
844 if (initarg == NULL)
845 return NULL;
846 if (stringio_init(self, initarg, NULL) < 0) {
847 Py_DECREF(initarg);
848 return NULL;
849 }
850 Py_DECREF(initarg);
851
852 /* Restore the buffer state. Even if __init__ did initialize the buffer,
853 we have to initialize it again since __init__ may translates the
854 newlines in the inital_value string. We clearly do not want that
855 because the string value in the state tuple has already been translated
856 once by __init__. So we do not take any chance and replace object's
857 buffer completely. */
858 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200859 PyObject *item;
860 Py_UCS4 *buf;
861 Py_ssize_t bufsize;
862
863 item = PyTuple_GET_ITEM(state, 0);
864 buf = PyUnicode_AsUCS4Copy(item);
865 if (buf == NULL)
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000866 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200867 bufsize = PyUnicode_GET_LENGTH(item);
868
869 if (resize_buffer(self, bufsize) < 0) {
870 PyMem_Free(buf);
871 return NULL;
872 }
873 memcpy(self->buf, buf, bufsize * sizeof(Py_UCS4));
874 PyMem_Free(buf);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000875 self->string_size = bufsize;
876 }
877
878 /* Set carefully the position value. Alternatively, we could use the seek
879 method instead of modifying self->pos directly to better protect the
880 object internal state against errneous (or malicious) inputs. */
881 position_obj = PyTuple_GET_ITEM(state, 2);
882 if (!PyLong_Check(position_obj)) {
883 PyErr_Format(PyExc_TypeError,
884 "third item of state must be an integer, got %.200s",
885 Py_TYPE(position_obj)->tp_name);
886 return NULL;
887 }
888 pos = PyLong_AsSsize_t(position_obj);
889 if (pos == -1 && PyErr_Occurred())
890 return NULL;
891 if (pos < 0) {
892 PyErr_SetString(PyExc_ValueError,
893 "position value cannot be negative");
894 return NULL;
895 }
896 self->pos = pos;
897
898 /* Set the dictionary of the instance variables. */
899 dict = PyTuple_GET_ITEM(state, 3);
900 if (dict != Py_None) {
901 if (!PyDict_Check(dict)) {
902 PyErr_Format(PyExc_TypeError,
903 "fourth item of state should be a dict, got a %.200s",
904 Py_TYPE(dict)->tp_name);
905 return NULL;
906 }
907 if (self->dict) {
908 /* Alternatively, we could replace the internal dictionary
909 completely. However, it seems more practical to just update it. */
910 if (PyDict_Update(self->dict, dict) < 0)
911 return NULL;
912 }
913 else {
914 Py_INCREF(dict);
915 self->dict = dict;
916 }
917 }
918
919 Py_RETURN_NONE;
920}
921
922
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000924stringio_closed(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000925{
926 CHECK_INITIALIZED(self);
927 return PyBool_FromLong(self->closed);
928}
929
930static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000931stringio_line_buffering(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000932{
933 CHECK_INITIALIZED(self);
934 CHECK_CLOSED(self);
935 Py_RETURN_FALSE;
936}
937
938static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000939stringio_newlines(stringio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000940{
941 CHECK_INITIALIZED(self);
942 CHECK_CLOSED(self);
943 if (self->decoder == NULL)
944 Py_RETURN_NONE;
945 return PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
946}
947
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000948static struct PyMethodDef stringio_methods[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000949 {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
Antoine Pitroud5c3f6c2010-09-02 19:48:07 +0000950 {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000951 {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
952 {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
953 {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
954 {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc},
955 {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc},
956 {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000957
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958 {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS},
959 {"readable", (PyCFunction)stringio_readable, METH_NOARGS},
960 {"writable", (PyCFunction)stringio_writable, METH_NOARGS},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000961
962 {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS},
963 {"__setstate__", (PyCFunction)stringio_setstate, METH_O},
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000964 {NULL, NULL} /* sentinel */
965};
966
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967static PyGetSetDef stringio_getset[] = {
968 {"closed", (getter)stringio_closed, NULL, NULL},
969 {"newlines", (getter)stringio_newlines, NULL, NULL},
970 /* (following comments straight off of the original Python wrapper:)
971 XXX Cruft to support the TextIOWrapper API. This would only
972 be meaningful if StringIO supported the buffer attribute.
973 Hopefully, a better solution, than adding these pseudo-attributes,
974 will be found.
975 */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000976 {"line_buffering", (getter)stringio_line_buffering, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000977 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000978};
979
980PyTypeObject PyStringIO_Type = {
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000981 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982 "_io.StringIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000983 sizeof(stringio), /*tp_basicsize*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000984 0, /*tp_itemsize*/
985 (destructor)stringio_dealloc, /*tp_dealloc*/
986 0, /*tp_print*/
987 0, /*tp_getattr*/
988 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000989 0, /*tp_reserved*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000990 0, /*tp_repr*/
991 0, /*tp_as_number*/
992 0, /*tp_as_sequence*/
993 0, /*tp_as_mapping*/
994 0, /*tp_hash*/
995 0, /*tp_call*/
996 0, /*tp_str*/
997 0, /*tp_getattro*/
998 0, /*tp_setattro*/
999 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001000 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1001 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1002 stringio_doc, /*tp_doc*/
1003 (traverseproc)stringio_traverse, /*tp_traverse*/
1004 (inquiry)stringio_clear, /*tp_clear*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001005 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001006 offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001007 0, /*tp_iter*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001008 (iternextfunc)stringio_iternext, /*tp_iternext*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001009 stringio_methods, /*tp_methods*/
1010 0, /*tp_members*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001011 stringio_getset, /*tp_getset*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001012 0, /*tp_base*/
1013 0, /*tp_dict*/
1014 0, /*tp_descr_get*/
1015 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001016 offsetof(stringio, dict), /*tp_dictoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001017 (initproc)stringio_init, /*tp_init*/
Alexandre Vassalotti794652d2008-06-11 22:58:36 +00001018 0, /*tp_alloc*/
1019 stringio_new, /*tp_new*/
1020};