blob: 490484254b3b31033582ea761856c2a74bea2c7b [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
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000016PyDoc_STRVAR(textiobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000017 "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 Peterson680bf1a2009-06-12 02:07:12 +000031PyDoc_STRVAR(textiobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000032 "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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000039textiobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +000040{
41 return _unsupported("detach");
42}
43
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000044PyDoc_STRVAR(textiobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000045 "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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000052textiobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000053{
54 return _unsupported("read");
55}
56
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000057PyDoc_STRVAR(textiobase_readline_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000058 "Read until newline or EOF.\n"
59 "\n"
60 "Returns an empty string if EOF is hit immediately.\n"
61 );
62
63static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000064textiobase_readline(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000065{
66 return _unsupported("readline");
67}
68
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000069PyDoc_STRVAR(textiobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000070 "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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000076textiobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000077{
78 return _unsupported("write");
79}
80
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000081PyDoc_STRVAR(textiobase_encoding_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000082 "Encoding of the text stream.\n"
83 "\n"
84 "Subclasses should override.\n"
85 );
86
87static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000088textiobase_encoding_get(PyObject *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000089{
90 Py_RETURN_NONE;
91}
92
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000093PyDoc_STRVAR(textiobase_newlines_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000094 "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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000102textiobase_newlines_get(PyObject *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000103{
104 Py_RETURN_NONE;
105}
106
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000107PyDoc_STRVAR(textiobase_errors_doc,
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000108 "The error setting of the decoder or encoder.\n"
109 "\n"
110 "Subclasses should override.\n"
111 );
112
113static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000114textiobase_errors_get(PyObject *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000115{
116 Py_RETURN_NONE;
117}
118
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000119
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000120static PyMethodDef textiobase_methods[] = {
121 {"detach", (PyCFunction)textiobase_detach, METH_NOARGS, textiobase_detach_doc},
122 {"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},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000125 {NULL, NULL}
126};
127
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000128static PyGetSetDef textiobase_getset[] = {
129 {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc},
130 {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc},
131 {"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*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000156 textiobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000157 0, /* tp_traverse */
158 0, /* tp_clear */
159 0, /* tp_richcompare */
160 0, /* tp_weaklistoffset */
161 0, /* tp_iter */
162 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000163 textiobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000164 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000165 textiobase_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000166 &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
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000179PyDoc_STRVAR(incrementalnewlinedecoder_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000180 "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;
Antoine Pitrouca767bd2009-09-21 21:37:02 +0000193 signed int pendingcr: 1;
194 signed int translate: 1;
195 unsigned int seennl: 3;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196} nldecoder_object;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197
198static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000199incrementalnewlinedecoder_init(nldecoder_object *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
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000232incrementalnewlinedecoder_dealloc(nldecoder_object *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000233{
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;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000250 nldecoder_object *self = (nldecoder_object *) _self;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251
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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000463incrementalnewlinedecoder_decode(nldecoder_object *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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000477incrementalnewlinedecoder_getstate(nldecoder_object *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000478{
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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000505incrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000506{
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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000524incrementalnewlinedecoder_reset(nldecoder_object *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000525{
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 *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000535incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000536{
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
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000559static 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
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000567static 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*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000575 sizeof(nldecoder_object), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000576 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000577 (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000578 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*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000593 incrementalnewlinedecoder_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000594 0, /* tp_traverse */
595 0, /* tp_clear */
596 0, /* tp_richcompare */
597 0, /*tp_weaklistoffset*/
598 0, /* tp_iter */
599 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000600 incrementalnewlinedecoder_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000601 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000602 incrementalnewlinedecoder_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000603 0, /* tp_base */
604 0, /* tp_dict */
605 0, /* tp_descr_get */
606 0, /* tp_descr_set */
607 0, /* tp_dictoffset */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000608 (initproc)incrementalnewlinedecoder_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000609 0, /* tp_alloc */
610 PyType_GenericNew, /* tp_new */
611};
612
613
614/* TextIOWrapper */
615
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000616PyDoc_STRVAR(textiowrapper_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000617 "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"
Antoine Pitrou0c1c0d42012-08-04 00:55:38 +0200625 "newline controls how line endings are handled. It can be None, '',\n"
626 "'\\n', '\\r', and '\\r\\n'. It works as follows:\n"
627 "\n"
628 "* On input, if newline is None, universal newlines mode is\n"
629 " enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n"
630 " these are translated into '\\n' before being returned to the\n"
631 " caller. If it is '', universal newline mode is enabled, but line\n"
632 " endings are returned to the caller untranslated. If it has any of\n"
633 " the other legal values, input lines are only terminated by the given\n"
634 " string, and the line ending is returned to the caller untranslated.\n"
635 "\n"
636 "* On output, if newline is None, any '\\n' characters written are\n"
637 " translated to the system default line separator, os.linesep. If\n"
Victor Stinner401e17d2012-08-04 01:18:56 +0200638 " newline is '' or '\n', no translation takes place. If newline is any\n"
639 " of the other legal values, any '\\n' characters written are translated\n"
640 " to the given string.\n"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000641 "\n"
642 "If line_buffering is True, a call to flush is implied when a call to\n"
643 "write contains a newline character."
644 );
645
646typedef PyObject *
647 (*encodefunc_t)(PyObject *, PyObject *);
648
649typedef struct
650{
651 PyObject_HEAD
652 int ok; /* initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000653 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000654 Py_ssize_t chunk_size;
655 PyObject *buffer;
656 PyObject *encoding;
657 PyObject *encoder;
658 PyObject *decoder;
659 PyObject *readnl;
660 PyObject *errors;
661 const char *writenl; /* utf-8 encoded, NULL stands for \n */
662 char line_buffering;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200663 char write_through;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664 char readuniversal;
665 char readtranslate;
666 char writetranslate;
667 char seekable;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200668 char has_read1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000669 char telling;
Antoine Pitroue033e062010-10-29 10:38:18 +0000670 char deallocating;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000671 /* Specialized encoding func (see below) */
672 encodefunc_t encodefunc;
Antoine Pitroue4501852009-05-14 18:55:55 +0000673 /* Whether or not it's the start of the stream */
674 char encoding_start_of_stream;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000675
676 /* Reads and writes are internally buffered in order to speed things up.
677 However, any read will first flush the write buffer if itsn't empty.
Antoine Pitrou24f36292009-03-28 22:16:42 +0000678
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000679 Please also note that text to be written is first encoded before being
680 buffered. This is necessary so that encoding errors are immediately
681 reported to the caller, but it unfortunately means that the
682 IncrementalEncoder (whose encode() method is always written in Python)
683 becomes a bottleneck for small writes.
684 */
685 PyObject *decoded_chars; /* buffer for text returned from decoder */
686 Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */
687 PyObject *pending_bytes; /* list of bytes objects waiting to be
688 written, or NULL */
689 Py_ssize_t pending_bytes_count;
690 PyObject *snapshot;
691 /* snapshot is either None, or a tuple (dec_flags, next_input) where
692 * dec_flags is the second (integer) item of the decoder state and
693 * next_input is the chunk of input bytes that comes next after the
694 * snapshot point. We use this to reconstruct decoder states in tell().
695 */
696
697 /* Cache raw object if it's a FileIO object */
698 PyObject *raw;
699
700 PyObject *weakreflist;
701 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000702} textio;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000703
704
705/* A couple of specialized cases in order to bypass the slow incremental
706 encoding methods for the most popular encodings. */
707
708static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000709ascii_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000710{
711 return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(text),
712 PyUnicode_GET_SIZE(text),
713 PyBytes_AS_STRING(self->errors));
714}
715
716static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000717utf16be_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000718{
719 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
720 PyUnicode_GET_SIZE(text),
721 PyBytes_AS_STRING(self->errors), 1);
722}
723
724static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000725utf16le_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000726{
727 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
728 PyUnicode_GET_SIZE(text),
729 PyBytes_AS_STRING(self->errors), -1);
730}
731
732static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000733utf16_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000734{
Antoine Pitroue4501852009-05-14 18:55:55 +0000735 if (!self->encoding_start_of_stream) {
736 /* Skip the BOM and use native byte ordering */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000737#if defined(WORDS_BIGENDIAN)
Antoine Pitroue4501852009-05-14 18:55:55 +0000738 return utf16be_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000739#else
Antoine Pitroue4501852009-05-14 18:55:55 +0000740 return utf16le_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000741#endif
Antoine Pitroue4501852009-05-14 18:55:55 +0000742 }
743 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
744 PyUnicode_GET_SIZE(text),
745 PyBytes_AS_STRING(self->errors), 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000746}
747
Antoine Pitroue4501852009-05-14 18:55:55 +0000748static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000749utf32be_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000750{
751 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
752 PyUnicode_GET_SIZE(text),
753 PyBytes_AS_STRING(self->errors), 1);
754}
755
756static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000757utf32le_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000758{
759 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
760 PyUnicode_GET_SIZE(text),
761 PyBytes_AS_STRING(self->errors), -1);
762}
763
764static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000765utf32_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000766{
767 if (!self->encoding_start_of_stream) {
768 /* Skip the BOM and use native byte ordering */
769#if defined(WORDS_BIGENDIAN)
770 return utf32be_encode(self, text);
771#else
772 return utf32le_encode(self, text);
773#endif
774 }
775 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
776 PyUnicode_GET_SIZE(text),
777 PyBytes_AS_STRING(self->errors), 0);
778}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000779
780static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000781utf8_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000782{
783 return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(text),
784 PyUnicode_GET_SIZE(text),
785 PyBytes_AS_STRING(self->errors));
786}
787
788static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000789latin1_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000790{
791 return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(text),
792 PyUnicode_GET_SIZE(text),
793 PyBytes_AS_STRING(self->errors));
794}
795
796/* Map normalized encoding names onto the specialized encoding funcs */
797
798typedef struct {
799 const char *name;
800 encodefunc_t encodefunc;
801} encodefuncentry;
802
Antoine Pitrou24f36292009-03-28 22:16:42 +0000803static encodefuncentry encodefuncs[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000804 {"ascii", (encodefunc_t) ascii_encode},
805 {"iso8859-1", (encodefunc_t) latin1_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000806 {"utf-8", (encodefunc_t) utf8_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000807 {"utf-16-be", (encodefunc_t) utf16be_encode},
808 {"utf-16-le", (encodefunc_t) utf16le_encode},
809 {"utf-16", (encodefunc_t) utf16_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000810 {"utf-32-be", (encodefunc_t) utf32be_encode},
811 {"utf-32-le", (encodefunc_t) utf32le_encode},
812 {"utf-32", (encodefunc_t) utf32_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000813 {NULL, NULL}
814};
815
816
817static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000818textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000819{
820 char *kwlist[] = {"buffer", "encoding", "errors",
Antoine Pitroue96ec682011-07-23 21:46:35 +0200821 "newline", "line_buffering", "write_through",
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000822 NULL};
823 PyObject *buffer, *raw;
824 char *encoding = NULL;
825 char *errors = NULL;
826 char *newline = NULL;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200827 int line_buffering = 0, write_through = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000828 _PyIO_State *state = IO_STATE;
829
830 PyObject *res;
831 int r;
832
833 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000834 self->detached = 0;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200835 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzii:fileio",
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000836 kwlist, &buffer, &encoding, &errors,
Antoine Pitroue96ec682011-07-23 21:46:35 +0200837 &newline, &line_buffering, &write_through))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000838 return -1;
839
840 if (newline && newline[0] != '\0'
841 && !(newline[0] == '\n' && newline[1] == '\0')
842 && !(newline[0] == '\r' && newline[1] == '\0')
843 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
844 PyErr_Format(PyExc_ValueError,
845 "illegal newline value: %s", newline);
846 return -1;
847 }
848
849 Py_CLEAR(self->buffer);
850 Py_CLEAR(self->encoding);
851 Py_CLEAR(self->encoder);
852 Py_CLEAR(self->decoder);
853 Py_CLEAR(self->readnl);
854 Py_CLEAR(self->decoded_chars);
855 Py_CLEAR(self->pending_bytes);
856 Py_CLEAR(self->snapshot);
857 Py_CLEAR(self->errors);
858 Py_CLEAR(self->raw);
859 self->decoded_chars_used = 0;
860 self->pending_bytes_count = 0;
861 self->encodefunc = NULL;
862
863 if (encoding == NULL) {
864 /* Try os.device_encoding(fileno) */
865 PyObject *fileno;
866 fileno = PyObject_CallMethod(buffer, "fileno", NULL);
867 /* Ignore only AttributeError and UnsupportedOperation */
868 if (fileno == NULL) {
869 if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
870 PyErr_ExceptionMatches(state->unsupported_operation)) {
871 PyErr_Clear();
872 }
873 else {
874 goto error;
875 }
876 }
877 else {
878 self->encoding = PyObject_CallMethod(state->os_module,
879 "device_encoding",
880 "N", fileno);
881 if (self->encoding == NULL)
882 goto error;
883 else if (!PyUnicode_Check(self->encoding))
884 Py_CLEAR(self->encoding);
885 }
886 }
887 if (encoding == NULL && self->encoding == NULL) {
888 if (state->locale_module == NULL) {
889 state->locale_module = PyImport_ImportModule("locale");
890 if (state->locale_module == NULL)
891 goto catch_ImportError;
892 else
893 goto use_locale;
894 }
895 else {
896 use_locale:
897 self->encoding = PyObject_CallMethod(
898 state->locale_module, "getpreferredencoding", NULL);
899 if (self->encoding == NULL) {
900 catch_ImportError:
901 /*
902 Importing locale can raise a ImportError because of
903 _functools, and locale.getpreferredencoding can raise a
904 ImportError if _locale is not available. These will happen
905 during module building.
906 */
907 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
908 PyErr_Clear();
909 self->encoding = PyUnicode_FromString("ascii");
910 }
911 else
912 goto error;
913 }
914 else if (!PyUnicode_Check(self->encoding))
915 Py_CLEAR(self->encoding);
916 }
917 }
Victor Stinnerf6c57832010-05-19 01:17:01 +0000918 if (self->encoding != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000919 encoding = _PyUnicode_AsString(self->encoding);
Victor Stinnerf6c57832010-05-19 01:17:01 +0000920 if (encoding == NULL)
921 goto error;
922 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000923 else if (encoding != NULL) {
924 self->encoding = PyUnicode_FromString(encoding);
925 if (self->encoding == NULL)
926 goto error;
927 }
928 else {
929 PyErr_SetString(PyExc_IOError,
930 "could not determine default encoding");
931 }
932
933 if (errors == NULL)
934 errors = "strict";
935 self->errors = PyBytes_FromString(errors);
936 if (self->errors == NULL)
937 goto error;
938
939 self->chunk_size = 8192;
940 self->readuniversal = (newline == NULL || newline[0] == '\0');
941 self->line_buffering = line_buffering;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200942 self->write_through = write_through;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943 self->readtranslate = (newline == NULL);
944 if (newline) {
945 self->readnl = PyUnicode_FromString(newline);
946 if (self->readnl == NULL)
947 return -1;
948 }
949 self->writetranslate = (newline == NULL || newline[0] != '\0');
950 if (!self->readuniversal && self->readnl) {
951 self->writenl = _PyUnicode_AsString(self->readnl);
Victor Stinnerf6c57832010-05-19 01:17:01 +0000952 if (self->writenl == NULL)
953 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000954 if (!strcmp(self->writenl, "\n"))
955 self->writenl = NULL;
956 }
957#ifdef MS_WINDOWS
958 else
959 self->writenl = "\r\n";
960#endif
961
962 /* Build the decoder object */
963 res = PyObject_CallMethod(buffer, "readable", NULL);
964 if (res == NULL)
965 goto error;
966 r = PyObject_IsTrue(res);
967 Py_DECREF(res);
968 if (r == -1)
969 goto error;
970 if (r == 1) {
971 self->decoder = PyCodec_IncrementalDecoder(
972 encoding, errors);
973 if (self->decoder == NULL)
974 goto error;
975
976 if (self->readuniversal) {
977 PyObject *incrementalDecoder = PyObject_CallFunction(
978 (PyObject *)&PyIncrementalNewlineDecoder_Type,
979 "Oi", self->decoder, (int)self->readtranslate);
980 if (incrementalDecoder == NULL)
981 goto error;
982 Py_CLEAR(self->decoder);
983 self->decoder = incrementalDecoder;
984 }
985 }
986
987 /* Build the encoder object */
988 res = PyObject_CallMethod(buffer, "writable", NULL);
989 if (res == NULL)
990 goto error;
991 r = PyObject_IsTrue(res);
992 Py_DECREF(res);
993 if (r == -1)
994 goto error;
995 if (r == 1) {
996 PyObject *ci;
997 self->encoder = PyCodec_IncrementalEncoder(
998 encoding, errors);
999 if (self->encoder == NULL)
1000 goto error;
1001 /* Get the normalized named of the codec */
1002 ci = _PyCodec_Lookup(encoding);
1003 if (ci == NULL)
1004 goto error;
1005 res = PyObject_GetAttrString(ci, "name");
1006 Py_DECREF(ci);
Benjamin Peterson2cfca792009-06-06 20:46:48 +00001007 if (res == NULL) {
1008 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1009 PyErr_Clear();
1010 else
1011 goto error;
1012 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001013 else if (PyUnicode_Check(res)) {
1014 encodefuncentry *e = encodefuncs;
1015 while (e->name != NULL) {
1016 if (!PyUnicode_CompareWithASCIIString(res, e->name)) {
1017 self->encodefunc = e->encodefunc;
1018 break;
1019 }
1020 e++;
1021 }
1022 }
1023 Py_XDECREF(res);
1024 }
1025
1026 self->buffer = buffer;
1027 Py_INCREF(buffer);
Antoine Pitrou24f36292009-03-28 22:16:42 +00001028
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001029 if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
1030 Py_TYPE(buffer) == &PyBufferedWriter_Type ||
1031 Py_TYPE(buffer) == &PyBufferedRandom_Type) {
1032 raw = PyObject_GetAttrString(buffer, "raw");
1033 /* Cache the raw FileIO object to speed up 'closed' checks */
Benjamin Peterson2cfca792009-06-06 20:46:48 +00001034 if (raw == NULL) {
1035 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1036 PyErr_Clear();
1037 else
1038 goto error;
1039 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001040 else if (Py_TYPE(raw) == &PyFileIO_Type)
1041 self->raw = raw;
1042 else
1043 Py_DECREF(raw);
1044 }
1045
1046 res = PyObject_CallMethod(buffer, "seekable", NULL);
1047 if (res == NULL)
1048 goto error;
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001049 r = PyObject_IsTrue(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001050 Py_DECREF(res);
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001051 if (r < 0)
1052 goto error;
1053 self->seekable = self->telling = r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001054
Antoine Pitroue96ec682011-07-23 21:46:35 +02001055 self->has_read1 = PyObject_HasAttrString(buffer, "read1");
1056
Antoine Pitroue4501852009-05-14 18:55:55 +00001057 self->encoding_start_of_stream = 0;
1058 if (self->seekable && self->encoder) {
1059 PyObject *cookieObj;
1060 int cmp;
1061
1062 self->encoding_start_of_stream = 1;
1063
1064 cookieObj = PyObject_CallMethodObjArgs(buffer, _PyIO_str_tell, NULL);
1065 if (cookieObj == NULL)
1066 goto error;
1067
1068 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
1069 Py_DECREF(cookieObj);
1070 if (cmp < 0) {
1071 goto error;
1072 }
1073
1074 if (cmp == 0) {
1075 self->encoding_start_of_stream = 0;
1076 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
1077 _PyIO_zero, NULL);
1078 if (res == NULL)
1079 goto error;
1080 Py_DECREF(res);
1081 }
1082 }
1083
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001084 self->ok = 1;
1085 return 0;
1086
1087 error:
1088 return -1;
1089}
1090
1091static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001092_textiowrapper_clear(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001093{
1094 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
1095 return -1;
1096 self->ok = 0;
1097 Py_CLEAR(self->buffer);
1098 Py_CLEAR(self->encoding);
1099 Py_CLEAR(self->encoder);
1100 Py_CLEAR(self->decoder);
1101 Py_CLEAR(self->readnl);
1102 Py_CLEAR(self->decoded_chars);
1103 Py_CLEAR(self->pending_bytes);
1104 Py_CLEAR(self->snapshot);
1105 Py_CLEAR(self->errors);
1106 Py_CLEAR(self->raw);
1107 return 0;
1108}
1109
1110static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001111textiowrapper_dealloc(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001112{
Antoine Pitroue033e062010-10-29 10:38:18 +00001113 self->deallocating = 1;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001114 if (_textiowrapper_clear(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001115 return;
1116 _PyObject_GC_UNTRACK(self);
1117 if (self->weakreflist != NULL)
1118 PyObject_ClearWeakRefs((PyObject *)self);
1119 Py_CLEAR(self->dict);
1120 Py_TYPE(self)->tp_free((PyObject *)self);
1121}
1122
1123static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001124textiowrapper_traverse(textio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001125{
1126 Py_VISIT(self->buffer);
1127 Py_VISIT(self->encoding);
1128 Py_VISIT(self->encoder);
1129 Py_VISIT(self->decoder);
1130 Py_VISIT(self->readnl);
1131 Py_VISIT(self->decoded_chars);
1132 Py_VISIT(self->pending_bytes);
1133 Py_VISIT(self->snapshot);
1134 Py_VISIT(self->errors);
1135 Py_VISIT(self->raw);
1136
1137 Py_VISIT(self->dict);
1138 return 0;
1139}
1140
1141static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001142textiowrapper_clear(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001143{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001144 if (_textiowrapper_clear(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001145 return -1;
1146 Py_CLEAR(self->dict);
1147 return 0;
1148}
1149
1150static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001151textiowrapper_closed_get(textio *self, void *context);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001152
1153/* This macro takes some shortcuts to make the common case faster. */
1154#define CHECK_CLOSED(self) \
1155 do { \
1156 int r; \
1157 PyObject *_res; \
1158 if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \
1159 if (self->raw != NULL) \
1160 r = _PyFileIO_closed(self->raw); \
1161 else { \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001162 _res = textiowrapper_closed_get(self, NULL); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001163 if (_res == NULL) \
1164 return NULL; \
1165 r = PyObject_IsTrue(_res); \
1166 Py_DECREF(_res); \
1167 if (r < 0) \
1168 return NULL; \
1169 } \
1170 if (r > 0) { \
1171 PyErr_SetString(PyExc_ValueError, \
1172 "I/O operation on closed file."); \
1173 return NULL; \
1174 } \
1175 } \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001176 else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177 return NULL; \
1178 } while (0)
1179
1180#define CHECK_INITIALIZED(self) \
1181 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001182 if (self->detached) { \
1183 PyErr_SetString(PyExc_ValueError, \
1184 "underlying buffer has been detached"); \
1185 } else { \
1186 PyErr_SetString(PyExc_ValueError, \
1187 "I/O operation on uninitialized object"); \
1188 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001189 return NULL; \
1190 }
1191
1192#define CHECK_INITIALIZED_INT(self) \
1193 if (self->ok <= 0) { \
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001194 if (self->detached) { \
1195 PyErr_SetString(PyExc_ValueError, \
1196 "underlying buffer has been detached"); \
1197 } else { \
1198 PyErr_SetString(PyExc_ValueError, \
1199 "I/O operation on uninitialized object"); \
1200 } \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201 return -1; \
1202 }
1203
1204
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001205static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001206textiowrapper_detach(textio *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001207{
1208 PyObject *buffer, *res;
1209 CHECK_INITIALIZED(self);
1210 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
1211 if (res == NULL)
1212 return NULL;
1213 Py_DECREF(res);
1214 buffer = self->buffer;
1215 self->buffer = NULL;
1216 self->detached = 1;
1217 self->ok = 0;
1218 return buffer;
1219}
1220
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001221Py_LOCAL_INLINE(const Py_UNICODE *)
1222findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch)
1223{
1224 /* like wcschr, but doesn't stop at NULL characters */
1225 while (size-- > 0) {
1226 if (*s == ch)
1227 return s;
1228 s++;
1229 }
1230 return NULL;
1231}
1232
Antoine Pitrou24f36292009-03-28 22:16:42 +00001233/* Flush the internal write buffer. This doesn't explicitly flush the
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001234 underlying buffered object, though. */
1235static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001236_textiowrapper_writeflush(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001237{
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001238 PyObject *pending, *b, *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001239
1240 if (self->pending_bytes == NULL)
1241 return 0;
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001242
1243 pending = self->pending_bytes;
1244 Py_INCREF(pending);
1245 self->pending_bytes_count = 0;
1246 Py_CLEAR(self->pending_bytes);
1247
1248 b = _PyBytes_Join(_PyIO_empty_bytes, pending);
1249 Py_DECREF(pending);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250 if (b == NULL)
1251 return -1;
1252 ret = PyObject_CallMethodObjArgs(self->buffer,
1253 _PyIO_str_write, b, NULL);
1254 Py_DECREF(b);
1255 if (ret == NULL)
1256 return -1;
1257 Py_DECREF(ret);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001258 return 0;
1259}
1260
1261static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001262textiowrapper_write(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263{
1264 PyObject *ret;
1265 PyObject *text; /* owned reference */
1266 PyObject *b;
1267 Py_ssize_t textlen;
1268 int haslf = 0;
1269 int needflush = 0;
1270
1271 CHECK_INITIALIZED(self);
1272
1273 if (!PyArg_ParseTuple(args, "U:write", &text)) {
1274 return NULL;
1275 }
1276
1277 CHECK_CLOSED(self);
1278
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001279 if (self->encoder == NULL)
1280 return _unsupported("not writable");
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001281
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 Py_INCREF(text);
1283
1284 textlen = PyUnicode_GetSize(text);
1285
1286 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
1287 if (findchar(PyUnicode_AS_UNICODE(text),
1288 PyUnicode_GET_SIZE(text), '\n'))
1289 haslf = 1;
1290
1291 if (haslf && self->writetranslate && self->writenl != NULL) {
1292 PyObject *newtext = PyObject_CallMethod(
1293 text, "replace", "ss", "\n", self->writenl);
1294 Py_DECREF(text);
1295 if (newtext == NULL)
1296 return NULL;
1297 text = newtext;
1298 }
1299
Antoine Pitroue96ec682011-07-23 21:46:35 +02001300 if (self->write_through)
1301 needflush = 1;
1302 else if (self->line_buffering &&
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001303 (haslf ||
1304 findchar(PyUnicode_AS_UNICODE(text),
1305 PyUnicode_GET_SIZE(text), '\r')))
1306 needflush = 1;
1307
1308 /* XXX What if we were just reading? */
Antoine Pitroue4501852009-05-14 18:55:55 +00001309 if (self->encodefunc != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001310 b = (*self->encodefunc)((PyObject *) self, text);
Antoine Pitroue4501852009-05-14 18:55:55 +00001311 self->encoding_start_of_stream = 0;
1312 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 else
1314 b = PyObject_CallMethodObjArgs(self->encoder,
1315 _PyIO_str_encode, text, NULL);
1316 Py_DECREF(text);
1317 if (b == NULL)
1318 return NULL;
1319
1320 if (self->pending_bytes == NULL) {
1321 self->pending_bytes = PyList_New(0);
1322 if (self->pending_bytes == NULL) {
1323 Py_DECREF(b);
1324 return NULL;
1325 }
1326 self->pending_bytes_count = 0;
1327 }
1328 if (PyList_Append(self->pending_bytes, b) < 0) {
1329 Py_DECREF(b);
1330 return NULL;
1331 }
1332 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1333 Py_DECREF(b);
1334 if (self->pending_bytes_count > self->chunk_size || needflush) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001335 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336 return NULL;
1337 }
Antoine Pitrou24f36292009-03-28 22:16:42 +00001338
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339 if (needflush) {
1340 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1341 if (ret == NULL)
1342 return NULL;
1343 Py_DECREF(ret);
1344 }
1345
1346 Py_CLEAR(self->snapshot);
1347
1348 if (self->decoder) {
1349 ret = PyObject_CallMethod(self->decoder, "reset", NULL);
1350 if (ret == NULL)
1351 return NULL;
1352 Py_DECREF(ret);
1353 }
1354
1355 return PyLong_FromSsize_t(textlen);
1356}
1357
1358/* Steal a reference to chars and store it in the decoded_char buffer;
1359 */
1360static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001361textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362{
1363 Py_CLEAR(self->decoded_chars);
1364 self->decoded_chars = chars;
1365 self->decoded_chars_used = 0;
1366}
1367
1368static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001369textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001370{
1371 PyObject *chars;
1372 Py_ssize_t avail;
1373
1374 if (self->decoded_chars == NULL)
1375 return PyUnicode_FromStringAndSize(NULL, 0);
1376
1377 avail = (PyUnicode_GET_SIZE(self->decoded_chars)
1378 - self->decoded_chars_used);
1379
1380 assert(avail >= 0);
1381
1382 if (n < 0 || n > avail)
1383 n = avail;
1384
1385 if (self->decoded_chars_used > 0 || n < avail) {
1386 chars = PyUnicode_FromUnicode(
1387 PyUnicode_AS_UNICODE(self->decoded_chars)
1388 + self->decoded_chars_used, n);
1389 if (chars == NULL)
1390 return NULL;
1391 }
1392 else {
1393 chars = self->decoded_chars;
1394 Py_INCREF(chars);
1395 }
1396
1397 self->decoded_chars_used += n;
1398 return chars;
1399}
1400
1401/* Read and decode the next chunk of data from the BufferedReader.
1402 */
1403static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001404textiowrapper_read_chunk(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001405{
1406 PyObject *dec_buffer = NULL;
1407 PyObject *dec_flags = NULL;
1408 PyObject *input_chunk = NULL;
1409 PyObject *decoded_chars, *chunk_size;
1410 int eof;
1411
1412 /* The return value is True unless EOF was reached. The decoded string is
1413 * placed in self._decoded_chars (replacing its previous value). The
1414 * entire input chunk is sent to the decoder, though some of it may remain
1415 * buffered in the decoder, yet to be converted.
1416 */
1417
1418 if (self->decoder == NULL) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001419 _unsupported("not readable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001420 return -1;
1421 }
1422
1423 if (self->telling) {
1424 /* To prepare for tell(), we need to snapshot a point in the file
1425 * where the decoder's input buffer is empty.
1426 */
1427
1428 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1429 _PyIO_str_getstate, NULL);
1430 if (state == NULL)
1431 return -1;
1432 /* Given this, we know there was a valid snapshot point
1433 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1434 */
1435 if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) {
1436 Py_DECREF(state);
1437 return -1;
1438 }
1439 Py_INCREF(dec_buffer);
1440 Py_INCREF(dec_flags);
1441 Py_DECREF(state);
1442 }
1443
1444 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
1445 chunk_size = PyLong_FromSsize_t(self->chunk_size);
1446 if (chunk_size == NULL)
1447 goto fail;
1448 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
Antoine Pitroue96ec682011-07-23 21:46:35 +02001449 (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read),
1450 chunk_size, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001451 Py_DECREF(chunk_size);
1452 if (input_chunk == NULL)
1453 goto fail;
1454 assert(PyBytes_Check(input_chunk));
1455
1456 eof = (PyBytes_Size(input_chunk) == 0);
1457
1458 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1459 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1460 self->decoder, input_chunk, eof);
1461 }
1462 else {
1463 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1464 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1465 }
1466
1467 /* TODO sanity check: isinstance(decoded_chars, unicode) */
1468 if (decoded_chars == NULL)
1469 goto fail;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001470 textiowrapper_set_decoded_chars(self, decoded_chars);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001471 if (PyUnicode_GET_SIZE(decoded_chars) > 0)
1472 eof = 0;
1473
1474 if (self->telling) {
1475 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1476 * next input to be decoded is dec_buffer + input_chunk.
1477 */
1478 PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk);
1479 if (next_input == NULL)
1480 goto fail;
1481 assert (PyBytes_Check(next_input));
1482 Py_DECREF(dec_buffer);
1483 Py_CLEAR(self->snapshot);
1484 self->snapshot = Py_BuildValue("NN", dec_flags, next_input);
1485 }
1486 Py_DECREF(input_chunk);
1487
1488 return (eof == 0);
1489
1490 fail:
1491 Py_XDECREF(dec_buffer);
1492 Py_XDECREF(dec_flags);
1493 Py_XDECREF(input_chunk);
1494 return -1;
1495}
1496
1497static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001498textiowrapper_read(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001499{
1500 Py_ssize_t n = -1;
1501 PyObject *result = NULL, *chunks = NULL;
1502
1503 CHECK_INITIALIZED(self);
1504
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001505 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001506 return NULL;
1507
1508 CHECK_CLOSED(self);
1509
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001510 if (self->decoder == NULL)
1511 return _unsupported("not readable");
Benjamin Petersona1b49012009-03-31 23:11:32 +00001512
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001513 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001514 return NULL;
1515
1516 if (n < 0) {
1517 /* Read everything */
1518 PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
1519 PyObject *decoded;
1520 if (bytes == NULL)
1521 goto fail;
1522 decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode,
1523 bytes, Py_True, NULL);
1524 Py_DECREF(bytes);
1525 if (decoded == NULL)
1526 goto fail;
1527
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001528 result = textiowrapper_get_decoded_chars(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001529
1530 if (result == NULL) {
1531 Py_DECREF(decoded);
1532 return NULL;
1533 }
1534
1535 PyUnicode_AppendAndDel(&result, decoded);
1536 if (result == NULL)
1537 goto fail;
1538
1539 Py_CLEAR(self->snapshot);
1540 return result;
1541 }
1542 else {
1543 int res = 1;
1544 Py_ssize_t remaining = n;
1545
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001546 result = textiowrapper_get_decoded_chars(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001547 if (result == NULL)
1548 goto fail;
1549 remaining -= PyUnicode_GET_SIZE(result);
1550
1551 /* Keep reading chunks until we have n characters to return */
1552 while (remaining > 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001553 res = textiowrapper_read_chunk(self);
Gregory P. Smith51359922012-06-23 23:55:39 -07001554 if (res < 0) {
1555 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1556 when EINTR occurs so we needn't do it ourselves. */
1557 if (_PyIO_trap_eintr()) {
1558 continue;
1559 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001560 goto fail;
Gregory P. Smith51359922012-06-23 23:55:39 -07001561 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001562 if (res == 0) /* EOF */
1563 break;
1564 if (chunks == NULL) {
1565 chunks = PyList_New(0);
1566 if (chunks == NULL)
1567 goto fail;
1568 }
1569 if (PyList_Append(chunks, result) < 0)
1570 goto fail;
1571 Py_DECREF(result);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001572 result = textiowrapper_get_decoded_chars(self, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001573 if (result == NULL)
1574 goto fail;
1575 remaining -= PyUnicode_GET_SIZE(result);
1576 }
1577 if (chunks != NULL) {
1578 if (result != NULL && PyList_Append(chunks, result) < 0)
1579 goto fail;
1580 Py_CLEAR(result);
1581 result = PyUnicode_Join(_PyIO_empty_str, chunks);
1582 if (result == NULL)
1583 goto fail;
1584 Py_CLEAR(chunks);
1585 }
1586 return result;
1587 }
1588 fail:
1589 Py_XDECREF(result);
1590 Py_XDECREF(chunks);
1591 return NULL;
1592}
1593
1594
1595/* NOTE: `end` must point to the real end of the Py_UNICODE storage,
1596 that is to the NUL character. Otherwise the function will produce
1597 incorrect results. */
1598static Py_UNICODE *
1599find_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch)
1600{
1601 Py_UNICODE *s = start;
1602 for (;;) {
1603 while (*s > ch)
1604 s++;
1605 if (*s == ch)
1606 return s;
1607 if (s == end)
1608 return NULL;
1609 s++;
1610 }
1611}
1612
1613Py_ssize_t
1614_PyIO_find_line_ending(
1615 int translated, int universal, PyObject *readnl,
1616 Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed)
1617{
1618 Py_ssize_t len = end - start;
1619
1620 if (translated) {
1621 /* Newlines are already translated, only search for \n */
1622 Py_UNICODE *pos = find_control_char(start, end, '\n');
1623 if (pos != NULL)
1624 return pos - start + 1;
1625 else {
1626 *consumed = len;
1627 return -1;
1628 }
1629 }
1630 else if (universal) {
1631 /* Universal newline search. Find any of \r, \r\n, \n
1632 * The decoder ensures that \r\n are not split in two pieces
1633 */
1634 Py_UNICODE *s = start;
1635 for (;;) {
1636 Py_UNICODE ch;
1637 /* Fast path for non-control chars. The loop always ends
1638 since the Py_UNICODE storage is NUL-terminated. */
1639 while (*s > '\r')
1640 s++;
1641 if (s >= end) {
1642 *consumed = len;
1643 return -1;
1644 }
1645 ch = *s++;
1646 if (ch == '\n')
1647 return s - start;
1648 if (ch == '\r') {
1649 if (*s == '\n')
1650 return s - start + 1;
1651 else
1652 return s - start;
1653 }
1654 }
1655 }
1656 else {
1657 /* Non-universal mode. */
1658 Py_ssize_t readnl_len = PyUnicode_GET_SIZE(readnl);
1659 Py_UNICODE *nl = PyUnicode_AS_UNICODE(readnl);
1660 if (readnl_len == 1) {
1661 Py_UNICODE *pos = find_control_char(start, end, nl[0]);
1662 if (pos != NULL)
1663 return pos - start + 1;
1664 *consumed = len;
1665 return -1;
1666 }
1667 else {
1668 Py_UNICODE *s = start;
1669 Py_UNICODE *e = end - readnl_len + 1;
1670 Py_UNICODE *pos;
1671 if (e < s)
1672 e = s;
1673 while (s < e) {
1674 Py_ssize_t i;
1675 Py_UNICODE *pos = find_control_char(s, end, nl[0]);
1676 if (pos == NULL || pos >= e)
1677 break;
1678 for (i = 1; i < readnl_len; i++) {
1679 if (pos[i] != nl[i])
1680 break;
1681 }
1682 if (i == readnl_len)
1683 return pos - start + readnl_len;
1684 s = pos + 1;
1685 }
1686 pos = find_control_char(e, end, nl[0]);
1687 if (pos == NULL)
1688 *consumed = len;
1689 else
1690 *consumed = pos - start;
1691 return -1;
1692 }
1693 }
1694}
1695
1696static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001697_textiowrapper_readline(textio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001698{
1699 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1700 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1701 int res;
1702
1703 CHECK_CLOSED(self);
1704
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001705 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 return NULL;
1707
1708 chunked = 0;
1709
1710 while (1) {
1711 Py_UNICODE *ptr;
1712 Py_ssize_t line_len;
1713 Py_ssize_t consumed = 0;
1714
1715 /* First, get some data if necessary */
1716 res = 1;
1717 while (!self->decoded_chars ||
1718 !PyUnicode_GET_SIZE(self->decoded_chars)) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001719 res = textiowrapper_read_chunk(self);
Gregory P. Smith51359922012-06-23 23:55:39 -07001720 if (res < 0) {
1721 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1722 when EINTR occurs so we needn't do it ourselves. */
1723 if (_PyIO_trap_eintr()) {
1724 continue;
1725 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001726 goto error;
Gregory P. Smith51359922012-06-23 23:55:39 -07001727 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001728 if (res == 0)
1729 break;
1730 }
1731 if (res == 0) {
1732 /* end of file */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001733 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001734 Py_CLEAR(self->snapshot);
1735 start = endpos = offset_to_buffer = 0;
1736 break;
1737 }
1738
1739 if (remaining == NULL) {
1740 line = self->decoded_chars;
1741 start = self->decoded_chars_used;
1742 offset_to_buffer = 0;
1743 Py_INCREF(line);
1744 }
1745 else {
1746 assert(self->decoded_chars_used == 0);
1747 line = PyUnicode_Concat(remaining, self->decoded_chars);
1748 start = 0;
1749 offset_to_buffer = PyUnicode_GET_SIZE(remaining);
1750 Py_CLEAR(remaining);
1751 if (line == NULL)
1752 goto error;
1753 }
1754
1755 ptr = PyUnicode_AS_UNICODE(line);
1756 line_len = PyUnicode_GET_SIZE(line);
1757
1758 endpos = _PyIO_find_line_ending(
1759 self->readtranslate, self->readuniversal, self->readnl,
1760 ptr + start, ptr + line_len, &consumed);
1761 if (endpos >= 0) {
1762 endpos += start;
1763 if (limit >= 0 && (endpos - start) + chunked >= limit)
1764 endpos = start + limit - chunked;
1765 break;
1766 }
1767
1768 /* We can put aside up to `endpos` */
1769 endpos = consumed + start;
1770 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1771 /* Didn't find line ending, but reached length limit */
1772 endpos = start + limit - chunked;
1773 break;
1774 }
1775
1776 if (endpos > start) {
1777 /* No line ending seen yet - put aside current data */
1778 PyObject *s;
1779 if (chunks == NULL) {
1780 chunks = PyList_New(0);
1781 if (chunks == NULL)
1782 goto error;
1783 }
1784 s = PyUnicode_FromUnicode(ptr + start, endpos - start);
1785 if (s == NULL)
1786 goto error;
1787 if (PyList_Append(chunks, s) < 0) {
1788 Py_DECREF(s);
1789 goto error;
1790 }
1791 chunked += PyUnicode_GET_SIZE(s);
1792 Py_DECREF(s);
1793 }
1794 /* There may be some remaining bytes we'll have to prepend to the
1795 next chunk of data */
1796 if (endpos < line_len) {
1797 remaining = PyUnicode_FromUnicode(
1798 ptr + endpos, line_len - endpos);
1799 if (remaining == NULL)
1800 goto error;
1801 }
1802 Py_CLEAR(line);
1803 /* We have consumed the buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001804 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 }
1806
1807 if (line != NULL) {
1808 /* Our line ends in the current buffer */
1809 self->decoded_chars_used = endpos - offset_to_buffer;
1810 if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) {
1811 if (start == 0 && Py_REFCNT(line) == 1) {
1812 if (PyUnicode_Resize(&line, endpos) < 0)
1813 goto error;
1814 }
1815 else {
1816 PyObject *s = PyUnicode_FromUnicode(
1817 PyUnicode_AS_UNICODE(line) + start, endpos - start);
1818 Py_CLEAR(line);
1819 if (s == NULL)
1820 goto error;
1821 line = s;
1822 }
1823 }
1824 }
1825 if (remaining != NULL) {
1826 if (chunks == NULL) {
1827 chunks = PyList_New(0);
1828 if (chunks == NULL)
1829 goto error;
1830 }
1831 if (PyList_Append(chunks, remaining) < 0)
1832 goto error;
1833 Py_CLEAR(remaining);
1834 }
1835 if (chunks != NULL) {
1836 if (line != NULL && PyList_Append(chunks, line) < 0)
1837 goto error;
1838 Py_CLEAR(line);
1839 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1840 if (line == NULL)
1841 goto error;
1842 Py_DECREF(chunks);
1843 }
1844 if (line == NULL)
1845 line = PyUnicode_FromStringAndSize(NULL, 0);
1846
1847 return line;
1848
1849 error:
1850 Py_XDECREF(chunks);
1851 Py_XDECREF(remaining);
1852 Py_XDECREF(line);
1853 return NULL;
1854}
1855
1856static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001857textiowrapper_readline(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858{
1859 Py_ssize_t limit = -1;
1860
1861 CHECK_INITIALIZED(self);
1862 if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
1863 return NULL;
1864 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001865 return _textiowrapper_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001866}
1867
1868/* Seek and Tell */
1869
1870typedef struct {
1871 Py_off_t start_pos;
1872 int dec_flags;
1873 int bytes_to_feed;
1874 int chars_to_skip;
1875 char need_eof;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001876} cookie_type;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001877
1878/*
1879 To speed up cookie packing/unpacking, we store the fields in a temporary
1880 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
1881 The following macros define at which offsets in the intermediary byte
1882 string the various CookieStruct fields will be stored.
1883 */
1884
1885#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
1886
1887#if defined(WORDS_BIGENDIAN)
1888
1889# define IS_LITTLE_ENDIAN 0
1890
1891/* We want the least significant byte of start_pos to also be the least
1892 significant byte of the cookie, which means that in big-endian mode we
1893 must copy the fields in reverse order. */
1894
1895# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
1896# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
1897# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
1898# define OFF_CHARS_TO_SKIP (sizeof(char))
1899# define OFF_NEED_EOF 0
1900
1901#else
1902
1903# define IS_LITTLE_ENDIAN 1
1904
1905/* Little-endian mode: the least significant byte of start_pos will
1906 naturally end up the least significant byte of the cookie. */
1907
1908# define OFF_START_POS 0
1909# define OFF_DEC_FLAGS (sizeof(Py_off_t))
1910# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
1911# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
1912# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
1913
1914#endif
1915
1916static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001917textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001918{
1919 unsigned char buffer[COOKIE_BUF_LEN];
1920 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
1921 if (cookieLong == NULL)
1922 return -1;
1923
1924 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
1925 IS_LITTLE_ENDIAN, 0) < 0) {
1926 Py_DECREF(cookieLong);
1927 return -1;
1928 }
1929 Py_DECREF(cookieLong);
1930
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001931 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
1932 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
1933 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
1934 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
1935 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001936
1937 return 0;
1938}
1939
1940static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001941textiowrapper_build_cookie(cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001942{
1943 unsigned char buffer[COOKIE_BUF_LEN];
1944
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001945 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
1946 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
1947 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
1948 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
1949 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001950
1951 return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0);
1952}
1953#undef IS_LITTLE_ENDIAN
1954
1955static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001956_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001957{
1958 PyObject *res;
1959 /* When seeking to the start of the stream, we call decoder.reset()
1960 rather than decoder.getstate().
1961 This is for a few decoders such as utf-16 for which the state value
1962 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
1963 utf-16, that we are expecting a BOM).
1964 */
1965 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
1966 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
1967 else
1968 res = PyObject_CallMethod(self->decoder, "setstate",
1969 "((yi))", "", cookie->dec_flags);
1970 if (res == NULL)
1971 return -1;
1972 Py_DECREF(res);
1973 return 0;
1974}
1975
Antoine Pitroue4501852009-05-14 18:55:55 +00001976static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001977_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
Antoine Pitroue4501852009-05-14 18:55:55 +00001978{
1979 PyObject *res;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001980 /* Same as _textiowrapper_decoder_setstate() above. */
Antoine Pitroue4501852009-05-14 18:55:55 +00001981 if (cookie->start_pos == 0 && cookie->dec_flags == 0) {
1982 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
1983 self->encoding_start_of_stream = 1;
1984 }
1985 else {
1986 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
1987 _PyIO_zero, NULL);
1988 self->encoding_start_of_stream = 0;
1989 }
1990 if (res == NULL)
1991 return -1;
1992 Py_DECREF(res);
1993 return 0;
1994}
1995
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001996static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001997textiowrapper_seek(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001998{
1999 PyObject *cookieObj, *posobj;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002000 cookie_type cookie;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001 int whence = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002002 PyObject *res;
2003 int cmp;
2004
2005 CHECK_INITIALIZED(self);
2006
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002007 if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
2008 return NULL;
2009 CHECK_CLOSED(self);
2010
2011 Py_INCREF(cookieObj);
2012
2013 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002014 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002015 goto fail;
2016 }
2017
2018 if (whence == 1) {
2019 /* seek relative to current position */
Antoine Pitroue4501852009-05-14 18:55:55 +00002020 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002021 if (cmp < 0)
2022 goto fail;
2023
2024 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002025 _unsupported("can't do nonzero cur-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002026 goto fail;
2027 }
2028
2029 /* Seeking to the current position should attempt to
2030 * sync the underlying buffer with the current position.
2031 */
2032 Py_DECREF(cookieObj);
2033 cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
2034 if (cookieObj == NULL)
2035 goto fail;
2036 }
2037 else if (whence == 2) {
2038 /* seek relative to end of file */
2039
Antoine Pitroue4501852009-05-14 18:55:55 +00002040 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002041 if (cmp < 0)
2042 goto fail;
2043
2044 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002045 _unsupported("can't do nonzero end-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046 goto fail;
2047 }
2048
2049 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2050 if (res == NULL)
2051 goto fail;
2052 Py_DECREF(res);
2053
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002054 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002055 Py_CLEAR(self->snapshot);
2056 if (self->decoder) {
2057 res = PyObject_CallMethod(self->decoder, "reset", NULL);
2058 if (res == NULL)
2059 goto fail;
2060 Py_DECREF(res);
2061 }
2062
2063 res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2);
2064 Py_XDECREF(cookieObj);
2065 return res;
2066 }
2067 else if (whence != 0) {
2068 PyErr_Format(PyExc_ValueError,
2069 "invalid whence (%d, should be 0, 1 or 2)", whence);
2070 goto fail;
2071 }
2072
Antoine Pitroue4501852009-05-14 18:55:55 +00002073 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_LT);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002074 if (cmp < 0)
2075 goto fail;
2076
2077 if (cmp == 1) {
2078 PyErr_Format(PyExc_ValueError,
2079 "negative seek position %R", cookieObj);
2080 goto fail;
2081 }
2082
2083 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2084 if (res == NULL)
2085 goto fail;
2086 Py_DECREF(res);
2087
2088 /* The strategy of seek() is to go back to the safe start point
2089 * and replay the effect of read(chars_to_skip) from there.
2090 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002091 if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002092 goto fail;
2093
2094 /* Seek back to the safe start point. */
2095 posobj = PyLong_FromOff_t(cookie.start_pos);
2096 if (posobj == NULL)
2097 goto fail;
2098 res = PyObject_CallMethodObjArgs(self->buffer,
2099 _PyIO_str_seek, posobj, NULL);
2100 Py_DECREF(posobj);
2101 if (res == NULL)
2102 goto fail;
2103 Py_DECREF(res);
2104
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002105 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002106 Py_CLEAR(self->snapshot);
2107
2108 /* Restore the decoder to its state from the safe start point. */
2109 if (self->decoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002110 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111 goto fail;
2112 }
2113
2114 if (cookie.chars_to_skip) {
2115 /* Just like _read_chunk, feed the decoder and save a snapshot. */
2116 PyObject *input_chunk = PyObject_CallMethod(
2117 self->buffer, "read", "i", cookie.bytes_to_feed);
2118 PyObject *decoded;
2119
2120 if (input_chunk == NULL)
2121 goto fail;
2122
2123 assert (PyBytes_Check(input_chunk));
2124
2125 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2126 if (self->snapshot == NULL) {
2127 Py_DECREF(input_chunk);
2128 goto fail;
2129 }
2130
2131 decoded = PyObject_CallMethod(self->decoder, "decode",
2132 "Oi", input_chunk, (int)cookie.need_eof);
2133
2134 if (decoded == NULL)
2135 goto fail;
2136
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002137 textiowrapper_set_decoded_chars(self, decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138
2139 /* Skip chars_to_skip of the decoded characters. */
2140 if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) {
2141 PyErr_SetString(PyExc_IOError, "can't restore logical file position");
2142 goto fail;
2143 }
2144 self->decoded_chars_used = cookie.chars_to_skip;
2145 }
2146 else {
2147 self->snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
2148 if (self->snapshot == NULL)
2149 goto fail;
2150 }
2151
Antoine Pitroue4501852009-05-14 18:55:55 +00002152 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2153 if (self->encoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002154 if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
Antoine Pitroue4501852009-05-14 18:55:55 +00002155 goto fail;
2156 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002157 return cookieObj;
2158 fail:
2159 Py_XDECREF(cookieObj);
2160 return NULL;
2161
2162}
2163
2164static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165textiowrapper_tell(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166{
2167 PyObject *res;
2168 PyObject *posobj = NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002169 cookie_type cookie = {0,0,0,0,0};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002170 PyObject *next_input;
2171 Py_ssize_t chars_to_skip, chars_decoded;
2172 PyObject *saved_state = NULL;
2173 char *input, *input_end;
2174
2175 CHECK_INITIALIZED(self);
2176 CHECK_CLOSED(self);
2177
2178 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002179 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002180 goto fail;
2181 }
2182 if (!self->telling) {
2183 PyErr_SetString(PyExc_IOError,
2184 "telling position disabled by next() call");
2185 goto fail;
2186 }
2187
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002188 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002189 return NULL;
2190 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2191 if (res == NULL)
2192 goto fail;
2193 Py_DECREF(res);
2194
2195 posobj = PyObject_CallMethod(self->buffer, "tell", NULL);
2196 if (posobj == NULL)
2197 goto fail;
2198
2199 if (self->decoder == NULL || self->snapshot == NULL) {
2200 assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0);
2201 return posobj;
2202 }
2203
2204#if defined(HAVE_LARGEFILE_SUPPORT)
2205 cookie.start_pos = PyLong_AsLongLong(posobj);
2206#else
2207 cookie.start_pos = PyLong_AsLong(posobj);
2208#endif
2209 if (PyErr_Occurred())
2210 goto fail;
2211
2212 /* Skip backward to the snapshot point (see _read_chunk). */
2213 if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input))
2214 goto fail;
2215
2216 assert (PyBytes_Check(next_input));
2217
2218 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2219
2220 /* How many decoded characters have been used up since the snapshot? */
2221 if (self->decoded_chars_used == 0) {
2222 /* We haven't moved from the snapshot point. */
2223 Py_DECREF(posobj);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002224 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002225 }
2226
2227 chars_to_skip = self->decoded_chars_used;
2228
2229 /* Starting from the snapshot position, we will walk the decoder
2230 * forward until it gives us enough decoded characters.
2231 */
2232 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2233 _PyIO_str_getstate, NULL);
2234 if (saved_state == NULL)
2235 goto fail;
2236
2237 /* Note our initial start point. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002238 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002239 goto fail;
2240
2241 /* Feed the decoder one byte at a time. As we go, note the
2242 * nearest "safe start point" before the current location
2243 * (a point where the decoder has nothing buffered, so seek()
2244 * can safely start from there and advance to this location).
2245 */
2246 chars_decoded = 0;
2247 input = PyBytes_AS_STRING(next_input);
2248 input_end = input + PyBytes_GET_SIZE(next_input);
2249 while (input < input_end) {
2250 PyObject *state;
2251 char *dec_buffer;
2252 Py_ssize_t dec_buffer_len;
2253 int dec_flags;
2254
2255 PyObject *decoded = PyObject_CallMethod(
2256 self->decoder, "decode", "y#", input, 1);
2257 if (decoded == NULL)
2258 goto fail;
2259 assert (PyUnicode_Check(decoded));
2260 chars_decoded += PyUnicode_GET_SIZE(decoded);
2261 Py_DECREF(decoded);
2262
2263 cookie.bytes_to_feed += 1;
2264
2265 state = PyObject_CallMethodObjArgs(self->decoder,
2266 _PyIO_str_getstate, NULL);
2267 if (state == NULL)
2268 goto fail;
2269 if (!PyArg_Parse(state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) {
2270 Py_DECREF(state);
2271 goto fail;
2272 }
2273 Py_DECREF(state);
2274
2275 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2276 /* Decoder buffer is empty, so this is a safe start point. */
2277 cookie.start_pos += cookie.bytes_to_feed;
2278 chars_to_skip -= chars_decoded;
2279 cookie.dec_flags = dec_flags;
2280 cookie.bytes_to_feed = 0;
2281 chars_decoded = 0;
2282 }
2283 if (chars_decoded >= chars_to_skip)
2284 break;
2285 input++;
2286 }
2287 if (input == input_end) {
2288 /* We didn't get enough decoded data; signal EOF to get more. */
2289 PyObject *decoded = PyObject_CallMethod(
2290 self->decoder, "decode", "yi", "", /* final = */ 1);
2291 if (decoded == NULL)
2292 goto fail;
2293 assert (PyUnicode_Check(decoded));
2294 chars_decoded += PyUnicode_GET_SIZE(decoded);
2295 Py_DECREF(decoded);
2296 cookie.need_eof = 1;
2297
2298 if (chars_decoded < chars_to_skip) {
2299 PyErr_SetString(PyExc_IOError,
2300 "can't reconstruct logical file position");
2301 goto fail;
2302 }
2303 }
2304
2305 /* finally */
2306 Py_XDECREF(posobj);
2307 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2308 Py_DECREF(saved_state);
2309 if (res == NULL)
2310 return NULL;
2311 Py_DECREF(res);
2312
2313 /* The returned cookie corresponds to the last safe start point. */
2314 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002315 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002316
2317 fail:
2318 Py_XDECREF(posobj);
2319 if (saved_state) {
2320 PyObject *type, *value, *traceback;
2321 PyErr_Fetch(&type, &value, &traceback);
2322
2323 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2324 Py_DECREF(saved_state);
2325 if (res == NULL)
2326 return NULL;
2327 Py_DECREF(res);
2328
2329 PyErr_Restore(type, value, traceback);
2330 }
2331 return NULL;
2332}
2333
2334static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002335textiowrapper_truncate(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002336{
2337 PyObject *pos = Py_None;
2338 PyObject *res;
2339
2340 CHECK_INITIALIZED(self)
2341 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
2342 return NULL;
2343 }
2344
2345 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2346 if (res == NULL)
2347 return NULL;
2348 Py_DECREF(res);
2349
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00002350 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002351}
2352
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002353static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002354textiowrapper_repr(textio *self)
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002355{
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002356 PyObject *nameobj, *modeobj, *res, *s;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002357
2358 CHECK_INITIALIZED(self);
2359
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002360 res = PyUnicode_FromString("<_io.TextIOWrapper");
2361 if (res == NULL)
2362 return NULL;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002363 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
2364 if (nameobj == NULL) {
2365 if (PyErr_ExceptionMatches(PyExc_AttributeError))
2366 PyErr_Clear();
2367 else
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002368 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002369 }
2370 else {
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002371 s = PyUnicode_FromFormat(" name=%R", nameobj);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002372 Py_DECREF(nameobj);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002373 if (s == NULL)
2374 goto error;
2375 PyUnicode_AppendAndDel(&res, s);
2376 if (res == NULL)
2377 return NULL;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002378 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002379 modeobj = PyObject_GetAttrString((PyObject *) self, "mode");
2380 if (modeobj == NULL) {
2381 if (PyErr_ExceptionMatches(PyExc_AttributeError))
2382 PyErr_Clear();
2383 else
2384 goto error;
2385 }
2386 else {
2387 s = PyUnicode_FromFormat(" mode=%R", modeobj);
2388 Py_DECREF(modeobj);
2389 if (s == NULL)
2390 goto error;
2391 PyUnicode_AppendAndDel(&res, s);
2392 if (res == NULL)
2393 return NULL;
2394 }
2395 s = PyUnicode_FromFormat("%U encoding=%R>",
2396 res, self->encoding);
2397 Py_DECREF(res);
2398 return s;
2399error:
2400 Py_XDECREF(res);
2401 return NULL;
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002402}
2403
2404
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002405/* Inquiries */
2406
2407static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002408textiowrapper_fileno(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002409{
2410 CHECK_INITIALIZED(self);
2411 return PyObject_CallMethod(self->buffer, "fileno", NULL);
2412}
2413
2414static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002415textiowrapper_seekable(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002416{
2417 CHECK_INITIALIZED(self);
2418 return PyObject_CallMethod(self->buffer, "seekable", NULL);
2419}
2420
2421static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002422textiowrapper_readable(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002423{
2424 CHECK_INITIALIZED(self);
2425 return PyObject_CallMethod(self->buffer, "readable", NULL);
2426}
2427
2428static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002429textiowrapper_writable(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002430{
2431 CHECK_INITIALIZED(self);
2432 return PyObject_CallMethod(self->buffer, "writable", NULL);
2433}
2434
2435static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002436textiowrapper_isatty(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002437{
2438 CHECK_INITIALIZED(self);
2439 return PyObject_CallMethod(self->buffer, "isatty", NULL);
2440}
2441
2442static PyObject *
Antoine Pitrou243757e2010-11-05 21:15:39 +00002443textiowrapper_getstate(textio *self, PyObject *args)
2444{
2445 PyErr_Format(PyExc_TypeError,
2446 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
2447 return NULL;
2448}
2449
2450static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002451textiowrapper_flush(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002452{
2453 CHECK_INITIALIZED(self);
2454 CHECK_CLOSED(self);
2455 self->telling = self->seekable;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002456 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002457 return NULL;
2458 return PyObject_CallMethod(self->buffer, "flush", NULL);
2459}
2460
2461static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002462textiowrapper_close(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002463{
2464 PyObject *res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002465 int r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002467
Antoine Pitrou6be88762010-05-03 16:48:20 +00002468 res = textiowrapper_closed_get(self, NULL);
2469 if (res == NULL)
2470 return NULL;
2471 r = PyObject_IsTrue(res);
2472 Py_DECREF(res);
2473 if (r < 0)
2474 return NULL;
Victor Stinnerf6c57832010-05-19 01:17:01 +00002475
Antoine Pitrou6be88762010-05-03 16:48:20 +00002476 if (r > 0) {
2477 Py_RETURN_NONE; /* stream already closed */
2478 }
2479 else {
Antoine Pitroue033e062010-10-29 10:38:18 +00002480 if (self->deallocating) {
2481 res = PyObject_CallMethod(self->buffer, "_dealloc_warn", "O", self);
2482 if (res)
2483 Py_DECREF(res);
2484 else
2485 PyErr_Clear();
2486 }
Antoine Pitrou6be88762010-05-03 16:48:20 +00002487 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2488 if (res == NULL) {
2489 return NULL;
2490 }
2491 else
2492 Py_DECREF(res);
2493
2494 return PyObject_CallMethod(self->buffer, "close", NULL);
2495 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002496}
2497
2498static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002499textiowrapper_iternext(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500{
2501 PyObject *line;
2502
2503 CHECK_INITIALIZED(self);
2504
2505 self->telling = 0;
2506 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2507 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002508 line = _textiowrapper_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002509 }
2510 else {
2511 line = PyObject_CallMethodObjArgs((PyObject *)self,
2512 _PyIO_str_readline, NULL);
2513 if (line && !PyUnicode_Check(line)) {
2514 PyErr_Format(PyExc_IOError,
2515 "readline() should have returned an str object, "
2516 "not '%.200s'", Py_TYPE(line)->tp_name);
2517 Py_DECREF(line);
2518 return NULL;
2519 }
2520 }
2521
2522 if (line == NULL)
2523 return NULL;
2524
2525 if (PyUnicode_GET_SIZE(line) == 0) {
2526 /* Reached EOF or would have blocked */
2527 Py_DECREF(line);
2528 Py_CLEAR(self->snapshot);
2529 self->telling = self->seekable;
2530 return NULL;
2531 }
2532
2533 return line;
2534}
2535
2536static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002537textiowrapper_name_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002538{
2539 CHECK_INITIALIZED(self);
2540 return PyObject_GetAttrString(self->buffer, "name");
2541}
2542
2543static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002544textiowrapper_closed_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002545{
2546 CHECK_INITIALIZED(self);
2547 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2548}
2549
2550static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002551textiowrapper_newlines_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002552{
2553 PyObject *res;
2554 CHECK_INITIALIZED(self);
2555 if (self->decoder == NULL)
2556 Py_RETURN_NONE;
2557 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2558 if (res == NULL) {
Benjamin Peterson2cfca792009-06-06 20:46:48 +00002559 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2560 PyErr_Clear();
2561 Py_RETURN_NONE;
2562 }
2563 else {
2564 return NULL;
2565 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566 }
2567 return res;
2568}
2569
2570static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002571textiowrapper_errors_get(textio *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002572{
2573 CHECK_INITIALIZED(self);
2574 return PyUnicode_FromString(PyBytes_AS_STRING(self->errors));
2575}
2576
2577static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002578textiowrapper_chunk_size_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002579{
2580 CHECK_INITIALIZED(self);
2581 return PyLong_FromSsize_t(self->chunk_size);
2582}
2583
2584static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002585textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002586{
2587 Py_ssize_t n;
2588 CHECK_INITIALIZED_INT(self);
Antoine Pitroucb4ae812011-07-13 21:07:49 +02002589 n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002590 if (n == -1 && PyErr_Occurred())
2591 return -1;
2592 if (n <= 0) {
2593 PyErr_SetString(PyExc_ValueError,
2594 "a strictly positive integer is required");
2595 return -1;
2596 }
2597 self->chunk_size = n;
2598 return 0;
2599}
2600
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002601static PyMethodDef textiowrapper_methods[] = {
2602 {"detach", (PyCFunction)textiowrapper_detach, METH_NOARGS},
2603 {"write", (PyCFunction)textiowrapper_write, METH_VARARGS},
2604 {"read", (PyCFunction)textiowrapper_read, METH_VARARGS},
2605 {"readline", (PyCFunction)textiowrapper_readline, METH_VARARGS},
2606 {"flush", (PyCFunction)textiowrapper_flush, METH_NOARGS},
2607 {"close", (PyCFunction)textiowrapper_close, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002608
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002609 {"fileno", (PyCFunction)textiowrapper_fileno, METH_NOARGS},
2610 {"seekable", (PyCFunction)textiowrapper_seekable, METH_NOARGS},
2611 {"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS},
2612 {"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS},
2613 {"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002614 {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002615
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002616 {"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS},
2617 {"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS},
2618 {"truncate", (PyCFunction)textiowrapper_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002619 {NULL, NULL}
2620};
2621
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002622static PyMemberDef textiowrapper_members[] = {
2623 {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
2624 {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
2625 {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002626 {NULL}
2627};
2628
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002629static PyGetSetDef textiowrapper_getset[] = {
2630 {"name", (getter)textiowrapper_name_get, NULL, NULL},
2631 {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002632/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2633*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002634 {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
2635 {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
2636 {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
2637 (setter)textiowrapper_chunk_size_set, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002638 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002639};
2640
2641PyTypeObject PyTextIOWrapper_Type = {
2642 PyVarObject_HEAD_INIT(NULL, 0)
2643 "_io.TextIOWrapper", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002644 sizeof(textio), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002645 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002646 (destructor)textiowrapper_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002647 0, /*tp_print*/
2648 0, /*tp_getattr*/
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002649 0, /*tps_etattr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002651 (reprfunc)textiowrapper_repr,/*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002652 0, /*tp_as_number*/
2653 0, /*tp_as_sequence*/
2654 0, /*tp_as_mapping*/
2655 0, /*tp_hash */
2656 0, /*tp_call*/
2657 0, /*tp_str*/
2658 0, /*tp_getattro*/
2659 0, /*tp_setattro*/
2660 0, /*tp_as_buffer*/
2661 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2662 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002663 textiowrapper_doc, /* tp_doc */
2664 (traverseproc)textiowrapper_traverse, /* tp_traverse */
2665 (inquiry)textiowrapper_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002666 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002667 offsetof(textio, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002668 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002669 (iternextfunc)textiowrapper_iternext, /* tp_iternext */
2670 textiowrapper_methods, /* tp_methods */
2671 textiowrapper_members, /* tp_members */
2672 textiowrapper_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002673 0, /* tp_base */
2674 0, /* tp_dict */
2675 0, /* tp_descr_get */
2676 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002677 offsetof(textio, dict), /*tp_dictoffset*/
2678 (initproc)textiowrapper_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002679 0, /* tp_alloc */
2680 PyType_GenericNew, /* tp_new */
2681};