blob: 3ec8be62e1c7908436f62c32ba24d4e5750bc94f [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Text I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou24f36292009-03-28 22:16:42 +00003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper.
Antoine Pitrou24f36292009-03-28 22:16:42 +00005
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00006 Written by Amaury Forgeot d'Arc and Antoine Pitrou
7*/
8
9#define PY_SSIZE_T_CLEAN
10#include "Python.h"
11#include "structmember.h"
12#include "_iomodule.h"
13
14/* TextIOBase */
15
16PyDoc_STRVAR(TextIOBase_doc,
17 "Base class for text I/O.\n"
18 "\n"
19 "This class provides a character and line based interface to stream\n"
20 "I/O. There is no readinto method because Python's character strings\n"
21 "are immutable. There is no public constructor.\n"
22 );
23
24static PyObject *
25_unsupported(const char *message)
26{
27 PyErr_SetString(IO_STATE->unsupported_operation, message);
28 return NULL;
29}
30
Benjamin Petersond2e0c792009-05-01 20:40:59 +000031PyDoc_STRVAR(TextIOBase_detach_doc,
32 "Separate the underlying buffer from the TextIOBase and return it.\n"
33 "\n"
34 "After the underlying buffer has been detached, the TextIO is in an\n"
35 "unusable state.\n"
36 );
37
38static PyObject *
39TextIOBase_detach(PyObject *self)
40{
41 return _unsupported("detach");
42}
43
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000044PyDoc_STRVAR(TextIOBase_read_doc,
45 "Read at most n characters from stream.\n"
46 "\n"
47 "Read from underlying buffer until we have n characters or we hit EOF.\n"
48 "If n is negative or omitted, read until EOF.\n"
49 );
50
51static PyObject *
52TextIOBase_read(PyObject *self, PyObject *args)
53{
54 return _unsupported("read");
55}
56
57PyDoc_STRVAR(TextIOBase_readline_doc,
58 "Read until newline or EOF.\n"
59 "\n"
60 "Returns an empty string if EOF is hit immediately.\n"
61 );
62
63static PyObject *
64TextIOBase_readline(PyObject *self, PyObject *args)
65{
66 return _unsupported("readline");
67}
68
69PyDoc_STRVAR(TextIOBase_write_doc,
70 "Write string to stream.\n"
71 "Returns the number of characters written (which is always equal to\n"
72 "the length of the string).\n"
73 );
74
75static PyObject *
76TextIOBase_write(PyObject *self, PyObject *args)
77{
78 return _unsupported("write");
79}
80
81PyDoc_STRVAR(TextIOBase_encoding_doc,
82 "Encoding of the text stream.\n"
83 "\n"
84 "Subclasses should override.\n"
85 );
86
87static PyObject *
88TextIOBase_encoding_get(PyObject *self, void *context)
89{
90 Py_RETURN_NONE;
91}
92
93PyDoc_STRVAR(TextIOBase_newlines_doc,
94 "Line endings translated so far.\n"
95 "\n"
96 "Only line endings translated during reading are considered.\n"
97 "\n"
98 "Subclasses should override.\n"
99 );
100
101static PyObject *
102TextIOBase_newlines_get(PyObject *self, void *context)
103{
104 Py_RETURN_NONE;
105}
106
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000107PyDoc_STRVAR(TextIOBase_errors_doc,
108 "The error setting of the decoder or encoder.\n"
109 "\n"
110 "Subclasses should override.\n"
111 );
112
113static PyObject *
114TextIOBase_errors_get(PyObject *self, void *context)
115{
116 Py_RETURN_NONE;
117}
118
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000119
120static PyMethodDef TextIOBase_methods[] = {
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000121 {"detach", (PyCFunction)TextIOBase_detach, METH_NOARGS, TextIOBase_detach_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000122 {"read", TextIOBase_read, METH_VARARGS, TextIOBase_read_doc},
123 {"readline", TextIOBase_readline, METH_VARARGS, TextIOBase_readline_doc},
124 {"write", TextIOBase_write, METH_VARARGS, TextIOBase_write_doc},
125 {NULL, NULL}
126};
127
128static PyGetSetDef TextIOBase_getset[] = {
129 {"encoding", (getter)TextIOBase_encoding_get, NULL, TextIOBase_encoding_doc},
130 {"newlines", (getter)TextIOBase_newlines_get, NULL, TextIOBase_newlines_doc},
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000131 {"errors", (getter)TextIOBase_errors_get, NULL, TextIOBase_errors_doc},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000132 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133};
134
135PyTypeObject PyTextIOBase_Type = {
136 PyVarObject_HEAD_INIT(NULL, 0)
137 "_io._TextIOBase", /*tp_name*/
138 0, /*tp_basicsize*/
139 0, /*tp_itemsize*/
140 0, /*tp_dealloc*/
141 0, /*tp_print*/
142 0, /*tp_getattr*/
143 0, /*tp_setattr*/
144 0, /*tp_compare */
145 0, /*tp_repr*/
146 0, /*tp_as_number*/
147 0, /*tp_as_sequence*/
148 0, /*tp_as_mapping*/
149 0, /*tp_hash */
150 0, /*tp_call*/
151 0, /*tp_str*/
152 0, /*tp_getattro*/
153 0, /*tp_setattro*/
154 0, /*tp_as_buffer*/
155 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
156 TextIOBase_doc, /* tp_doc */
157 0, /* tp_traverse */
158 0, /* tp_clear */
159 0, /* tp_richcompare */
160 0, /* tp_weaklistoffset */
161 0, /* tp_iter */
162 0, /* tp_iternext */
163 TextIOBase_methods, /* tp_methods */
164 0, /* tp_members */
165 TextIOBase_getset, /* tp_getset */
166 &PyIOBase_Type, /* tp_base */
167 0, /* tp_dict */
168 0, /* tp_descr_get */
169 0, /* tp_descr_set */
170 0, /* tp_dictoffset */
171 0, /* tp_init */
172 0, /* tp_alloc */
173 0, /* tp_new */
174};
175
176
177/* IncrementalNewlineDecoder */
178
179PyDoc_STRVAR(IncrementalNewlineDecoder_doc,
180 "Codec used when reading a file in universal newlines mode. It wraps\n"
181 "another incremental decoder, translating \\r\\n and \\r into \\n. It also\n"
182 "records the types of newlines encountered. When used with\n"
183 "translate=False, it ensures that the newline sequence is returned in\n"
184 "one piece. When used with decoder=None, it expects unicode strings as\n"
185 "decode input and translates newlines without first invoking an external\n"
186 "decoder.\n"
187 );
188
189typedef struct {
190 PyObject_HEAD
191 PyObject *decoder;
192 PyObject *errors;
193 int pendingcr:1;
194 int translate:1;
195 unsigned int seennl:3;
196} PyNewLineDecoderObject;
197
198static int
Antoine Pitrou24f36292009-03-28 22:16:42 +0000199IncrementalNewlineDecoder_init(PyNewLineDecoderObject *self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000200 PyObject *args, PyObject *kwds)
201{
202 PyObject *decoder;
203 int translate;
204 PyObject *errors = NULL;
205 char *kwlist[] = {"decoder", "translate", "errors", NULL};
206
207 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|O:IncrementalNewlineDecoder",
208 kwlist, &decoder, &translate, &errors))
209 return -1;
210
211 self->decoder = decoder;
212 Py_INCREF(decoder);
213
214 if (errors == NULL) {
215 self->errors = PyUnicode_FromString("strict");
216 if (self->errors == NULL)
217 return -1;
218 }
219 else {
220 Py_INCREF(errors);
221 self->errors = errors;
222 }
223
224 self->translate = translate;
225 self->seennl = 0;
226 self->pendingcr = 0;
227
228 return 0;
229}
230
231static void
232IncrementalNewlineDecoder_dealloc(PyNewLineDecoderObject *self)
233{
234 Py_CLEAR(self->decoder);
235 Py_CLEAR(self->errors);
236 Py_TYPE(self)->tp_free((PyObject *)self);
237}
238
239#define SEEN_CR 1
240#define SEEN_LF 2
241#define SEEN_CRLF 4
242#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF)
243
244PyObject *
Antoine Pitrou24f36292009-03-28 22:16:42 +0000245_PyIncrementalNewlineDecoder_decode(PyObject *_self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000246 PyObject *input, int final)
247{
248 PyObject *output;
249 Py_ssize_t output_len;
250 PyNewLineDecoderObject *self = (PyNewLineDecoderObject *) _self;
251
252 if (self->decoder == NULL) {
253 PyErr_SetString(PyExc_ValueError,
254 "IncrementalNewlineDecoder.__init__ not called");
255 return NULL;
256 }
257
258 /* decode input (with the eventual \r from a previous pass) */
259 if (self->decoder != Py_None) {
260 output = PyObject_CallMethodObjArgs(self->decoder,
261 _PyIO_str_decode, input, final ? Py_True : Py_False, NULL);
262 }
263 else {
264 output = input;
265 Py_INCREF(output);
266 }
267
268 if (output == NULL)
269 return NULL;
270
271 if (!PyUnicode_Check(output)) {
272 PyErr_SetString(PyExc_TypeError,
273 "decoder should return a string result");
274 goto error;
275 }
276
277 output_len = PyUnicode_GET_SIZE(output);
278 if (self->pendingcr && (final || output_len > 0)) {
279 Py_UNICODE *out;
280 PyObject *modified = PyUnicode_FromUnicode(NULL, output_len + 1);
281 if (modified == NULL)
282 goto error;
283 out = PyUnicode_AS_UNICODE(modified);
284 out[0] = '\r';
285 memcpy(out + 1, PyUnicode_AS_UNICODE(output),
286 output_len * sizeof(Py_UNICODE));
287 Py_DECREF(output);
288 output = modified;
289 self->pendingcr = 0;
290 output_len++;
291 }
292
293 /* retain last \r even when not translating data:
294 * then readline() is sure to get \r\n in one pass
295 */
296 if (!final) {
Antoine Pitrou24f36292009-03-28 22:16:42 +0000297 if (output_len > 0
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000298 && PyUnicode_AS_UNICODE(output)[output_len - 1] == '\r') {
299
300 if (Py_REFCNT(output) == 1) {
301 if (PyUnicode_Resize(&output, output_len - 1) < 0)
302 goto error;
303 }
304 else {
305 PyObject *modified = PyUnicode_FromUnicode(
306 PyUnicode_AS_UNICODE(output),
307 output_len - 1);
308 if (modified == NULL)
309 goto error;
310 Py_DECREF(output);
311 output = modified;
312 }
313 self->pendingcr = 1;
314 }
315 }
316
317 /* Record which newlines are read and do newline translation if desired,
318 all in one pass. */
319 {
320 Py_UNICODE *in_str;
321 Py_ssize_t len;
322 int seennl = self->seennl;
323 int only_lf = 0;
324
325 in_str = PyUnicode_AS_UNICODE(output);
326 len = PyUnicode_GET_SIZE(output);
327
328 if (len == 0)
329 return output;
330
331 /* If, up to now, newlines are consistently \n, do a quick check
332 for the \r *byte* with the libc's optimized memchr.
333 */
334 if (seennl == SEEN_LF || seennl == 0) {
Antoine Pitrou0e941892009-03-06 23:57:20 +0000335 only_lf = (memchr(in_str, '\r', len * sizeof(Py_UNICODE)) == NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000336 }
337
Antoine Pitrou66913e22009-03-06 23:40:56 +0000338 if (only_lf) {
339 /* If not already seen, quick scan for a possible "\n" character.
340 (there's nothing else to be done, even when in translation mode)
341 */
342 if (seennl == 0 &&
343 memchr(in_str, '\n', len * sizeof(Py_UNICODE)) != NULL) {
344 Py_UNICODE *s, *end;
345 s = in_str;
346 end = in_str + len;
347 for (;;) {
348 Py_UNICODE c;
349 /* Fast loop for non-control characters */
350 while (*s > '\n')
351 s++;
352 c = *s++;
353 if (c == '\n') {
354 seennl |= SEEN_LF;
355 break;
356 }
357 if (s > end)
358 break;
359 }
360 }
361 /* Finished: we have scanned for newlines, and none of them
362 need translating */
363 }
364 else if (!self->translate) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000365 Py_UNICODE *s, *end;
Antoine Pitrou66913e22009-03-06 23:40:56 +0000366 /* We have already seen all newline types, no need to scan again */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000367 if (seennl == SEEN_ALL)
368 goto endscan;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000369 s = in_str;
370 end = in_str + len;
371 for (;;) {
372 Py_UNICODE c;
373 /* Fast loop for non-control characters */
374 while (*s > '\r')
375 s++;
376 c = *s++;
377 if (c == '\n')
378 seennl |= SEEN_LF;
379 else if (c == '\r') {
380 if (*s == '\n') {
381 seennl |= SEEN_CRLF;
382 s++;
383 }
384 else
385 seennl |= SEEN_CR;
386 }
387 if (s > end)
388 break;
389 if (seennl == SEEN_ALL)
390 break;
391 }
392 endscan:
393 ;
394 }
Antoine Pitrou66913e22009-03-06 23:40:56 +0000395 else {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000396 PyObject *translated = NULL;
397 Py_UNICODE *out_str;
398 Py_UNICODE *in, *out, *end;
399 if (Py_REFCNT(output) != 1) {
400 /* We could try to optimize this so that we only do a copy
401 when there is something to translate. On the other hand,
402 most decoders should only output non-shared strings, i.e.
403 translation is done in place. */
404 translated = PyUnicode_FromUnicode(NULL, len);
405 if (translated == NULL)
406 goto error;
407 assert(Py_REFCNT(translated) == 1);
408 memcpy(PyUnicode_AS_UNICODE(translated),
409 PyUnicode_AS_UNICODE(output),
410 len * sizeof(Py_UNICODE));
411 }
412 else {
413 translated = output;
414 }
415 out_str = PyUnicode_AS_UNICODE(translated);
416 in = in_str;
417 out = out_str;
418 end = in_str + len;
419 for (;;) {
420 Py_UNICODE c;
421 /* Fast loop for non-control characters */
422 while ((c = *in++) > '\r')
423 *out++ = c;
424 if (c == '\n') {
425 *out++ = c;
426 seennl |= SEEN_LF;
427 continue;
428 }
429 if (c == '\r') {
430 if (*in == '\n') {
431 in++;
432 seennl |= SEEN_CRLF;
433 }
434 else
435 seennl |= SEEN_CR;
436 *out++ = '\n';
437 continue;
438 }
439 if (in > end)
440 break;
441 *out++ = c;
442 }
443 if (translated != output) {
444 Py_DECREF(output);
445 output = translated;
446 }
447 if (out - out_str != len) {
448 if (PyUnicode_Resize(&output, out - out_str) < 0)
449 goto error;
450 }
451 }
452 self->seennl |= seennl;
453 }
454
455 return output;
456
457 error:
458 Py_DECREF(output);
459 return NULL;
460}
461
462static PyObject *
Antoine Pitrou24f36292009-03-28 22:16:42 +0000463IncrementalNewlineDecoder_decode(PyNewLineDecoderObject *self,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464 PyObject *args, PyObject *kwds)
465{
466 char *kwlist[] = {"input", "final", NULL};
467 PyObject *input;
468 int final = 0;
469
470 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder",
471 kwlist, &input, &final))
472 return NULL;
473 return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final);
474}
475
476static PyObject *
477IncrementalNewlineDecoder_getstate(PyNewLineDecoderObject *self, PyObject *args)
478{
479 PyObject *buffer;
480 unsigned PY_LONG_LONG flag;
481
482 if (self->decoder != Py_None) {
483 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
484 _PyIO_str_getstate, NULL);
485 if (state == NULL)
486 return NULL;
487 if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) {
488 Py_DECREF(state);
489 return NULL;
490 }
491 Py_INCREF(buffer);
492 Py_DECREF(state);
493 }
494 else {
495 buffer = PyBytes_FromString("");
496 flag = 0;
497 }
498 flag <<= 1;
499 if (self->pendingcr)
500 flag |= 1;
501 return Py_BuildValue("NK", buffer, flag);
502}
503
504static PyObject *
505IncrementalNewlineDecoder_setstate(PyNewLineDecoderObject *self, PyObject *state)
506{
507 PyObject *buffer;
508 unsigned PY_LONG_LONG flag;
509
510 if (!PyArg_Parse(state, "(OK)", &buffer, &flag))
511 return NULL;
512
513 self->pendingcr = (int) flag & 1;
514 flag >>= 1;
515
516 if (self->decoder != Py_None)
517 return PyObject_CallMethod(self->decoder,
518 "setstate", "((OK))", buffer, flag);
519 else
520 Py_RETURN_NONE;
521}
522
523static PyObject *
524IncrementalNewlineDecoder_reset(PyNewLineDecoderObject *self, PyObject *args)
525{
526 self->seennl = 0;
527 self->pendingcr = 0;
528 if (self->decoder != Py_None)
529 return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
530 else
531 Py_RETURN_NONE;
532}
533
534static PyObject *
535IncrementalNewlineDecoder_newlines_get(PyNewLineDecoderObject *self, void *context)
536{
537 switch (self->seennl) {
538 case SEEN_CR:
539 return PyUnicode_FromString("\r");
540 case SEEN_LF:
541 return PyUnicode_FromString("\n");
542 case SEEN_CRLF:
543 return PyUnicode_FromString("\r\n");
544 case SEEN_CR | SEEN_LF:
545 return Py_BuildValue("ss", "\r", "\n");
546 case SEEN_CR | SEEN_CRLF:
547 return Py_BuildValue("ss", "\r", "\r\n");
548 case SEEN_LF | SEEN_CRLF:
549 return Py_BuildValue("ss", "\n", "\r\n");
550 case SEEN_CR | SEEN_LF | SEEN_CRLF:
551 return Py_BuildValue("sss", "\r", "\n", "\r\n");
552 default:
553 Py_RETURN_NONE;
554 }
555
556}
557
558
559static PyMethodDef IncrementalNewlineDecoder_methods[] = {
560 {"decode", (PyCFunction)IncrementalNewlineDecoder_decode, METH_VARARGS|METH_KEYWORDS},
561 {"getstate", (PyCFunction)IncrementalNewlineDecoder_getstate, METH_NOARGS},
562 {"setstate", (PyCFunction)IncrementalNewlineDecoder_setstate, METH_O},
563 {"reset", (PyCFunction)IncrementalNewlineDecoder_reset, METH_NOARGS},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000564 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565};
566
567static PyGetSetDef IncrementalNewlineDecoder_getset[] = {
568 {"newlines", (getter)IncrementalNewlineDecoder_newlines_get, NULL, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000569 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000570};
571
572PyTypeObject PyIncrementalNewlineDecoder_Type = {
573 PyVarObject_HEAD_INIT(NULL, 0)
574 "_io.IncrementalNewlineDecoder", /*tp_name*/
575 sizeof(PyNewLineDecoderObject), /*tp_basicsize*/
576 0, /*tp_itemsize*/
577 (destructor)IncrementalNewlineDecoder_dealloc, /*tp_dealloc*/
578 0, /*tp_print*/
579 0, /*tp_getattr*/
580 0, /*tp_setattr*/
581 0, /*tp_compare */
582 0, /*tp_repr*/
583 0, /*tp_as_number*/
584 0, /*tp_as_sequence*/
585 0, /*tp_as_mapping*/
586 0, /*tp_hash */
587 0, /*tp_call*/
588 0, /*tp_str*/
589 0, /*tp_getattro*/
590 0, /*tp_setattro*/
591 0, /*tp_as_buffer*/
592 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
593 IncrementalNewlineDecoder_doc, /* tp_doc */
594 0, /* tp_traverse */
595 0, /* tp_clear */
596 0, /* tp_richcompare */
597 0, /*tp_weaklistoffset*/
598 0, /* tp_iter */
599 0, /* tp_iternext */
600 IncrementalNewlineDecoder_methods, /* tp_methods */
601 0, /* tp_members */
602 IncrementalNewlineDecoder_getset, /* tp_getset */
603 0, /* tp_base */
604 0, /* tp_dict */
605 0, /* tp_descr_get */
606 0, /* tp_descr_set */
607 0, /* tp_dictoffset */
608 (initproc)IncrementalNewlineDecoder_init, /* tp_init */
609 0, /* tp_alloc */
610 PyType_GenericNew, /* tp_new */
611};
612
613
614/* TextIOWrapper */
615
616PyDoc_STRVAR(TextIOWrapper_doc,
617 "Character and line based layer over a BufferedIOBase object, buffer.\n"
618 "\n"
619 "encoding gives the name of the encoding that the stream will be\n"
620 "decoded or encoded with. It defaults to locale.getpreferredencoding.\n"
621 "\n"
622 "errors determines the strictness of encoding and decoding (see the\n"
623 "codecs.register) and defaults to \"strict\".\n"
624 "\n"
625 "newline can be None, '', '\\n', '\\r', or '\\r\\n'. It controls the\n"
626 "handling of line endings. If it is None, universal newlines is\n"
627 "enabled. With this enabled, on input, the lines endings '\\n', '\\r',\n"
628 "or '\\r\\n' are translated to '\\n' before being returned to the\n"
629 "caller. Conversely, on output, '\\n' is translated to the system\n"
630 "default line seperator, os.linesep. If newline is any other of its\n"
631 "legal values, that newline becomes the newline when the file is read\n"
632 "and it is returned untranslated. On output, '\\n' is converted to the\n"
633 "newline.\n"
634 "\n"
635 "If line_buffering is True, a call to flush is implied when a call to\n"
636 "write contains a newline character."
637 );
638
639typedef PyObject *
640 (*encodefunc_t)(PyObject *, PyObject *);
641
642typedef struct
643{
644 PyObject_HEAD
645 int ok; /* initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000646 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000647 Py_ssize_t chunk_size;
648 PyObject *buffer;
649 PyObject *encoding;
650 PyObject *encoder;
651 PyObject *decoder;
652 PyObject *readnl;
653 PyObject *errors;
654 const char *writenl; /* utf-8 encoded, NULL stands for \n */
655 char line_buffering;
656 char readuniversal;
657 char readtranslate;
658 char writetranslate;
659 char seekable;
660 char telling;
661 /* Specialized encoding func (see below) */
662 encodefunc_t encodefunc;
Antoine Pitroue4501852009-05-14 18:55:55 +0000663 /* Whether or not it's the start of the stream */
664 char encoding_start_of_stream;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665
666 /* Reads and writes are internally buffered in order to speed things up.
667 However, any read will first flush the write buffer if itsn't empty.
Antoine Pitrou24f36292009-03-28 22:16:42 +0000668
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669 Please also note that text to be written is first encoded before being
670 buffered. This is necessary so that encoding errors are immediately
671 reported to the caller, but it unfortunately means that the
672 IncrementalEncoder (whose encode() method is always written in Python)
673 becomes a bottleneck for small writes.
674 */
675 PyObject *decoded_chars; /* buffer for text returned from decoder */
676 Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */
677 PyObject *pending_bytes; /* list of bytes objects waiting to be
678 written, or NULL */
679 Py_ssize_t pending_bytes_count;
680 PyObject *snapshot;
681 /* snapshot is either None, or a tuple (dec_flags, next_input) where
682 * dec_flags is the second (integer) item of the decoder state and
683 * next_input is the chunk of input bytes that comes next after the
684 * snapshot point. We use this to reconstruct decoder states in tell().
685 */
686
687 /* Cache raw object if it's a FileIO object */
688 PyObject *raw;
689
690 PyObject *weakreflist;
691 PyObject *dict;
692} PyTextIOWrapperObject;
693
694
695/* A couple of specialized cases in order to bypass the slow incremental
696 encoding methods for the most popular encodings. */
697
698static PyObject *
699ascii_encode(PyTextIOWrapperObject *self, PyObject *text)
700{
701 return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(text),
702 PyUnicode_GET_SIZE(text),
703 PyBytes_AS_STRING(self->errors));
704}
705
706static PyObject *
707utf16be_encode(PyTextIOWrapperObject *self, PyObject *text)
708{
709 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
710 PyUnicode_GET_SIZE(text),
711 PyBytes_AS_STRING(self->errors), 1);
712}
713
714static PyObject *
715utf16le_encode(PyTextIOWrapperObject *self, PyObject *text)
716{
717 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
718 PyUnicode_GET_SIZE(text),
719 PyBytes_AS_STRING(self->errors), -1);
720}
721
722static PyObject *
723utf16_encode(PyTextIOWrapperObject *self, PyObject *text)
724{
Antoine Pitroue4501852009-05-14 18:55:55 +0000725 if (!self->encoding_start_of_stream) {
726 /* Skip the BOM and use native byte ordering */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000727#if defined(WORDS_BIGENDIAN)
Antoine Pitroue4501852009-05-14 18:55:55 +0000728 return utf16be_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000729#else
Antoine Pitroue4501852009-05-14 18:55:55 +0000730 return utf16le_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731#endif
Antoine Pitroue4501852009-05-14 18:55:55 +0000732 }
733 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
734 PyUnicode_GET_SIZE(text),
735 PyBytes_AS_STRING(self->errors), 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000736}
737
Antoine Pitroue4501852009-05-14 18:55:55 +0000738static PyObject *
739utf32be_encode(PyTextIOWrapperObject *self, PyObject *text)
740{
741 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
742 PyUnicode_GET_SIZE(text),
743 PyBytes_AS_STRING(self->errors), 1);
744}
745
746static PyObject *
747utf32le_encode(PyTextIOWrapperObject *self, PyObject *text)
748{
749 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
750 PyUnicode_GET_SIZE(text),
751 PyBytes_AS_STRING(self->errors), -1);
752}
753
754static PyObject *
755utf32_encode(PyTextIOWrapperObject *self, PyObject *text)
756{
757 if (!self->encoding_start_of_stream) {
758 /* Skip the BOM and use native byte ordering */
759#if defined(WORDS_BIGENDIAN)
760 return utf32be_encode(self, text);
761#else
762 return utf32le_encode(self, text);
763#endif
764 }
765 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
766 PyUnicode_GET_SIZE(text),
767 PyBytes_AS_STRING(self->errors), 0);
768}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000769
770static PyObject *
771utf8_encode(PyTextIOWrapperObject *self, PyObject *text)
772{
773 return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(text),
774 PyUnicode_GET_SIZE(text),
775 PyBytes_AS_STRING(self->errors));
776}
777
778static PyObject *
779latin1_encode(PyTextIOWrapperObject *self, PyObject *text)
780{
781 return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(text),
782 PyUnicode_GET_SIZE(text),
783 PyBytes_AS_STRING(self->errors));
784}
785
786/* Map normalized encoding names onto the specialized encoding funcs */
787
788typedef struct {
789 const char *name;
790 encodefunc_t encodefunc;
791} encodefuncentry;
792
Antoine Pitrou24f36292009-03-28 22:16:42 +0000793static encodefuncentry encodefuncs[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000794 {"ascii", (encodefunc_t) ascii_encode},
795 {"iso8859-1", (encodefunc_t) latin1_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000796 {"utf-8", (encodefunc_t) utf8_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000797 {"utf-16-be", (encodefunc_t) utf16be_encode},
798 {"utf-16-le", (encodefunc_t) utf16le_encode},
799 {"utf-16", (encodefunc_t) utf16_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000800 {"utf-32-be", (encodefunc_t) utf32be_encode},
801 {"utf-32-le", (encodefunc_t) utf32le_encode},
802 {"utf-32", (encodefunc_t) utf32_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000803 {NULL, NULL}
804};
805
806
807static int
808TextIOWrapper_init(PyTextIOWrapperObject *self, PyObject *args, PyObject *kwds)
809{
810 char *kwlist[] = {"buffer", "encoding", "errors",
811 "newline", "line_buffering",
812 NULL};
813 PyObject *buffer, *raw;
814 char *encoding = NULL;
815 char *errors = NULL;
816 char *newline = NULL;
817 int line_buffering = 0;
818 _PyIO_State *state = IO_STATE;
819
820 PyObject *res;
821 int r;
822
823 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000824 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000825 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio",
826 kwlist, &buffer, &encoding, &errors,
827 &newline, &line_buffering))
828 return -1;
829
830 if (newline && newline[0] != '\0'
831 && !(newline[0] == '\n' && newline[1] == '\0')
832 && !(newline[0] == '\r' && newline[1] == '\0')
833 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
834 PyErr_Format(PyExc_ValueError,
835 "illegal newline value: %s", newline);
836 return -1;
837 }
838
839 Py_CLEAR(self->buffer);
840 Py_CLEAR(self->encoding);
841 Py_CLEAR(self->encoder);
842 Py_CLEAR(self->decoder);
843 Py_CLEAR(self->readnl);
844 Py_CLEAR(self->decoded_chars);
845 Py_CLEAR(self->pending_bytes);
846 Py_CLEAR(self->snapshot);
847 Py_CLEAR(self->errors);
848 Py_CLEAR(self->raw);
849 self->decoded_chars_used = 0;
850 self->pending_bytes_count = 0;
851 self->encodefunc = NULL;
852
853 if (encoding == NULL) {
854 /* Try os.device_encoding(fileno) */
855 PyObject *fileno;
856 fileno = PyObject_CallMethod(buffer, "fileno", NULL);
857 /* Ignore only AttributeError and UnsupportedOperation */
858 if (fileno == NULL) {
859 if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
860 PyErr_ExceptionMatches(state->unsupported_operation)) {
861 PyErr_Clear();
862 }
863 else {
864 goto error;
865 }
866 }
867 else {
868 self->encoding = PyObject_CallMethod(state->os_module,
869 "device_encoding",
870 "N", fileno);
871 if (self->encoding == NULL)
872 goto error;
873 else if (!PyUnicode_Check(self->encoding))
874 Py_CLEAR(self->encoding);
875 }
876 }
877 if (encoding == NULL && self->encoding == NULL) {
878 if (state->locale_module == NULL) {
879 state->locale_module = PyImport_ImportModule("locale");
880 if (state->locale_module == NULL)
881 goto catch_ImportError;
882 else
883 goto use_locale;
884 }
885 else {
886 use_locale:
887 self->encoding = PyObject_CallMethod(
888 state->locale_module, "getpreferredencoding", NULL);
889 if (self->encoding == NULL) {
890 catch_ImportError:
891 /*
892 Importing locale can raise a ImportError because of
893 _functools, and locale.getpreferredencoding can raise a
894 ImportError if _locale is not available. These will happen
895 during module building.
896 */
897 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
898 PyErr_Clear();
899 self->encoding = PyUnicode_FromString("ascii");
900 }
901 else
902 goto error;
903 }
904 else if (!PyUnicode_Check(self->encoding))
905 Py_CLEAR(self->encoding);
906 }
907 }
908 if (self->encoding != NULL)
909 encoding = _PyUnicode_AsString(self->encoding);
910 else if (encoding != NULL) {
911 self->encoding = PyUnicode_FromString(encoding);
912 if (self->encoding == NULL)
913 goto error;
914 }
915 else {
916 PyErr_SetString(PyExc_IOError,
917 "could not determine default encoding");
918 }
919
920 if (errors == NULL)
921 errors = "strict";
922 self->errors = PyBytes_FromString(errors);
923 if (self->errors == NULL)
924 goto error;
925
926 self->chunk_size = 8192;
927 self->readuniversal = (newline == NULL || newline[0] == '\0');
928 self->line_buffering = line_buffering;
929 self->readtranslate = (newline == NULL);
930 if (newline) {
931 self->readnl = PyUnicode_FromString(newline);
932 if (self->readnl == NULL)
933 return -1;
934 }
935 self->writetranslate = (newline == NULL || newline[0] != '\0');
936 if (!self->readuniversal && self->readnl) {
937 self->writenl = _PyUnicode_AsString(self->readnl);
938 if (!strcmp(self->writenl, "\n"))
939 self->writenl = NULL;
940 }
941#ifdef MS_WINDOWS
942 else
943 self->writenl = "\r\n";
944#endif
945
946 /* Build the decoder object */
947 res = PyObject_CallMethod(buffer, "readable", NULL);
948 if (res == NULL)
949 goto error;
950 r = PyObject_IsTrue(res);
951 Py_DECREF(res);
952 if (r == -1)
953 goto error;
954 if (r == 1) {
955 self->decoder = PyCodec_IncrementalDecoder(
956 encoding, errors);
957 if (self->decoder == NULL)
958 goto error;
959
960 if (self->readuniversal) {
961 PyObject *incrementalDecoder = PyObject_CallFunction(
962 (PyObject *)&PyIncrementalNewlineDecoder_Type,
963 "Oi", self->decoder, (int)self->readtranslate);
964 if (incrementalDecoder == NULL)
965 goto error;
966 Py_CLEAR(self->decoder);
967 self->decoder = incrementalDecoder;
968 }
969 }
970
971 /* Build the encoder object */
972 res = PyObject_CallMethod(buffer, "writable", NULL);
973 if (res == NULL)
974 goto error;
975 r = PyObject_IsTrue(res);
976 Py_DECREF(res);
977 if (r == -1)
978 goto error;
979 if (r == 1) {
980 PyObject *ci;
981 self->encoder = PyCodec_IncrementalEncoder(
982 encoding, errors);
983 if (self->encoder == NULL)
984 goto error;
985 /* Get the normalized named of the codec */
986 ci = _PyCodec_Lookup(encoding);
987 if (ci == NULL)
988 goto error;
989 res = PyObject_GetAttrString(ci, "name");
990 Py_DECREF(ci);
991 if (res == NULL)
992 PyErr_Clear();
993 else if (PyUnicode_Check(res)) {
994 encodefuncentry *e = encodefuncs;
995 while (e->name != NULL) {
996 if (!PyUnicode_CompareWithASCIIString(res, e->name)) {
997 self->encodefunc = e->encodefunc;
998 break;
999 }
1000 e++;
1001 }
1002 }
1003 Py_XDECREF(res);
1004 }
1005
1006 self->buffer = buffer;
1007 Py_INCREF(buffer);
Antoine Pitrou24f36292009-03-28 22:16:42 +00001008
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001009 if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
1010 Py_TYPE(buffer) == &PyBufferedWriter_Type ||
1011 Py_TYPE(buffer) == &PyBufferedRandom_Type) {
1012 raw = PyObject_GetAttrString(buffer, "raw");
1013 /* Cache the raw FileIO object to speed up 'closed' checks */
1014 if (raw == NULL)
1015 PyErr_Clear();
1016 else if (Py_TYPE(raw) == &PyFileIO_Type)
1017 self->raw = raw;
1018 else
1019 Py_DECREF(raw);
1020 }
1021
1022 res = PyObject_CallMethod(buffer, "seekable", NULL);
1023 if (res == NULL)
1024 goto error;
1025 self->seekable = self->telling = PyObject_IsTrue(res);
1026 Py_DECREF(res);
1027
Antoine Pitroue4501852009-05-14 18:55:55 +00001028 self->encoding_start_of_stream = 0;
1029 if (self->seekable && self->encoder) {
1030 PyObject *cookieObj;
1031 int cmp;
1032
1033 self->encoding_start_of_stream = 1;
1034
1035 cookieObj = PyObject_CallMethodObjArgs(buffer, _PyIO_str_tell, NULL);
1036 if (cookieObj == NULL)
1037 goto error;
1038
1039 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
1040 Py_DECREF(cookieObj);
1041 if (cmp < 0) {
1042 goto error;
1043 }
1044
1045 if (cmp == 0) {
1046 self->encoding_start_of_stream = 0;
1047 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
1048 _PyIO_zero, NULL);
1049 if (res == NULL)
1050 goto error;
1051 Py_DECREF(res);
1052 }
1053 }
1054
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001055 self->ok = 1;
1056 return 0;
1057
1058 error:
1059 return -1;
1060}
1061
1062static int
1063_TextIOWrapper_clear(PyTextIOWrapperObject *self)
1064{
1065 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
1066 return -1;
1067 self->ok = 0;
1068 Py_CLEAR(self->buffer);
1069 Py_CLEAR(self->encoding);
1070 Py_CLEAR(self->encoder);
1071 Py_CLEAR(self->decoder);
1072 Py_CLEAR(self->readnl);
1073 Py_CLEAR(self->decoded_chars);
1074 Py_CLEAR(self->pending_bytes);
1075 Py_CLEAR(self->snapshot);
1076 Py_CLEAR(self->errors);
1077 Py_CLEAR(self->raw);
1078 return 0;
1079}
1080
1081static void
1082TextIOWrapper_dealloc(PyTextIOWrapperObject *self)
1083{
1084 if (_TextIOWrapper_clear(self) < 0)
1085 return;
1086 _PyObject_GC_UNTRACK(self);
1087 if (self->weakreflist != NULL)
1088 PyObject_ClearWeakRefs((PyObject *)self);
1089 Py_CLEAR(self->dict);
1090 Py_TYPE(self)->tp_free((PyObject *)self);
1091}
1092
1093static int
1094TextIOWrapper_traverse(PyTextIOWrapperObject *self, visitproc visit, void *arg)
1095{
1096 Py_VISIT(self->buffer);
1097 Py_VISIT(self->encoding);
1098 Py_VISIT(self->encoder);
1099 Py_VISIT(self->decoder);
1100 Py_VISIT(self->readnl);
1101 Py_VISIT(self->decoded_chars);
1102 Py_VISIT(self->pending_bytes);
1103 Py_VISIT(self->snapshot);
1104 Py_VISIT(self->errors);
1105 Py_VISIT(self->raw);
1106
1107 Py_VISIT(self->dict);
1108 return 0;
1109}
1110
1111static int
1112TextIOWrapper_clear(PyTextIOWrapperObject *self)
1113{
1114 if (_TextIOWrapper_clear(self) < 0)
1115 return -1;
1116 Py_CLEAR(self->dict);
1117 return 0;
1118}
1119
1120static PyObject *
1121TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context);
1122
1123/* This macro takes some shortcuts to make the common case faster. */
1124#define CHECK_CLOSED(self) \
1125 do { \
1126 int r; \
1127 PyObject *_res; \
1128 if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \
1129 if (self->raw != NULL) \
1130 r = _PyFileIO_closed(self->raw); \
1131 else { \
1132 _res = TextIOWrapper_closed_get(self, NULL); \
1133 if (_res == NULL) \
1134 return NULL; \
1135 r = PyObject_IsTrue(_res); \
1136 Py_DECREF(_res); \
1137 if (r < 0) \
1138 return NULL; \
1139 } \
1140 if (r > 0) { \
1141 PyErr_SetString(PyExc_ValueError, \
1142 "I/O operation on closed file."); \
1143 return NULL; \
1144 } \
1145 } \
1146 else if (_PyIOBase_checkClosed((PyObject *)self, Py_True) == NULL) \
1147 return NULL; \
1148 } while (0)
1149
1150#define CHECK_INITIALIZED(self) \
1151 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001152 if (self->detached) { \
1153 PyErr_SetString(PyExc_ValueError, \
1154 "underlying buffer has been detached"); \
1155 } else { \
1156 PyErr_SetString(PyExc_ValueError, \
1157 "I/O operation on uninitialized object"); \
1158 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001159 return NULL; \
1160 }
1161
1162#define CHECK_INITIALIZED_INT(self) \
1163 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001164 if (self->detached) { \
1165 PyErr_SetString(PyExc_ValueError, \
1166 "underlying buffer has been detached"); \
1167 } else { \
1168 PyErr_SetString(PyExc_ValueError, \
1169 "I/O operation on uninitialized object"); \
1170 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001171 return -1; \
1172 }
1173
1174
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001175static PyObject *
1176TextIOWrapper_detach(PyTextIOWrapperObject *self)
1177{
1178 PyObject *buffer, *res;
1179 CHECK_INITIALIZED(self);
1180 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
1181 if (res == NULL)
1182 return NULL;
1183 Py_DECREF(res);
1184 buffer = self->buffer;
1185 self->buffer = NULL;
1186 self->detached = 1;
1187 self->ok = 0;
1188 return buffer;
1189}
1190
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001191Py_LOCAL_INLINE(const Py_UNICODE *)
1192findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch)
1193{
1194 /* like wcschr, but doesn't stop at NULL characters */
1195 while (size-- > 0) {
1196 if (*s == ch)
1197 return s;
1198 s++;
1199 }
1200 return NULL;
1201}
1202
Antoine Pitrou24f36292009-03-28 22:16:42 +00001203/* Flush the internal write buffer. This doesn't explicitly flush the
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001204 underlying buffered object, though. */
1205static int
1206_TextIOWrapper_writeflush(PyTextIOWrapperObject *self)
1207{
1208 PyObject *b, *ret;
1209
1210 if (self->pending_bytes == NULL)
1211 return 0;
1212 b = _PyBytes_Join(_PyIO_empty_bytes, self->pending_bytes);
1213 if (b == NULL)
1214 return -1;
1215 ret = PyObject_CallMethodObjArgs(self->buffer,
1216 _PyIO_str_write, b, NULL);
1217 Py_DECREF(b);
1218 if (ret == NULL)
1219 return -1;
1220 Py_DECREF(ret);
1221 Py_CLEAR(self->pending_bytes);
1222 self->pending_bytes_count = 0;
1223 return 0;
1224}
1225
1226static PyObject *
1227TextIOWrapper_write(PyTextIOWrapperObject *self, PyObject *args)
1228{
1229 PyObject *ret;
1230 PyObject *text; /* owned reference */
1231 PyObject *b;
1232 Py_ssize_t textlen;
1233 int haslf = 0;
1234 int needflush = 0;
1235
1236 CHECK_INITIALIZED(self);
1237
1238 if (!PyArg_ParseTuple(args, "U:write", &text)) {
1239 return NULL;
1240 }
1241
1242 CHECK_CLOSED(self);
1243
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001244 if (self->encoder == NULL) {
1245 PyErr_SetString(PyExc_IOError, "not writable");
1246 return NULL;
1247 }
1248
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249 Py_INCREF(text);
1250
1251 textlen = PyUnicode_GetSize(text);
1252
1253 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
1254 if (findchar(PyUnicode_AS_UNICODE(text),
1255 PyUnicode_GET_SIZE(text), '\n'))
1256 haslf = 1;
1257
1258 if (haslf && self->writetranslate && self->writenl != NULL) {
1259 PyObject *newtext = PyObject_CallMethod(
1260 text, "replace", "ss", "\n", self->writenl);
1261 Py_DECREF(text);
1262 if (newtext == NULL)
1263 return NULL;
1264 text = newtext;
1265 }
1266
1267 if (self->line_buffering &&
1268 (haslf ||
1269 findchar(PyUnicode_AS_UNICODE(text),
1270 PyUnicode_GET_SIZE(text), '\r')))
1271 needflush = 1;
1272
1273 /* XXX What if we were just reading? */
Antoine Pitroue4501852009-05-14 18:55:55 +00001274 if (self->encodefunc != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275 b = (*self->encodefunc)((PyObject *) self, text);
Antoine Pitroue4501852009-05-14 18:55:55 +00001276 self->encoding_start_of_stream = 0;
1277 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001278 else
1279 b = PyObject_CallMethodObjArgs(self->encoder,
1280 _PyIO_str_encode, text, NULL);
1281 Py_DECREF(text);
1282 if (b == NULL)
1283 return NULL;
1284
1285 if (self->pending_bytes == NULL) {
1286 self->pending_bytes = PyList_New(0);
1287 if (self->pending_bytes == NULL) {
1288 Py_DECREF(b);
1289 return NULL;
1290 }
1291 self->pending_bytes_count = 0;
1292 }
1293 if (PyList_Append(self->pending_bytes, b) < 0) {
1294 Py_DECREF(b);
1295 return NULL;
1296 }
1297 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1298 Py_DECREF(b);
1299 if (self->pending_bytes_count > self->chunk_size || needflush) {
1300 if (_TextIOWrapper_writeflush(self) < 0)
1301 return NULL;
1302 }
Antoine Pitrou24f36292009-03-28 22:16:42 +00001303
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001304 if (needflush) {
1305 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1306 if (ret == NULL)
1307 return NULL;
1308 Py_DECREF(ret);
1309 }
1310
1311 Py_CLEAR(self->snapshot);
1312
1313 if (self->decoder) {
1314 ret = PyObject_CallMethod(self->decoder, "reset", NULL);
1315 if (ret == NULL)
1316 return NULL;
1317 Py_DECREF(ret);
1318 }
1319
1320 return PyLong_FromSsize_t(textlen);
1321}
1322
1323/* Steal a reference to chars and store it in the decoded_char buffer;
1324 */
1325static void
1326TextIOWrapper_set_decoded_chars(PyTextIOWrapperObject *self, PyObject *chars)
1327{
1328 Py_CLEAR(self->decoded_chars);
1329 self->decoded_chars = chars;
1330 self->decoded_chars_used = 0;
1331}
1332
1333static PyObject *
1334TextIOWrapper_get_decoded_chars(PyTextIOWrapperObject *self, Py_ssize_t n)
1335{
1336 PyObject *chars;
1337 Py_ssize_t avail;
1338
1339 if (self->decoded_chars == NULL)
1340 return PyUnicode_FromStringAndSize(NULL, 0);
1341
1342 avail = (PyUnicode_GET_SIZE(self->decoded_chars)
1343 - self->decoded_chars_used);
1344
1345 assert(avail >= 0);
1346
1347 if (n < 0 || n > avail)
1348 n = avail;
1349
1350 if (self->decoded_chars_used > 0 || n < avail) {
1351 chars = PyUnicode_FromUnicode(
1352 PyUnicode_AS_UNICODE(self->decoded_chars)
1353 + self->decoded_chars_used, n);
1354 if (chars == NULL)
1355 return NULL;
1356 }
1357 else {
1358 chars = self->decoded_chars;
1359 Py_INCREF(chars);
1360 }
1361
1362 self->decoded_chars_used += n;
1363 return chars;
1364}
1365
1366/* Read and decode the next chunk of data from the BufferedReader.
1367 */
1368static int
1369TextIOWrapper_read_chunk(PyTextIOWrapperObject *self)
1370{
1371 PyObject *dec_buffer = NULL;
1372 PyObject *dec_flags = NULL;
1373 PyObject *input_chunk = NULL;
1374 PyObject *decoded_chars, *chunk_size;
1375 int eof;
1376
1377 /* The return value is True unless EOF was reached. The decoded string is
1378 * placed in self._decoded_chars (replacing its previous value). The
1379 * entire input chunk is sent to the decoder, though some of it may remain
1380 * buffered in the decoder, yet to be converted.
1381 */
1382
1383 if (self->decoder == NULL) {
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001384 PyErr_SetString(PyExc_IOError, "not readable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001385 return -1;
1386 }
1387
1388 if (self->telling) {
1389 /* To prepare for tell(), we need to snapshot a point in the file
1390 * where the decoder's input buffer is empty.
1391 */
1392
1393 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1394 _PyIO_str_getstate, NULL);
1395 if (state == NULL)
1396 return -1;
1397 /* Given this, we know there was a valid snapshot point
1398 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1399 */
1400 if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) {
1401 Py_DECREF(state);
1402 return -1;
1403 }
1404 Py_INCREF(dec_buffer);
1405 Py_INCREF(dec_flags);
1406 Py_DECREF(state);
1407 }
1408
1409 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
1410 chunk_size = PyLong_FromSsize_t(self->chunk_size);
1411 if (chunk_size == NULL)
1412 goto fail;
1413 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
1414 _PyIO_str_read1, chunk_size, NULL);
1415 Py_DECREF(chunk_size);
1416 if (input_chunk == NULL)
1417 goto fail;
1418 assert(PyBytes_Check(input_chunk));
1419
1420 eof = (PyBytes_Size(input_chunk) == 0);
1421
1422 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1423 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1424 self->decoder, input_chunk, eof);
1425 }
1426 else {
1427 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1428 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1429 }
1430
1431 /* TODO sanity check: isinstance(decoded_chars, unicode) */
1432 if (decoded_chars == NULL)
1433 goto fail;
1434 TextIOWrapper_set_decoded_chars(self, decoded_chars);
1435 if (PyUnicode_GET_SIZE(decoded_chars) > 0)
1436 eof = 0;
1437
1438 if (self->telling) {
1439 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1440 * next input to be decoded is dec_buffer + input_chunk.
1441 */
1442 PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk);
1443 if (next_input == NULL)
1444 goto fail;
1445 assert (PyBytes_Check(next_input));
1446 Py_DECREF(dec_buffer);
1447 Py_CLEAR(self->snapshot);
1448 self->snapshot = Py_BuildValue("NN", dec_flags, next_input);
1449 }
1450 Py_DECREF(input_chunk);
1451
1452 return (eof == 0);
1453
1454 fail:
1455 Py_XDECREF(dec_buffer);
1456 Py_XDECREF(dec_flags);
1457 Py_XDECREF(input_chunk);
1458 return -1;
1459}
1460
1461static PyObject *
1462TextIOWrapper_read(PyTextIOWrapperObject *self, PyObject *args)
1463{
1464 Py_ssize_t n = -1;
1465 PyObject *result = NULL, *chunks = NULL;
1466
1467 CHECK_INITIALIZED(self);
1468
1469 if (!PyArg_ParseTuple(args, "|n:read", &n))
1470 return NULL;
1471
1472 CHECK_CLOSED(self);
1473
Benjamin Petersona1b49012009-03-31 23:11:32 +00001474 if (self->decoder == NULL) {
1475 PyErr_SetString(PyExc_IOError, "not readable");
1476 return NULL;
1477 }
1478
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 if (_TextIOWrapper_writeflush(self) < 0)
1480 return NULL;
1481
1482 if (n < 0) {
1483 /* Read everything */
1484 PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
1485 PyObject *decoded;
1486 if (bytes == NULL)
1487 goto fail;
1488 decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode,
1489 bytes, Py_True, NULL);
1490 Py_DECREF(bytes);
1491 if (decoded == NULL)
1492 goto fail;
1493
1494 result = TextIOWrapper_get_decoded_chars(self, -1);
1495
1496 if (result == NULL) {
1497 Py_DECREF(decoded);
1498 return NULL;
1499 }
1500
1501 PyUnicode_AppendAndDel(&result, decoded);
1502 if (result == NULL)
1503 goto fail;
1504
1505 Py_CLEAR(self->snapshot);
1506 return result;
1507 }
1508 else {
1509 int res = 1;
1510 Py_ssize_t remaining = n;
1511
1512 result = TextIOWrapper_get_decoded_chars(self, n);
1513 if (result == NULL)
1514 goto fail;
1515 remaining -= PyUnicode_GET_SIZE(result);
1516
1517 /* Keep reading chunks until we have n characters to return */
1518 while (remaining > 0) {
1519 res = TextIOWrapper_read_chunk(self);
1520 if (res < 0)
1521 goto fail;
1522 if (res == 0) /* EOF */
1523 break;
1524 if (chunks == NULL) {
1525 chunks = PyList_New(0);
1526 if (chunks == NULL)
1527 goto fail;
1528 }
1529 if (PyList_Append(chunks, result) < 0)
1530 goto fail;
1531 Py_DECREF(result);
1532 result = TextIOWrapper_get_decoded_chars(self, remaining);
1533 if (result == NULL)
1534 goto fail;
1535 remaining -= PyUnicode_GET_SIZE(result);
1536 }
1537 if (chunks != NULL) {
1538 if (result != NULL && PyList_Append(chunks, result) < 0)
1539 goto fail;
1540 Py_CLEAR(result);
1541 result = PyUnicode_Join(_PyIO_empty_str, chunks);
1542 if (result == NULL)
1543 goto fail;
1544 Py_CLEAR(chunks);
1545 }
1546 return result;
1547 }
1548 fail:
1549 Py_XDECREF(result);
1550 Py_XDECREF(chunks);
1551 return NULL;
1552}
1553
1554
1555/* NOTE: `end` must point to the real end of the Py_UNICODE storage,
1556 that is to the NUL character. Otherwise the function will produce
1557 incorrect results. */
1558static Py_UNICODE *
1559find_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch)
1560{
1561 Py_UNICODE *s = start;
1562 for (;;) {
1563 while (*s > ch)
1564 s++;
1565 if (*s == ch)
1566 return s;
1567 if (s == end)
1568 return NULL;
1569 s++;
1570 }
1571}
1572
1573Py_ssize_t
1574_PyIO_find_line_ending(
1575 int translated, int universal, PyObject *readnl,
1576 Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed)
1577{
1578 Py_ssize_t len = end - start;
1579
1580 if (translated) {
1581 /* Newlines are already translated, only search for \n */
1582 Py_UNICODE *pos = find_control_char(start, end, '\n');
1583 if (pos != NULL)
1584 return pos - start + 1;
1585 else {
1586 *consumed = len;
1587 return -1;
1588 }
1589 }
1590 else if (universal) {
1591 /* Universal newline search. Find any of \r, \r\n, \n
1592 * The decoder ensures that \r\n are not split in two pieces
1593 */
1594 Py_UNICODE *s = start;
1595 for (;;) {
1596 Py_UNICODE ch;
1597 /* Fast path for non-control chars. The loop always ends
1598 since the Py_UNICODE storage is NUL-terminated. */
1599 while (*s > '\r')
1600 s++;
1601 if (s >= end) {
1602 *consumed = len;
1603 return -1;
1604 }
1605 ch = *s++;
1606 if (ch == '\n')
1607 return s - start;
1608 if (ch == '\r') {
1609 if (*s == '\n')
1610 return s - start + 1;
1611 else
1612 return s - start;
1613 }
1614 }
1615 }
1616 else {
1617 /* Non-universal mode. */
1618 Py_ssize_t readnl_len = PyUnicode_GET_SIZE(readnl);
1619 Py_UNICODE *nl = PyUnicode_AS_UNICODE(readnl);
1620 if (readnl_len == 1) {
1621 Py_UNICODE *pos = find_control_char(start, end, nl[0]);
1622 if (pos != NULL)
1623 return pos - start + 1;
1624 *consumed = len;
1625 return -1;
1626 }
1627 else {
1628 Py_UNICODE *s = start;
1629 Py_UNICODE *e = end - readnl_len + 1;
1630 Py_UNICODE *pos;
1631 if (e < s)
1632 e = s;
1633 while (s < e) {
1634 Py_ssize_t i;
1635 Py_UNICODE *pos = find_control_char(s, end, nl[0]);
1636 if (pos == NULL || pos >= e)
1637 break;
1638 for (i = 1; i < readnl_len; i++) {
1639 if (pos[i] != nl[i])
1640 break;
1641 }
1642 if (i == readnl_len)
1643 return pos - start + readnl_len;
1644 s = pos + 1;
1645 }
1646 pos = find_control_char(e, end, nl[0]);
1647 if (pos == NULL)
1648 *consumed = len;
1649 else
1650 *consumed = pos - start;
1651 return -1;
1652 }
1653 }
1654}
1655
1656static PyObject *
1657_TextIOWrapper_readline(PyTextIOWrapperObject *self, Py_ssize_t limit)
1658{
1659 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1660 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1661 int res;
1662
1663 CHECK_CLOSED(self);
1664
1665 if (_TextIOWrapper_writeflush(self) < 0)
1666 return NULL;
1667
1668 chunked = 0;
1669
1670 while (1) {
1671 Py_UNICODE *ptr;
1672 Py_ssize_t line_len;
1673 Py_ssize_t consumed = 0;
1674
1675 /* First, get some data if necessary */
1676 res = 1;
1677 while (!self->decoded_chars ||
1678 !PyUnicode_GET_SIZE(self->decoded_chars)) {
1679 res = TextIOWrapper_read_chunk(self);
1680 if (res < 0)
1681 goto error;
1682 if (res == 0)
1683 break;
1684 }
1685 if (res == 0) {
1686 /* end of file */
1687 TextIOWrapper_set_decoded_chars(self, NULL);
1688 Py_CLEAR(self->snapshot);
1689 start = endpos = offset_to_buffer = 0;
1690 break;
1691 }
1692
1693 if (remaining == NULL) {
1694 line = self->decoded_chars;
1695 start = self->decoded_chars_used;
1696 offset_to_buffer = 0;
1697 Py_INCREF(line);
1698 }
1699 else {
1700 assert(self->decoded_chars_used == 0);
1701 line = PyUnicode_Concat(remaining, self->decoded_chars);
1702 start = 0;
1703 offset_to_buffer = PyUnicode_GET_SIZE(remaining);
1704 Py_CLEAR(remaining);
1705 if (line == NULL)
1706 goto error;
1707 }
1708
1709 ptr = PyUnicode_AS_UNICODE(line);
1710 line_len = PyUnicode_GET_SIZE(line);
1711
1712 endpos = _PyIO_find_line_ending(
1713 self->readtranslate, self->readuniversal, self->readnl,
1714 ptr + start, ptr + line_len, &consumed);
1715 if (endpos >= 0) {
1716 endpos += start;
1717 if (limit >= 0 && (endpos - start) + chunked >= limit)
1718 endpos = start + limit - chunked;
1719 break;
1720 }
1721
1722 /* We can put aside up to `endpos` */
1723 endpos = consumed + start;
1724 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1725 /* Didn't find line ending, but reached length limit */
1726 endpos = start + limit - chunked;
1727 break;
1728 }
1729
1730 if (endpos > start) {
1731 /* No line ending seen yet - put aside current data */
1732 PyObject *s;
1733 if (chunks == NULL) {
1734 chunks = PyList_New(0);
1735 if (chunks == NULL)
1736 goto error;
1737 }
1738 s = PyUnicode_FromUnicode(ptr + start, endpos - start);
1739 if (s == NULL)
1740 goto error;
1741 if (PyList_Append(chunks, s) < 0) {
1742 Py_DECREF(s);
1743 goto error;
1744 }
1745 chunked += PyUnicode_GET_SIZE(s);
1746 Py_DECREF(s);
1747 }
1748 /* There may be some remaining bytes we'll have to prepend to the
1749 next chunk of data */
1750 if (endpos < line_len) {
1751 remaining = PyUnicode_FromUnicode(
1752 ptr + endpos, line_len - endpos);
1753 if (remaining == NULL)
1754 goto error;
1755 }
1756 Py_CLEAR(line);
1757 /* We have consumed the buffer */
1758 TextIOWrapper_set_decoded_chars(self, NULL);
1759 }
1760
1761 if (line != NULL) {
1762 /* Our line ends in the current buffer */
1763 self->decoded_chars_used = endpos - offset_to_buffer;
1764 if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) {
1765 if (start == 0 && Py_REFCNT(line) == 1) {
1766 if (PyUnicode_Resize(&line, endpos) < 0)
1767 goto error;
1768 }
1769 else {
1770 PyObject *s = PyUnicode_FromUnicode(
1771 PyUnicode_AS_UNICODE(line) + start, endpos - start);
1772 Py_CLEAR(line);
1773 if (s == NULL)
1774 goto error;
1775 line = s;
1776 }
1777 }
1778 }
1779 if (remaining != NULL) {
1780 if (chunks == NULL) {
1781 chunks = PyList_New(0);
1782 if (chunks == NULL)
1783 goto error;
1784 }
1785 if (PyList_Append(chunks, remaining) < 0)
1786 goto error;
1787 Py_CLEAR(remaining);
1788 }
1789 if (chunks != NULL) {
1790 if (line != NULL && PyList_Append(chunks, line) < 0)
1791 goto error;
1792 Py_CLEAR(line);
1793 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1794 if (line == NULL)
1795 goto error;
1796 Py_DECREF(chunks);
1797 }
1798 if (line == NULL)
1799 line = PyUnicode_FromStringAndSize(NULL, 0);
1800
1801 return line;
1802
1803 error:
1804 Py_XDECREF(chunks);
1805 Py_XDECREF(remaining);
1806 Py_XDECREF(line);
1807 return NULL;
1808}
1809
1810static PyObject *
1811TextIOWrapper_readline(PyTextIOWrapperObject *self, PyObject *args)
1812{
1813 Py_ssize_t limit = -1;
1814
1815 CHECK_INITIALIZED(self);
1816 if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
1817 return NULL;
1818 }
1819 return _TextIOWrapper_readline(self, limit);
1820}
1821
1822/* Seek and Tell */
1823
1824typedef struct {
1825 Py_off_t start_pos;
1826 int dec_flags;
1827 int bytes_to_feed;
1828 int chars_to_skip;
1829 char need_eof;
1830} CookieStruct;
1831
1832/*
1833 To speed up cookie packing/unpacking, we store the fields in a temporary
1834 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
1835 The following macros define at which offsets in the intermediary byte
1836 string the various CookieStruct fields will be stored.
1837 */
1838
1839#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
1840
1841#if defined(WORDS_BIGENDIAN)
1842
1843# define IS_LITTLE_ENDIAN 0
1844
1845/* We want the least significant byte of start_pos to also be the least
1846 significant byte of the cookie, which means that in big-endian mode we
1847 must copy the fields in reverse order. */
1848
1849# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
1850# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
1851# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
1852# define OFF_CHARS_TO_SKIP (sizeof(char))
1853# define OFF_NEED_EOF 0
1854
1855#else
1856
1857# define IS_LITTLE_ENDIAN 1
1858
1859/* Little-endian mode: the least significant byte of start_pos will
1860 naturally end up the least significant byte of the cookie. */
1861
1862# define OFF_START_POS 0
1863# define OFF_DEC_FLAGS (sizeof(Py_off_t))
1864# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
1865# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
1866# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
1867
1868#endif
1869
1870static int
1871TextIOWrapper_parseCookie(CookieStruct *cookie, PyObject *cookieObj)
1872{
1873 unsigned char buffer[COOKIE_BUF_LEN];
1874 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
1875 if (cookieLong == NULL)
1876 return -1;
1877
1878 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
1879 IS_LITTLE_ENDIAN, 0) < 0) {
1880 Py_DECREF(cookieLong);
1881 return -1;
1882 }
1883 Py_DECREF(cookieLong);
1884
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001885 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
1886 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
1887 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
1888 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
1889 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001890
1891 return 0;
1892}
1893
1894static PyObject *
1895TextIOWrapper_buildCookie(CookieStruct *cookie)
1896{
1897 unsigned char buffer[COOKIE_BUF_LEN];
1898
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001899 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
1900 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
1901 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
1902 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
1903 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001904
1905 return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0);
1906}
1907#undef IS_LITTLE_ENDIAN
1908
1909static int
1910_TextIOWrapper_decoder_setstate(PyTextIOWrapperObject *self,
1911 CookieStruct *cookie)
1912{
1913 PyObject *res;
1914 /* When seeking to the start of the stream, we call decoder.reset()
1915 rather than decoder.getstate().
1916 This is for a few decoders such as utf-16 for which the state value
1917 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
1918 utf-16, that we are expecting a BOM).
1919 */
1920 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
1921 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
1922 else
1923 res = PyObject_CallMethod(self->decoder, "setstate",
1924 "((yi))", "", cookie->dec_flags);
1925 if (res == NULL)
1926 return -1;
1927 Py_DECREF(res);
1928 return 0;
1929}
1930
Antoine Pitroue4501852009-05-14 18:55:55 +00001931static int
1932_TextIOWrapper_encoder_setstate(PyTextIOWrapperObject *self,
1933 CookieStruct *cookie)
1934{
1935 PyObject *res;
1936 /* Same as _TextIOWrapper_decoder_setstate() above. */
1937 if (cookie->start_pos == 0 && cookie->dec_flags == 0) {
1938 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
1939 self->encoding_start_of_stream = 1;
1940 }
1941 else {
1942 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
1943 _PyIO_zero, NULL);
1944 self->encoding_start_of_stream = 0;
1945 }
1946 if (res == NULL)
1947 return -1;
1948 Py_DECREF(res);
1949 return 0;
1950}
1951
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001952static PyObject *
1953TextIOWrapper_seek(PyTextIOWrapperObject *self, PyObject *args)
1954{
1955 PyObject *cookieObj, *posobj;
1956 CookieStruct cookie;
1957 int whence = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958 PyObject *res;
1959 int cmp;
1960
1961 CHECK_INITIALIZED(self);
1962
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001963 if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
1964 return NULL;
1965 CHECK_CLOSED(self);
1966
1967 Py_INCREF(cookieObj);
1968
1969 if (!self->seekable) {
1970 PyErr_SetString(PyExc_IOError,
1971 "underlying stream is not seekable");
1972 goto fail;
1973 }
1974
1975 if (whence == 1) {
1976 /* seek relative to current position */
Antoine Pitroue4501852009-05-14 18:55:55 +00001977 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978 if (cmp < 0)
1979 goto fail;
1980
1981 if (cmp == 0) {
1982 PyErr_SetString(PyExc_IOError,
1983 "can't do nonzero cur-relative seeks");
1984 goto fail;
1985 }
1986
1987 /* Seeking to the current position should attempt to
1988 * sync the underlying buffer with the current position.
1989 */
1990 Py_DECREF(cookieObj);
1991 cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
1992 if (cookieObj == NULL)
1993 goto fail;
1994 }
1995 else if (whence == 2) {
1996 /* seek relative to end of file */
1997
Antoine Pitroue4501852009-05-14 18:55:55 +00001998 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999 if (cmp < 0)
2000 goto fail;
2001
2002 if (cmp == 0) {
2003 PyErr_SetString(PyExc_IOError,
2004 "can't do nonzero end-relative seeks");
2005 goto fail;
2006 }
2007
2008 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2009 if (res == NULL)
2010 goto fail;
2011 Py_DECREF(res);
2012
2013 TextIOWrapper_set_decoded_chars(self, NULL);
2014 Py_CLEAR(self->snapshot);
2015 if (self->decoder) {
2016 res = PyObject_CallMethod(self->decoder, "reset", NULL);
2017 if (res == NULL)
2018 goto fail;
2019 Py_DECREF(res);
2020 }
2021
2022 res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2);
2023 Py_XDECREF(cookieObj);
2024 return res;
2025 }
2026 else if (whence != 0) {
2027 PyErr_Format(PyExc_ValueError,
2028 "invalid whence (%d, should be 0, 1 or 2)", whence);
2029 goto fail;
2030 }
2031
Antoine Pitroue4501852009-05-14 18:55:55 +00002032 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_LT);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033 if (cmp < 0)
2034 goto fail;
2035
2036 if (cmp == 1) {
2037 PyErr_Format(PyExc_ValueError,
2038 "negative seek position %R", cookieObj);
2039 goto fail;
2040 }
2041
2042 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2043 if (res == NULL)
2044 goto fail;
2045 Py_DECREF(res);
2046
2047 /* The strategy of seek() is to go back to the safe start point
2048 * and replay the effect of read(chars_to_skip) from there.
2049 */
2050 if (TextIOWrapper_parseCookie(&cookie, cookieObj) < 0)
2051 goto fail;
2052
2053 /* Seek back to the safe start point. */
2054 posobj = PyLong_FromOff_t(cookie.start_pos);
2055 if (posobj == NULL)
2056 goto fail;
2057 res = PyObject_CallMethodObjArgs(self->buffer,
2058 _PyIO_str_seek, posobj, NULL);
2059 Py_DECREF(posobj);
2060 if (res == NULL)
2061 goto fail;
2062 Py_DECREF(res);
2063
2064 TextIOWrapper_set_decoded_chars(self, NULL);
2065 Py_CLEAR(self->snapshot);
2066
2067 /* Restore the decoder to its state from the safe start point. */
2068 if (self->decoder) {
2069 if (_TextIOWrapper_decoder_setstate(self, &cookie) < 0)
2070 goto fail;
2071 }
2072
2073 if (cookie.chars_to_skip) {
2074 /* Just like _read_chunk, feed the decoder and save a snapshot. */
2075 PyObject *input_chunk = PyObject_CallMethod(
2076 self->buffer, "read", "i", cookie.bytes_to_feed);
2077 PyObject *decoded;
2078
2079 if (input_chunk == NULL)
2080 goto fail;
2081
2082 assert (PyBytes_Check(input_chunk));
2083
2084 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2085 if (self->snapshot == NULL) {
2086 Py_DECREF(input_chunk);
2087 goto fail;
2088 }
2089
2090 decoded = PyObject_CallMethod(self->decoder, "decode",
2091 "Oi", input_chunk, (int)cookie.need_eof);
2092
2093 if (decoded == NULL)
2094 goto fail;
2095
2096 TextIOWrapper_set_decoded_chars(self, decoded);
2097
2098 /* Skip chars_to_skip of the decoded characters. */
2099 if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) {
2100 PyErr_SetString(PyExc_IOError, "can't restore logical file position");
2101 goto fail;
2102 }
2103 self->decoded_chars_used = cookie.chars_to_skip;
2104 }
2105 else {
2106 self->snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
2107 if (self->snapshot == NULL)
2108 goto fail;
2109 }
2110
Antoine Pitroue4501852009-05-14 18:55:55 +00002111 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2112 if (self->encoder) {
2113 if (_TextIOWrapper_encoder_setstate(self, &cookie) < 0)
2114 goto fail;
2115 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002116 return cookieObj;
2117 fail:
2118 Py_XDECREF(cookieObj);
2119 return NULL;
2120
2121}
2122
2123static PyObject *
2124TextIOWrapper_tell(PyTextIOWrapperObject *self, PyObject *args)
2125{
2126 PyObject *res;
2127 PyObject *posobj = NULL;
2128 CookieStruct cookie = {0,0,0,0,0};
2129 PyObject *next_input;
2130 Py_ssize_t chars_to_skip, chars_decoded;
2131 PyObject *saved_state = NULL;
2132 char *input, *input_end;
2133
2134 CHECK_INITIALIZED(self);
2135 CHECK_CLOSED(self);
2136
2137 if (!self->seekable) {
2138 PyErr_SetString(PyExc_IOError,
2139 "underlying stream is not seekable");
2140 goto fail;
2141 }
2142 if (!self->telling) {
2143 PyErr_SetString(PyExc_IOError,
2144 "telling position disabled by next() call");
2145 goto fail;
2146 }
2147
2148 if (_TextIOWrapper_writeflush(self) < 0)
2149 return NULL;
2150 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2151 if (res == NULL)
2152 goto fail;
2153 Py_DECREF(res);
2154
2155 posobj = PyObject_CallMethod(self->buffer, "tell", NULL);
2156 if (posobj == NULL)
2157 goto fail;
2158
2159 if (self->decoder == NULL || self->snapshot == NULL) {
2160 assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0);
2161 return posobj;
2162 }
2163
2164#if defined(HAVE_LARGEFILE_SUPPORT)
2165 cookie.start_pos = PyLong_AsLongLong(posobj);
2166#else
2167 cookie.start_pos = PyLong_AsLong(posobj);
2168#endif
2169 if (PyErr_Occurred())
2170 goto fail;
2171
2172 /* Skip backward to the snapshot point (see _read_chunk). */
2173 if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input))
2174 goto fail;
2175
2176 assert (PyBytes_Check(next_input));
2177
2178 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2179
2180 /* How many decoded characters have been used up since the snapshot? */
2181 if (self->decoded_chars_used == 0) {
2182 /* We haven't moved from the snapshot point. */
2183 Py_DECREF(posobj);
2184 return TextIOWrapper_buildCookie(&cookie);
2185 }
2186
2187 chars_to_skip = self->decoded_chars_used;
2188
2189 /* Starting from the snapshot position, we will walk the decoder
2190 * forward until it gives us enough decoded characters.
2191 */
2192 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2193 _PyIO_str_getstate, NULL);
2194 if (saved_state == NULL)
2195 goto fail;
2196
2197 /* Note our initial start point. */
2198 if (_TextIOWrapper_decoder_setstate(self, &cookie) < 0)
2199 goto fail;
2200
2201 /* Feed the decoder one byte at a time. As we go, note the
2202 * nearest "safe start point" before the current location
2203 * (a point where the decoder has nothing buffered, so seek()
2204 * can safely start from there and advance to this location).
2205 */
2206 chars_decoded = 0;
2207 input = PyBytes_AS_STRING(next_input);
2208 input_end = input + PyBytes_GET_SIZE(next_input);
2209 while (input < input_end) {
2210 PyObject *state;
2211 char *dec_buffer;
2212 Py_ssize_t dec_buffer_len;
2213 int dec_flags;
2214
2215 PyObject *decoded = PyObject_CallMethod(
2216 self->decoder, "decode", "y#", input, 1);
2217 if (decoded == NULL)
2218 goto fail;
2219 assert (PyUnicode_Check(decoded));
2220 chars_decoded += PyUnicode_GET_SIZE(decoded);
2221 Py_DECREF(decoded);
2222
2223 cookie.bytes_to_feed += 1;
2224
2225 state = PyObject_CallMethodObjArgs(self->decoder,
2226 _PyIO_str_getstate, NULL);
2227 if (state == NULL)
2228 goto fail;
2229 if (!PyArg_Parse(state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) {
2230 Py_DECREF(state);
2231 goto fail;
2232 }
2233 Py_DECREF(state);
2234
2235 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2236 /* Decoder buffer is empty, so this is a safe start point. */
2237 cookie.start_pos += cookie.bytes_to_feed;
2238 chars_to_skip -= chars_decoded;
2239 cookie.dec_flags = dec_flags;
2240 cookie.bytes_to_feed = 0;
2241 chars_decoded = 0;
2242 }
2243 if (chars_decoded >= chars_to_skip)
2244 break;
2245 input++;
2246 }
2247 if (input == input_end) {
2248 /* We didn't get enough decoded data; signal EOF to get more. */
2249 PyObject *decoded = PyObject_CallMethod(
2250 self->decoder, "decode", "yi", "", /* final = */ 1);
2251 if (decoded == NULL)
2252 goto fail;
2253 assert (PyUnicode_Check(decoded));
2254 chars_decoded += PyUnicode_GET_SIZE(decoded);
2255 Py_DECREF(decoded);
2256 cookie.need_eof = 1;
2257
2258 if (chars_decoded < chars_to_skip) {
2259 PyErr_SetString(PyExc_IOError,
2260 "can't reconstruct logical file position");
2261 goto fail;
2262 }
2263 }
2264
2265 /* finally */
2266 Py_XDECREF(posobj);
2267 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2268 Py_DECREF(saved_state);
2269 if (res == NULL)
2270 return NULL;
2271 Py_DECREF(res);
2272
2273 /* The returned cookie corresponds to the last safe start point. */
2274 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
2275 return TextIOWrapper_buildCookie(&cookie);
2276
2277 fail:
2278 Py_XDECREF(posobj);
2279 if (saved_state) {
2280 PyObject *type, *value, *traceback;
2281 PyErr_Fetch(&type, &value, &traceback);
2282
2283 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2284 Py_DECREF(saved_state);
2285 if (res == NULL)
2286 return NULL;
2287 Py_DECREF(res);
2288
2289 PyErr_Restore(type, value, traceback);
2290 }
2291 return NULL;
2292}
2293
2294static PyObject *
2295TextIOWrapper_truncate(PyTextIOWrapperObject *self, PyObject *args)
2296{
2297 PyObject *pos = Py_None;
2298 PyObject *res;
2299
2300 CHECK_INITIALIZED(self)
2301 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
2302 return NULL;
2303 }
2304
2305 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2306 if (res == NULL)
2307 return NULL;
2308 Py_DECREF(res);
2309
2310 if (pos != Py_None) {
2311 res = PyObject_CallMethodObjArgs((PyObject *) self,
2312 _PyIO_str_seek, pos, NULL);
2313 if (res == NULL)
2314 return NULL;
2315 Py_DECREF(res);
2316 }
2317
2318 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, NULL);
2319}
2320
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002321static PyObject *
2322TextIOWrapper_repr(PyTextIOWrapperObject *self)
2323{
Antoine Pitrou716c4442009-05-23 19:04:03 +00002324 PyObject *nameobj, *res;
2325
2326 CHECK_INITIALIZED(self);
2327
2328 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
2329 if (nameobj == NULL) {
2330 if (PyErr_ExceptionMatches(PyExc_AttributeError))
2331 PyErr_Clear();
2332 else
2333 return NULL;
2334 res = PyUnicode_FromFormat("<_io.TextIOWrapper encoding=%R>",
2335 self->encoding);
2336 }
2337 else {
2338 res = PyUnicode_FromFormat("<_io.TextIOWrapper name=%R encoding=%R>",
2339 nameobj, self->encoding);
2340 Py_DECREF(nameobj);
2341 }
2342 return res;
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002343}
2344
2345
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002346/* Inquiries */
2347
2348static PyObject *
2349TextIOWrapper_fileno(PyTextIOWrapperObject *self, PyObject *args)
2350{
2351 CHECK_INITIALIZED(self);
2352 return PyObject_CallMethod(self->buffer, "fileno", NULL);
2353}
2354
2355static PyObject *
2356TextIOWrapper_seekable(PyTextIOWrapperObject *self, PyObject *args)
2357{
2358 CHECK_INITIALIZED(self);
2359 return PyObject_CallMethod(self->buffer, "seekable", NULL);
2360}
2361
2362static PyObject *
2363TextIOWrapper_readable(PyTextIOWrapperObject *self, PyObject *args)
2364{
2365 CHECK_INITIALIZED(self);
2366 return PyObject_CallMethod(self->buffer, "readable", NULL);
2367}
2368
2369static PyObject *
2370TextIOWrapper_writable(PyTextIOWrapperObject *self, PyObject *args)
2371{
2372 CHECK_INITIALIZED(self);
2373 return PyObject_CallMethod(self->buffer, "writable", NULL);
2374}
2375
2376static PyObject *
2377TextIOWrapper_isatty(PyTextIOWrapperObject *self, PyObject *args)
2378{
2379 CHECK_INITIALIZED(self);
2380 return PyObject_CallMethod(self->buffer, "isatty", NULL);
2381}
2382
2383static PyObject *
2384TextIOWrapper_flush(PyTextIOWrapperObject *self, PyObject *args)
2385{
2386 CHECK_INITIALIZED(self);
2387 CHECK_CLOSED(self);
2388 self->telling = self->seekable;
2389 if (_TextIOWrapper_writeflush(self) < 0)
2390 return NULL;
2391 return PyObject_CallMethod(self->buffer, "flush", NULL);
2392}
2393
2394static PyObject *
2395TextIOWrapper_close(PyTextIOWrapperObject *self, PyObject *args)
2396{
2397 PyObject *res;
2398 CHECK_INITIALIZED(self);
2399 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2400 if (res == NULL) {
2401 /* If flush() fails, just give up */
2402 PyErr_Clear();
2403 }
2404 else
2405 Py_DECREF(res);
2406
2407 return PyObject_CallMethod(self->buffer, "close", NULL);
2408}
2409
2410static PyObject *
2411TextIOWrapper_iternext(PyTextIOWrapperObject *self)
2412{
2413 PyObject *line;
2414
2415 CHECK_INITIALIZED(self);
2416
2417 self->telling = 0;
2418 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2419 /* Skip method call overhead for speed */
2420 line = _TextIOWrapper_readline(self, -1);
2421 }
2422 else {
2423 line = PyObject_CallMethodObjArgs((PyObject *)self,
2424 _PyIO_str_readline, NULL);
2425 if (line && !PyUnicode_Check(line)) {
2426 PyErr_Format(PyExc_IOError,
2427 "readline() should have returned an str object, "
2428 "not '%.200s'", Py_TYPE(line)->tp_name);
2429 Py_DECREF(line);
2430 return NULL;
2431 }
2432 }
2433
2434 if (line == NULL)
2435 return NULL;
2436
2437 if (PyUnicode_GET_SIZE(line) == 0) {
2438 /* Reached EOF or would have blocked */
2439 Py_DECREF(line);
2440 Py_CLEAR(self->snapshot);
2441 self->telling = self->seekable;
2442 return NULL;
2443 }
2444
2445 return line;
2446}
2447
2448static PyObject *
2449TextIOWrapper_name_get(PyTextIOWrapperObject *self, void *context)
2450{
2451 CHECK_INITIALIZED(self);
2452 return PyObject_GetAttrString(self->buffer, "name");
2453}
2454
2455static PyObject *
2456TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context)
2457{
2458 CHECK_INITIALIZED(self);
2459 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2460}
2461
2462static PyObject *
2463TextIOWrapper_newlines_get(PyTextIOWrapperObject *self, void *context)
2464{
2465 PyObject *res;
2466 CHECK_INITIALIZED(self);
2467 if (self->decoder == NULL)
2468 Py_RETURN_NONE;
2469 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2470 if (res == NULL) {
2471 PyErr_Clear();
2472 Py_RETURN_NONE;
2473 }
2474 return res;
2475}
2476
2477static PyObject *
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002478TextIOWrapper_errors_get(PyTextIOWrapperObject *self, void *context)
2479{
2480 CHECK_INITIALIZED(self);
2481 return PyUnicode_FromString(PyBytes_AS_STRING(self->errors));
2482}
2483
2484static PyObject *
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002485TextIOWrapper_chunk_size_get(PyTextIOWrapperObject *self, void *context)
2486{
2487 CHECK_INITIALIZED(self);
2488 return PyLong_FromSsize_t(self->chunk_size);
2489}
2490
2491static int
2492TextIOWrapper_chunk_size_set(PyTextIOWrapperObject *self,
2493 PyObject *arg, void *context)
2494{
2495 Py_ssize_t n;
2496 CHECK_INITIALIZED_INT(self);
2497 n = PyNumber_AsSsize_t(arg, PyExc_TypeError);
2498 if (n == -1 && PyErr_Occurred())
2499 return -1;
2500 if (n <= 0) {
2501 PyErr_SetString(PyExc_ValueError,
2502 "a strictly positive integer is required");
2503 return -1;
2504 }
2505 self->chunk_size = n;
2506 return 0;
2507}
2508
2509static PyMethodDef TextIOWrapper_methods[] = {
Benjamin Petersond2e0c792009-05-01 20:40:59 +00002510 {"detach", (PyCFunction)TextIOWrapper_detach, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002511 {"write", (PyCFunction)TextIOWrapper_write, METH_VARARGS},
2512 {"read", (PyCFunction)TextIOWrapper_read, METH_VARARGS},
2513 {"readline", (PyCFunction)TextIOWrapper_readline, METH_VARARGS},
2514 {"flush", (PyCFunction)TextIOWrapper_flush, METH_NOARGS},
2515 {"close", (PyCFunction)TextIOWrapper_close, METH_NOARGS},
2516
2517 {"fileno", (PyCFunction)TextIOWrapper_fileno, METH_NOARGS},
2518 {"seekable", (PyCFunction)TextIOWrapper_seekable, METH_NOARGS},
2519 {"readable", (PyCFunction)TextIOWrapper_readable, METH_NOARGS},
2520 {"writable", (PyCFunction)TextIOWrapper_writable, METH_NOARGS},
2521 {"isatty", (PyCFunction)TextIOWrapper_isatty, METH_NOARGS},
2522
2523 {"seek", (PyCFunction)TextIOWrapper_seek, METH_VARARGS},
2524 {"tell", (PyCFunction)TextIOWrapper_tell, METH_NOARGS},
2525 {"truncate", (PyCFunction)TextIOWrapper_truncate, METH_VARARGS},
2526 {NULL, NULL}
2527};
2528
2529static PyMemberDef TextIOWrapper_members[] = {
2530 {"encoding", T_OBJECT, offsetof(PyTextIOWrapperObject, encoding), READONLY},
2531 {"buffer", T_OBJECT, offsetof(PyTextIOWrapperObject, buffer), READONLY},
2532 {"line_buffering", T_BOOL, offsetof(PyTextIOWrapperObject, line_buffering), READONLY},
2533 {NULL}
2534};
2535
2536static PyGetSetDef TextIOWrapper_getset[] = {
2537 {"name", (getter)TextIOWrapper_name_get, NULL, NULL},
2538 {"closed", (getter)TextIOWrapper_closed_get, NULL, NULL},
2539/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2540*/
2541 {"newlines", (getter)TextIOWrapper_newlines_get, NULL, NULL},
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002542 {"errors", (getter)TextIOWrapper_errors_get, NULL, NULL},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002543 {"_CHUNK_SIZE", (getter)TextIOWrapper_chunk_size_get,
2544 (setter)TextIOWrapper_chunk_size_set, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002545 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002546};
2547
2548PyTypeObject PyTextIOWrapper_Type = {
2549 PyVarObject_HEAD_INIT(NULL, 0)
2550 "_io.TextIOWrapper", /*tp_name*/
2551 sizeof(PyTextIOWrapperObject), /*tp_basicsize*/
2552 0, /*tp_itemsize*/
2553 (destructor)TextIOWrapper_dealloc, /*tp_dealloc*/
2554 0, /*tp_print*/
2555 0, /*tp_getattr*/
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002556 0, /*tps_etattr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002557 0, /*tp_compare */
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002558 (reprfunc)TextIOWrapper_repr,/*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559 0, /*tp_as_number*/
2560 0, /*tp_as_sequence*/
2561 0, /*tp_as_mapping*/
2562 0, /*tp_hash */
2563 0, /*tp_call*/
2564 0, /*tp_str*/
2565 0, /*tp_getattro*/
2566 0, /*tp_setattro*/
2567 0, /*tp_as_buffer*/
2568 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2569 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2570 TextIOWrapper_doc, /* tp_doc */
2571 (traverseproc)TextIOWrapper_traverse, /* tp_traverse */
2572 (inquiry)TextIOWrapper_clear, /* tp_clear */
2573 0, /* tp_richcompare */
2574 offsetof(PyTextIOWrapperObject, weakreflist), /*tp_weaklistoffset*/
2575 0, /* tp_iter */
2576 (iternextfunc)TextIOWrapper_iternext, /* tp_iternext */
2577 TextIOWrapper_methods, /* tp_methods */
2578 TextIOWrapper_members, /* tp_members */
2579 TextIOWrapper_getset, /* tp_getset */
2580 0, /* tp_base */
2581 0, /* tp_dict */
2582 0, /* tp_descr_get */
2583 0, /* tp_descr_set */
2584 offsetof(PyTextIOWrapperObject, dict), /*tp_dictoffset*/
2585 (initproc)TextIOWrapper_init, /* tp_init */
2586 0, /* tp_alloc */
2587 PyType_GenericNew, /* tp_new */
2588};